Pod生命周期

1. Pod生命周期过程中的状态(或者叫相位)

  • init
  • poststart
  • poststop
  • liveness
  • readiness

d.jpg

  • [x] Pending: API Server创建了pod资源对象并存入etcd,但未被调度完成或仍处于下载镜像过程
  • [x] Running: pod已被调度至节点,并且所有容器都被kubelet创建完成
  • [x] Succeeded: pod中的所有容器都已经成功终止并且不会被重启
  • [x] Failed: 所有容器已经被终止,但至少有一个容器终止失败,即容器返回非0值的退出状态或被已被系统终止
  • [x] Unknown: API Server无法正常获取到pod对象状态信息,通常是由于其无法与所在工作节点的kubelet通信所致

2.Pod创建过程

e.jpg


3.针对pod生命周期,做一些事前,事中,事后的一些操作

  • 初始化容器
  • 生命周期钩子函数
  • 容器探测
3.1 初始化容器
$ cat initC-pod.yaml
apiVersion: v1
kind: Pod
metadata:
  name: myapp-pod
  labels:
    app: myapp
spec:
  containers:
  - name: myapp-container
    image: busybox:1.28
    command: ['sh', '-c', 'echo The app is running! && sleep 3600']
  initContainers:
  - name: init-myservice
    image: busybox:1.28
    command: ['sh', '-c', "until nslookup myservice.$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace).svc.cluster.local; do echo waiting for myservice; sleep 2; done"]
  - name: init-mydb
    image: busybox:1.28
    command: ['sh', '-c', "until nslookup mydb.$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace).svc.cluster.local; do echo waiting for mydb; sleep 2; done"]
$ cat initC-service.yaml
kind: Service
apiVersion: v1
metadata:
  name: myservice
spec:
  ports:
    - protocol: TCP
      port: 80
      targetPort: 9367
---
kind: Service
apiVersion: v1
metadata:
  name: mydb
spec:
  ports:
    - protocol: TCP
      port: 80
      targetPort: 9377
创建pod,不创建service,pod在初始化时检查域名失败,容器会停留在init状态
$ kubectl apply -f initC-pod.yaml 

$ kubectl get pod
NAME                              READY   STATUS     RESTARTS   AGE
myapp-pod                         0/1     Init:0/2   0          7s
$ kubectl describe -f initC-pod.yaml
...
  init-myservice:
    Container ID:  docker://c22ec8d0b0ab5cb9a55274892ae7f818198394f9fb851cf672b60dc30099df1f
    Image:         busybox
    Image ID:      docker-pullable://busybox@sha256:9ddee63a712cea977267342e8750ecbc60d3aab25f04ceacfa795e6fce341793
    Port:          <none>
    Host Port:     <none>
    Command:
      sh
      -c
      until nslookup myservice; do echo waiting for myservice; sleep 2; done;
    State:          Running
      Started:      Sun, 19 Jul 2020 13:54:43 +0800
    Ready:          False
    Restart Count:  0
    Environment:    <none>
    Mounts:
      /var/run/secrets/kubernetes.io/serviceaccount from default-token-58nkl (ro)
  init-mydb:
    Container ID:  
    Image:         busybox
    Image ID:      
    Port:          <none>
    Host Port:     <none>
    Command:
      sh
      -c
      until nslookup mydb; do echo waiting for mydb; sleep 2; done;
    State:          Waiting
      Reason:       PodInitializing
    Ready:          False
    Restart Count:  0
    Environment:    <none>
    Mounts:
      /var/run/secrets/kubernetes.io/serviceaccount from default-token-58nkl (ro)
...
$ kubectl logs myapp-pod -c init-myservic
nslookup: can't resolve 'myservice.default.svc.cluster.local'
Server:    10.96.0.10
Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local

$ kubectl logs myapp-pod -c init-mydb
Error from server (BadRequest): container "init-mydb" in pod "myapp-pod" is waiting to start: PodInitializing

f.jpg

创建service,service创建完成后,再看pod状态,会发现myapp-pod已经正常运行
$ kubectl create -f initC-service.yaml

$ kubectl logs myapp-pod -c init-myservic
waiting for myservice
Server:    10.96.0.10
Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local

Name:      myservice.default.svc.cluster.local
Address 1: 10.100.169.77 myservice.default.svc.cluster.local

$ kubectl logs myapp-pod -c init-mydb

Server:    10.96.0.10
Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local

Name:      mydb.default.svc.cluster.local
Address 1: 10.111.35.232 mydb.default.svc.cluster.local


$ kubectl get pod
NAME                              READY   STATUS    RESTARTS   AGE
myapp-pod                         1/1     Running   0          21m

