Pod 的生命周期

# pod的生命周期 > 参考: https://kubernetes.io/zh/docs/concepts/workloads/pods/pod-life cycle/ > 有些pod(比如跑httpd服务), 正常情况下会一直运行中,但如果手动删除 它,此pod会终止 >也有些pod(比如执行计算任务),任务计算完后就会自动终止 >上面两种场景中,pod从创建到终止的过程就是pod的生命周期。 ## 容器启动 > 1. pod中的容器在创建前,有初始化容器(init container)来进行初始化环境 > 2. 初化完后,主容器(main container)开始启动 > 3. 主容器启动后,有一个post start的操作(启动后的触发型操作,或者叫启动后钩子) > 4. post start后,就开始做健康检查 **第一个健康检查叫存活状态检查(liveness probe ),用来检查主容 器存活状态的 第二个健康检查叫准备就绪检查(readiness probe),用来检查主容 器是否启动就绪** ## 容器终止 > 1. 可以在容器终止前设置pre stop操作(终止前的触发型操作,或者叫终止 前钩子) > 2. 当出现特殊情况不能正常销毁pod时,大概等待30秒会强制终止 > 3. 终止容器后还可能会重启容器(视容器重启策略而定)。 ## 回顾容器重启策略 > **Always:**表示容器挂了总是重启,这是默认策略 > **OnFailures:**表容器状态为错误时才重启,也就是容器正常终止时不重 启 > **Never:**表示容器挂了不予重启 > 对于Always这种策略,容器只要挂了,就会立即重启,这样是很耗费 资源的。所以Always重启策略是这么做的:第一次容器挂了立即重 启,如果再挂了就要延时10s重启,第三次挂了就等20s重启...... 依次 类推 ### HealthCheck健康检查 > 当Pod启动时,容器可能会因为某种错误(服务未启动或端口不正确)而无法 访问等。 ### Health Check方式 > kubelet拥有两个检测器,它们分别对应不同的触发器(根据触发器的结构执行进一步的动作) | 方式 | 说明 | | -------- | -------- | | Liveness Probe(存活状态探测) | 检查后不健康,重启pod(参照容器重启策略) | | readiness Probe(就绪型 探测) | 检查后不健康,将容器设置为Notready;如果使用 service来访问,流量不会转发给此种状态的pod | ## Probe探测方式 | 方式 | 说明 | | -------- | -------- | |Exec | 执行命令 | | HTTPGet | http请求某一个URL路径 | | TCP | tcp连接某一个端口 | ## 案例1: liveness-exec > 参考: https://kubernetes.io/zh/docs/tasks/configure-pod-container/co nfigure-liveness-readiness-startup-probes/ ### 1, 准备YAML文件 > vim pod-liveness-exec.yml ``` apiVersion: v1 kind: Pod metadata: name: liveness-exec namespace: default spec: containers: - name: liveness image: busybox imagePullPolicy: IfNotPresent args: - /bin/sh - -c - touch /tmp/healthy; sleep 30; rm -rf /tmp/healthy; sleep 600 livenessProbe: exec: command: - cat - /tmp/healthy initialDelaySeconds: 5 # pod启动延迟5秒后探测 periodSeconds: 5 ``` ### 2, 应用YAML文件 > kubectl apply -f pod-liveness-exec.yml ### 3, 通过下面的命令观察 > kubectl describe pod liveness-exec ![image.png](http://www.icode9.com/i/li/?n=2&i=images/20210613/1623551771457045.png?,size_14,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_20,type_ZmFuZ3poZW5naGVpdGk=) **看到40s前被调度以node1节点,3s前健康检查出问题** ### 4, 过几分钟再观察 >kubectl describe pod liveness-exec > kubectl get pod ![image.png](http://www.icode9.com/i/li/?n=2&i=images/20210613/1623551834334474.png?,size_14,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_20,type_ZmFuZ3poZW5naGVpdGk=) ![image.png](http://www.icode9.com/i/li/?n=2&i=images/20210613/1623552482926515.png?,size_14,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_20,type_ZmFuZ3poZW5naGVpdGk=) **看到重启5次,慢慢地重启间隔时间会越来越长** ## 拓展: 容器重启策略验证 ``` apiVersion: v1 kind: Pod metadata:  name: liveness-exec  namespace: default spec: restartPolicy: Never # 把容器重启策略由默 认的always改为Never  containers:  - name: liveness    image: busybox    imagePullPolicy: IfNotPresent    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 ``` ![image.png](http://www.icode9.com/i/li/?n=2&i=images/20210613/1623552954292666.png?,size_14,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_20,type_ZmFuZ3poZW5naGVpdGk=) ![image.png](http://www.icode9.com/i/li/?n=2&i=images/20210613/1623552982794653.png?,size_14,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_20,type_ZmFuZ3poZW5naGVpdGk=) ![image.png](http://www.icode9.com/i/li/?n=2&i=images/20210613/1623553714493111.png?,size_14,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_20,type_ZmFuZ3poZW5naGVpdGk=) ![image.png](http://www.icode9.com/i/li/?n=2&i=images/20210613/1623553856446830.png?,size_14,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_20,type_ZmFuZ3poZW5naGVpdGk=) **验证结果:** > 容器健康检查出现问题后,不再重启,也不会继续sleep 600秒,而是 直接关闭了 ## 案例2: liveness-httpget ### 1, 编写YMAL文件 > vim pod-liveness-httpget.yml ``` apiVersion: v1 kind: Pod metadata:  name: liveness-httpget  namespace: default spec:  containers: - name: liveness    image: nginx:1.15-alpine    imagePullPolicy: IfNotPresent    ports: # 指定容器端口,这一 段不写也行,端口由镜像决定    - name: http # 自定义名称,不需要 与下面的port: http对应      containerPort: 80 # 类似dockerfile里 的expose 80    livenessProbe:      httpGet:                          # 使用httpGet方式        port: http             # http协议,也可以直 接写80端口        path: /index.html               # 探测家目录下的 index.html      initialDelaySeconds: 3            # 延迟3秒开始探测      periodSeconds: 5   ``` ### 2, 应用YAML文件 >kubectl apply -f pod-liveness-httpget.yml ### 3, 验证查看 > kubectl get pods ![image.png](http://www.icode9.com/i/li/?n=2&i=images/20210613/1623553981330734.png?,size_14,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_20,type_ZmFuZ3poZW5naGVpdGk=) ### 4, 交互删除nginx里的主页文件 >kubectl exec -it liveness-httpget -- rm -rf /usr/share/nginx/html/index.html > kubectl describe pod liveness-httpget |tail ![image.png](http://www.icode9.com/i/li/?n=2&i=images/20210613/1623554127925985.png?,size_14,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_20,type_ZmFuZ3poZW5naGVpdGk=) ### 5, 验证查看会发现 > kubectl get pod ![image.png](http://www.icode9.com/i/li/?n=2&i=images/20210613/1623554354487529.png?,size_14,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_20,type_ZmFuZ3poZW5naGVpdGk=) **只restart一次** ## 案例3: liveness-tcp ### 1, 编写YAML文件 > vim pod-liveness-tcp.yml ``` apiVersion: v1 kind: Pod metadata:  name: liveness-tcp  namespace: default spec:  containers:  - name: liveness    image: nginx:1.15-alpine    imagePullPolicy: IfNotPresent    ports:    - name: http      containerPort: 80    livenessProbe:      tcpSocket:                        # 使用tcp连接方式        port: 80                        # 连接80端口进行探测      initialDelaySeconds: 3      periodSeconds: 5 ``` ### 2, 应用YAML文件创建pod > kubectl apply -f pod-liveness-tcp.yml ### 3, 查看验证 > kubectl get pod |grep liveness-tcp ![image.png](http://www.icode9.com/i/li/?n=2&i=images/20210613/1623554521428001.png?,size_14,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_20,type_ZmFuZ3poZW5naGVpdGk=) ### 4, 交互关闭nginx > kubectl exec -it liveness-tcp -- /usr/sbin/nginx -s stop ### 5, 再次验证查看 > kubectl get pod ![image.png](http://www.icode9.com/i/li/?n=2&i=images/20210613/1623554729708175.png?,size_14,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_20,type_ZmFuZ3poZW5naGVpdGk=) ![image.png](http://www.icode9.com/i/li/?n=2&i=images/20210613/1623554769321615.png?,size_14,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_20,type_ZmFuZ3poZW5naGVpdGk=) **也只重启1次,重启后重新初始化了** ## 案例4: readiness ### 1, 编写YAML文件 > vim pod-readiness-httpget.yml ``` apiVersion: v1 kind: Pod metadata:  name: readiness-httpget  namespace: default spec: containers:  - name: readiness    image: nginx:1.15-alpine    imagePullPolicy: IfNotPresent    ports:    - name: http      containerPort: 80    readinessProbe:       # 这里由liveness换成了readiness      httpGet:        port: http        path: /index.html      initialDelaySeconds: 3      periodSeconds: 5 ``` ### 2, 应用YAML文件 > kubectl apply -f pod-readiness-httpget.yml ### 3, 验证查看 >kubectl get pod |grep readiness-httpget ![image.png](http://www.icode9.com/i/li/?n=2&i=images/20210613/1623554919385951.png?,size_14,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_20,type_ZmFuZ3poZW5naGVpdGk=) ### 4, 交互删除nginx主页 > kubectl exec -it readiness-httpget -- rm -rf /usr/share/nginx/html/index.html ### 5, 再次验证 >kubectl get pod |grep readiness-httpget ![image.png](http://www.icode9.com/i/li/?n=2&i=images/20210613/1623555174478963.png?,size_14,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_20,type_ZmFuZ3poZW5naGVpdGk=) **READY状态为0/1** ### 6, 交互创建nginx主页文件再验证 > kubectl exec -it readiness-httpget -- touch /usr/share/nginx/html/index.html ### 7, 再次验证 > kubectl get pod |grep readiness-httpget ![image.png](http://www.icode9.com/i/li/?n=2&i=images/20210613/1623555328117781.png?,size_14,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_20,type_ZmFuZ3poZW5naGVpdGk=) **READY状态为1/1** ## 案例5: readiness+liveness综合 ### 1, 编写YAML文件 > vim pod-readiness-liveiness.yml ``` apiVersion: v1 kind: Pod metadata: name: readiness-liveness-httpget namespace: default spec: containers: - name: readiness-liveness image: nginx:1.15-alpine imagePullPolicy: IfNotPresent ports: - name: http containerPort: 80 livenessProbe: httpGet: port: http path: /index.html initialDelaySeconds: 1 periodSeconds: 3 readinessProbe: httpGet: port: http path: /index.html initialDelaySeconds: 5 periodSeconds: 5 ``` ### 2, 应用YAML文件 > kubectl apply -f pod-readiness-liveiness.yml ### 3, 验证 > kubectl get pod |grep readiness-liveness-httpget ![image.png](http://www.icode9.com/i/li/?n=2&i=images/20210613/1623555403796418.png?,size_14,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_20,type_ZmFuZ3poZW5naGVpdGk=) ### 1, 编写YAML文件 > vim pod-poststart.yml ``` apiVersion: v1 kind: Pod metadata: name: poststart namespace: default spec: containers: - name: poststart image: nginx:1.15-alpine imagePullPolicy: IfNotPresent lifecycle: # 生命周期事件 postStart: exec: command: ["mkdir","-p","/usr/share/nginx/html/haha"] ``` ### 2, 应用YMAL文件 > kubectl apply -f pod-poststart.yml ### 3, 验证 > kubectl get pods ![image.png](http://www.icode9.com/i/li/?n=2&i=images/20210613/1623555505392582.png?,size_14,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_20,type_ZmFuZ3poZW5naGVpdGk=) >kubectl exec -it poststart -- ls /usr/share/nginx/html -l ![image.png](http://www.icode9.com/i/li/?n=2&i=images/20210613/1623555549758869.png?,size_14,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_20,type_ZmFuZ3poZW5naGVpdGk=) ## pre-stop **容器终止前执行的命令** ### 1, 编写YAML文件 > vim prestop.yml ``` apiVersion: v1 kind:Pod metadata:  name: prestop  namespace: default spec:  containers:  - name: prestop    image: nginx:1.15-alpine    imagePullPolicy: IfNotPresent    lifecycle:     # 生命周期事件      preStop:     # preStop        exec:          command: ["/bin/sh","-c","sleep 60000000"]     # 容器终止前sleep 60000000秒 ``` ### 2, 应用YAML文件创建pod > kubectl apply -f prestop.yml ### 3, 删除pod验证 > kubectl delete -f prestop.yml ![image.png](http://www.icode9.com/i/li/?n=2&i=images/20210613/1623555656732101.png?,size_14,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_20,type_ZmFuZ3poZW5naGVpdGk=) > 会在这一步等待一定的时间(大概30s-60s左右)才能删除,说明验证成功 **结论: 当出现特殊情况不能正常销毁pod时,大概等待30秒会强制终止** ## pod 故障排除 | 状态 | 描述 | | -------- | -------- | | Pending | pod创建已经提交到Kubernetes。但是,因为 某种原因而不能顺利创建。例如下载镜像慢, 调度不成功。 | | Running | pod已经绑定到一个节点,并且已经创建了所有 容器。至少有一个容器正在运行中,或正在启 动或重新启动。 | | Completed | Pod中的所有容器都已成功终止,不会重新启动。 | | Failed | Pod的所有容器均已终止,且至少有一个容器已 在故障中终止。也就是说,容器要么以非零状 态退出,要么被系统终止。 | |Unknown | 由于某种原因apiserver无法获得Pod的状态, 通常是由于Master与Pod所在主机kubelet通信 时出错。 | | CrashLoopBackOff | 多见于CMD语句错误或者找不到container入口 语句导致了快速退出,可以用kubectl logs 查看 日志进行排错 | > kubectl describe pod pod名 > kubectl logs pod [-c CONTAINER] > kubectl exec POD [-c CONTAINER] --COMMAND [args...]
上一篇:如何购买阿里云服务器(服务器配置选择手册)?


下一篇:使用阿里云来建网站三种方式(自助建站+模板建站+定制建站)