什么是pod,k8s为什么要设计pod

直接用容器不是更简单吗?因为容器是单进程的,一个容器只能跑一个服务。一个容器跑多个服务是违背docker的设计原则的,也是后患无穷的自杀式的做法。比如说我们有一台节点还有2.5g的内存,有三个服务等待调度其中每个服务占用1g的内存,如果我们一个一个去调度的话 调度完前两个是没问题的 调度第三个就会发现内存不够。在调度层面直接使用容器的话肯定也会有问题的

设计思想

Pod是最小的调度单位,它的调度是按照Pod的资源需求来做的,当然pod肯定不只是为了解决调度而设计的 ,pod对kubernetes还有更重要的作用。pod是一个逻辑的概念,在物理机上并不真实的存在本质还是容器的隔离,具体来说pod的本质就是共享了同一个network
、namespace、volume。你可能会想使用docker命令也可以实现docker run --net=xxx-volumes-from=xxx...也可以让容器共享网络存储,但是这样是对容器的启动顺序有要求的,多个容器不是对等的关系了处理起来非常的复杂。pod用到了Pause容器,这个容器并不需要我们在配置中显示的声明,每个pod都会有并且第一个启动的就是它,我们在配置文件中定义的容器都是通过join network namespace的方式跟pod容器关联在一起的,pause容器是暂停状态的并不占用计算资源并且镜像非常小只有100-200k

lifecycle

postStart,当容器执行了entrypoint cmd后,正常启动时也会同时执行postStart,不能把容器完全启动后要做的事放在这
preStop,容器停止之前会执行并且等待执行完成后会给容器发送停止信号

apiVersion: v1
kind: Pod
metadata:
  name: nginx
spec:
  containers:
  - name: nginx
    image: nginx:1.23.2-alpine
    ports:
    - containerPort: 80
    volumeMounts:
    - name: shared-volume
      mountPath: /shared
    lifecycle:
      postStart:
        exec:
          command: ['/bin/sh', '-c', 'echo web starting >> /var/log/messages']
      preStop:
        exec:
          command: ['/bin/sh', '-c', 'echo web stopping >> /var/log/messages && sleep 3']
  volumes:
  - name: shared-volume
    hostPath:
      path: /root/shared

启动删除pod

[root@node1 ~]# kubectl create -f pod-nginx.yaml 
pod/nginx created
[root@node1 ~]# kubectl delete -f pod-nginx.yaml 
pod "nginx" deleted

查看postStart、preStop执行情况

[root@node1 ~]# kubectl exec -it nginx -- tail -n 10 -f /var/log/messages
web starting
web stopping
command terminated with exit code 137

pod的生命周期

Pendding Pod最开始状态,由于某种原因还没有被调度的状态比如内存不足,匹配不到满足要求的节点,拉取镜像
containerCreating Pod被调度,创建容器状态
Running Pod处于运行中的状态
Succeeded 运行结束了,成功退出(只有cronjob)
Failed 运行结束,非正常退出(只有cronjob)
Ready 对于长期运行的应用并且配置了健康检查,通过了健康检查会处于Ready状态
CrashLoopBackOff 如果没有通过健康检查
Unknow 一般是apiserver没有收到pod的汇报

ProjectedVolume

projectedVolumn是一种轻量级的volume是由apiserver投射到pod里面的,k8s提供了三种使用方法

Secret

Secret作用是在etcd中存放密钥加密,一般用来存放用户名密码之类,k8s本身也有很多地方在使用secret

apiVersion: v1
kind: Secret
metadata:
  name: dbpass
type: Opaque
data:
  username: Z2xvbwo=
  password: MTIzNDU2Cg==

创建secret

[root@node1 ~]# kubectl create -f secret.yaml 
secret/dbpass created
[root@node1 ~]# kubectl get secrets -o wide
NAME     TYPE     DATA   AGE
dbpass   Opaque   2      11s

在pod中使用

[root@node1 ~]# cat pod-secret.yaml
apiVersion: v1
kind: Pod
metadata:
  name: pod-secret
spec:
  containers:
  - name: nginx
    image: nginx:1.23.2-alpine
    ports:
    - containerPort: 80
    volumeMounts:
    - name: db-secret
      mountPath: /db-secret
      readOnly: true
  volumes:
  - name: db-secret
    projected:
      sources:
      - secret:
          name: dbpass
[root@node1 ~]# kubectl create -f pod-secret.yaml 
pod/pod-secret created
[root@node1 ~]# kubectl get pod
NAME             READY   STATUS    RESTARTS      AGE
nginx-ds-7psqb   1/1     Running   0             2d18h
nginx-ds-nddxd   1/1     Running   0             2d18h
nginx-ds-x9jzf   1/1     Running   1 (17h ago)   2d18h
pod-secret       1/1     Running   0             6s
[root@node1 ~]# kubectl exec -it pod-secret -- sh
/ # cat db-secret/username 
gloo
/ # cat db-secret/password 
123456

ConfigMap

ConfigMap的作用和使用方法和Secret基本一致,Secret存储加密数据 ConfigMap存储配置信息
从properties文件创建configMap