a.jpg

3.2 生命周期钩子函数

钩子函数提供两种实现方式:

  • Exec
  • HTTP
$ cat lifecycle-events.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: lifecycle-demo
spec:
  containers:
  - name: lifecycle-demo-container
    image: nginx
    lifecycle:
      postStart:
        exec:
          command: ["/bin/sh", "-c", "echo Hello from the postStart handler > /usr/share/message"]
      preStop:
        exec:
          command: ["/bin/sh","-c","nginx -s quit; while killall -0 nginx; do sleep 1; done"]
$ kubectl apply -f lifecycle-events.yaml 
pod/lifecycle-demo created

$ kubectl get pod lifecycle-demo
NAME             READY   STATUS              RESTARTS   AGE
lifecycle-demo   0/1     ContainerCreating   0          8s

$ kubectl get pod lifecycle-demo
NAME             READY   STATUS    RESTARTS   AGE
lifecycle-demo   1/1     Running   0          5m2s

$ kubectl exec -it lifecycle-demo -- /bin/bash
root@lifecycle-demo:/# cat /usr/share/message
Hello from the postStart handler

b.jpg


3.3 容器探测

探测方式:

  • exec
  • http
  • tcp

探测分类:

  • 存活探测
  • 就绪检测
exec存活性检测
$ cat exec-liveness.yaml
apiVersion: v1
kind: Pod
metadata:
  labels:
    test: liveness
  name: liveness-exec
spec:
  containers:
  - name: liveness
    image: busybox
    args:
    - /bin/sh
    - -c
    - touch /tmp/healthy; sleep 30; rm -rf /tmp/healthy; sleep 600
    livenessProbe:
      exec:
        command:
        - cat
        - /tmp/healthy
      initialDelaySeconds: 5
      periodSeconds: 5
通过每60秒删除一次healthy文件,检测文件不存在则重启pod,可以看到RESTARTS列数字在递增,AGE时间间隔均匀,这是通过该方式来模拟观察

c.jpg

HTTP存活性检测
$ cat http-liveness.yaml 
apiVersion: v1
kind: Pod
metadata:
  labels:
    test: liveness
  name: liveness-http
spec:
  containers:
  - name: liveness
    image: k8s.gcr.io/liveness
    args:
    - /server
    livenessProbe:
      httpGet:
        path: /healthz
        port: 8080
        httpHeaders:
        - name: Custom-Header
          value: Awesome
      initialDelaySeconds: 3
      periodSeconds: 3
该镜像采用官方文档,容器存活的最开始10秒中,/healthz 处理程序返回一个200的状态码。之后处理程序返回500的状态码。

d.jpg

TCP存活性检测
$ cat tcp-liveness-readiness.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: goproxy
  labels:
    app: goproxy
spec:
  containers:
  - name: goproxy
    image: k8s.gcr.io/goproxy:0.1
    ports:
    - containerPort: 8080
    readinessProbe:
      tcpSocket:
        port: 8081
      initialDelaySeconds: 5
      periodSeconds: 10
    livenessProbe:
      tcpSocket:
        port: 8081
      initialDelaySeconds: 15
      periodSeconds: 20
该服务本来是8080端口,现将livenessProbe探测的tcp端口改为8081,该端口未开启,用于模拟服务宕机,这样服务处于无限重启。服务还配置了就绪检测,服务会一直处于就绪状态,不会对外提供服务

e.jpg

f.jpg

exec就绪检测
$ kubectl create -f readiness-exec.yaml
$ cat readiness-exec.yaml
apiVersion: v1
kind: Pod
metadata:
  labels:
    test: readiness-exec
  name: readiness-exec
spec:
  containers:
  - name: readiness-demo
    image: busybox
    args: ["/bin/sh", "-c", "while true; do rm -f /tmp/ready; sleep 30; touch /tmp/ready; sleep 300; done"]
    readinessProbe:
      exec:
        command: ["test", "-e", "/tmp/ready"]
      initialDelaySeconds: 5
      periodSeconds: 5
# 状态为running,但是READY状态前30秒检测失败,pod一直处于就绪状态,服务一直处于就绪状态,无法对外提供服务
$ kubectl get pod readiness-exec -w
NAME             READY   STATUS              RESTARTS   AGE
readiness-exec   0/1     ContainerCreating   0          3s
readiness-exec   0/1     Running             0          10s
readiness-exec   1/1     Running             0          43s
readiness-exec   0/1     Running             0          5m53s
readiness-exec   1/1     Running             0          6m13s

gg.jpg

【结束】


pa0v0
1 声望0 粉丝