[root@node1 ~]# cat game.properties 
enemies=3
lives=3
enemies.cheat=true
enemies.cheat.level=noGoodRotten
secret.code.passphrase=UUDDLRLRBABAS
secret.code.allowed=true
secret.code.lives=30
[root@node1 ~]# kubectl create configmap web-game --from-file game.properties 
configmap/web-game created
[root@node1 ~]# kubectl get cm web-game -o yaml 
apiVersion: v1
data:
  game.properties: |
    enemies=3
    lives=3
    enemies.cheat=true
    enemies.cheat.level=noGoodRotten
    secret.code.passphrase=UUDDLRLRBABAS
    secret.code.allowed=true
    secret.code.lives=30
kind: ConfigMap
metadata:
  creationTimestamp: "2023-02-06T03:23:53Z"
  name: web-game
  namespace: default
  resourceVersion: "74875"
  uid: d193ef4e-868d-4f34-969f-2d2fc36f1baa

在pod中使用configMap

[root@node1 ~]# cat pod-game.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: pod-game
spec:
  containers:
  - name: nginx
    image: nginx:1.23.2-alpine
    ports:
    - containerPort: 80
    volumeMounts:
    - name: game
      mountPath: /etc/config/game
      readOnly: true
  volumes:
  - name: game
    projected:
      sources:
      - configMap:
          name: web-game
[root@node1 ~]# kubectl create -f pod-game.yaml 
pod/pod-game created
[root@node1 ~]# kubectl exec -it pod-game -- sh
/ # cat /etc/config/game/game.properties 
enemies=3
lives=3
enemies.cheat=true
enemies.cheat.level=noGoodRotten
secret.code.passphrase=UUDDLRLRBABAS
secret.code.allowed=true
secret.code.lives=30

以配置文件的方式创建configMap

[root@node1 ~]# kubectl create -f configmap.yaml 
configmap/configs created
[root@node1 ~]# cat configmap.yaml 
apiVersion: v1
kind: ConfigMap
metadata:
  name: configs
data:
  JAVA_OPTS: -Xms1024m
  LOG_LEVEL: DEBUG

环境变量的方式使用configMap

[root@node1 ~]# cat pod-env.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: pod-env
spec:
  containers:
  - name: nginx
    image: nginx:1.23.2-alpine
    ports:
    - containerPort: 80
    env:
      - name: LOG_LEVEL_CONFIG
        valueFrom:
          configMapKeyRef:
            name: configs
            key: LOG_LEVEL
[root@node1 ~]# kubectl get pod -o wide
NAME             READY   STATUS    RESTARTS      AGE     IP               NODE    NOMINATED NODE   READINESS GATES
nginx-ds-7psqb   1/1     Running   0             2d21h   10.233.75.6      node2   <none>           <none>
nginx-ds-nddxd   1/1     Running   0             2d21h   10.233.71.6      node3   <none>           <none>
nginx-ds-x9jzf   1/1     Running   1 (20h ago)   2d21h   10.233.102.135   node1   <none>           <none>
pod-env          1/1     Running   0             45s     10.233.71.20     node3   <none>           <none>
pod-game         1/1     Running   0             142m    10.233.71.19     node3   <none>           <none>
pod-secret       1/1     Running   0             175m    10.233.71.18     node3   <none>           <none>
[root@node1 ~]# kubectl exec -it pod-env -- sh
/ # env|grep LOG
LOG_LEVEL_CONFIG=DEBUG

DownwardAPI

DownwardAPI的作用是让程序中获取Pod本身的一些信息

[root@node1 ~]# cat podinfo.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: podinfo
spec:
  containers:
  - name: nginx
    image: nginx:1.23.2-alpine
    ports:
    - containerPort: 80
    volumeMounts:
    - name: podinfo
      mountPath: /etc/podinfo
      readOnly: true
  volumes:
  - name: podinfo
    projected:
      sources:
      - downwardAPI:
          items:
            - path: "labels"
              fieldRef:
                fieldPath: metadata.labels
            - path: "name"
              fieldRef:
                fieldPath: metadata.name
            - path: "namespace"
              fieldRef:
                fieldPath: metadata.namespace
            - path: "cpu-request"
              resourceFieldRef:
                containerName: nginx
                resource: limits.memory
[root@node1 ~]# kubectl create -f podinfo.yaml pod/podinfo created
[root@node1 ~]# kubectl get pod -o wide
NAME             READY   STATUS    RESTARTS      AGE     IP               NODE    NOMINATED NODE   READINESS GATES
nginx-ds-7psqb   1/1     Running   0             2d21h   10.233.75.6      node2   <none>           <none>
nginx-ds-nddxd   1/1     Running   0             2d21h   10.233.71.6      node3   <none>           <none>
nginx-ds-x9jzf   1/1     Running   1 (20h ago)   2d21h   10.233.102.135   node1   <none>           <none>
pod-env          1/1     Running   0             16m     10.233.71.20     node3   <none>           <none>
pod-game         1/1     Running   0             158m    10.233.71.19     node3   <none>           <none>
pod-secret       1/1     Running   0             3h10m   10.233.71.18     node3   <none>           <none>
podinfo          1/1     Running   0             6s      10.233.71.21     node3   <none>           <none>
[root@node1 ~]# kubectl exec -it podinfo -- sh
/ # cat /etc/podinfo/cpu-request 
1733607424
/ # cat /etc/podinfo/name
podinfo
/ # cat /etc/podinfo/namespace 
default