• k8s上Pod生命周期、重启策略、容器探测简介


    目录

    一.Pod的创建过程

    二.Pod的终止过程

    三.Pod的重启策略(restartPolicy)

    1.Always

    2.OnFailture

    3.Never

    4.示例

    四.Pod生命周期内的5种状态(相位)

    1.Pending

    2.Running

    3.Succeeded

    4.Failed

    5.Unknown

    五.初始化容器(init container)

    1.运行初始化容器

    2.以一个案例进行验证初始化容器的重要性

    (1)首先只为mysql提供一个IP地址,tomcat的还没有提供

    (2)编写文件

    (3)应用验证

    (4)为redis提供可用IP地址,并应用验证

    六.主容器(main container)

    1.钩子函数简介

    (1)exec,只在容器内执行一次

    (2)tcpSocket,在当前的容器中尝试访问指定socket,成功后继续执行

    (3)httpGet,在当前的容器中向某url发起http请求,成功后继续执行

    2.容器探测

    (1)liveness probes

    (2)readiness probes

    (3)initialDelaySeconds和timeoutSeconds


    一.Pod的创建过程

    1.用户通过kubectl提交pod信息传给apiserver,apiserver生成pod信息,将信息存入etcd,并像kubectl返回确认信息

    2.apiserver开始记录etcd上apiserver传来的pod的变化,剩余其他组件使用watch机制跟踪apiserver信息变化

    3.scheduler发现pod创建请求,为pod分配主机,向apiserver返回分配信息

    4.node上kubectl接收到pod调度任务,使用现有容器引擎启动容器,向apiserver返回启动等结果

    5.apiserver最后又将pod状态存入etcd

     

    二.Pod的终止过程

    1.kubectl客户端向apiserver发出删除pod命令

    2.apiserver中的pod信息在默认的30s宽限期内被视为dead,被标记为terminating状态

    3.

    (1)kubelet察觉到pod为terminating状态后会开始关闭该pod的进程,node上的设备察觉到进程关闭后会把该pod在此node上匹配的service资源都移出列表

    (2)若是pod定义了prestop钩子相关部分,在terminating后会同步开启执行prestop

    4.容器进程收到停止信号后,判断宽限期结束后是否还有运行中的进程,若存在,该进程和pod会被要求立即终止

    5.apiserver收到kubelet将pod宽限期设置为0的请求,随后完成删除

    三.Pod的重启策略(restartPolicy)

    主要是针对容器探测时出现问题后的重启具体策略,主要有Always、OnFailure、Never三种策略,除首次重启外,以后的每次重启间隔一般都为10s-20s-40s-80s这样的双倍递增规律

    1.Always

    容器生效后,自动重启,默认就是Always

    2.OnFailture

    容器停止运行而且退出码不为0时才重启

    3.Never

    不管是处于什么状态,都不重启

    4.示例

    1. apiVersion: v1
    2. kind: Pod
    3. metadata:
    4. name: mynginx
    5. namespace: myns
    6. labels:
    7.   run: nginx
    8.   user: sulibao
    9. spec:
    10. containers:
    11.   - name: mynginx
    12.     image: nginx
    13.     ports:
    14.     - name: nginx-port
    15.       containerPort: 80
    16.     lifecycle:
    17.       postStart:
    18.         tcpSocket:
    19.           port: 8080
    20. restartPolicy: Always
    21. [root@k8s-master pod]# kubectl get pods -n myns
    22. NAME     READY   STATUS             RESTARTS     AGE
    23. mynginx   0/1     CrashLoopBackOff   1 (43s ago)   2m
    24. [root@k8s-master pod]# vim nginx.yaml
    25. [root@k8s-master pod]# kubectl get pods -n myns
    26. NAME     READY   STATUS             RESTARTS     AGE
    27. mynginx   0/1     CrashLoopBackOff   2 (11s ago)   2m16s   #该容器无法正常创建,需要重启
    28. #将策略更改为Never,不会重启,直接显示error
    29. [root@k8s-master pod]# kubectl get pods -n myns
    30. NAME     READY   STATUS   RESTARTS   AGE
    31. mynginx   0/1     Error   0         54s
    32. [root@k8s-master pod]# cat nginx.yaml
    33. apiVersion: v1
    34. kind: Pod
    35. metadata:
    36. name: mynginx
    37. namespace: myns
    38. labels:
    39.   run: nginx
    40.   user: sulibao
    41. spec:
    42. containers:
    43.   - name: mynginx
    44.     image: nginx
    45.     ports:
    46.     - name: nginx-port
    47.       containerPort: 80
    48.     lifecycle:
    49.       postStart:
    50.         tcpSocket:
    51.           port: 8080
    52. restartPolicy: Never

    四.Pod生命周期内的5种状态(相位)

    1.Pending

    挂起状态,已经创建了pod,但没有被调度完成或者仍处于镜像拉取过程中

    2.Running

    运行中,pod已经被调度至受管节点,且pod要求的所有容器都已经创建完成

    3.Succeeded

    成功,pod中的所有容器都成功终止且不会被重启

    4.Failed

    失败,所有容器都停止,有一个或以上容器终止失败,容器返回非0值

    5.Unknown

    无法正常获取到pod状态信息,通常是网络通信问题

    五.初始化容器(init container)

    当需要用到主容器镜像中没有的代码或文件时、需要利用初始化容器去延缓主容器创建时间、或需要利用初始化容器去满足主容器依赖条件的情况下多用到初始化容器

    1.运行初始化容器

    (1)简单来说初始化容器就是在主容器执行之前要执行的工作,所以初始化容器必须完整运行完成不能失败才能执行到主容器,若运行失败,会一直被重启直到成功(理解为卡在初始化执行阶段)

    (2)初始化容器严格按照定义的顺序执行,理解为第一个执行成功第二个才能开始执行

    2.以一个案例进行验证初始化容器的重要性

    准备创建三个容器,主容器为nginx,两个初始化容器为busybox、分别用于测试mysql和tomcat(这两个服务需要具有IP地址,仅供简单测试,两个服务并非真正启动)

    (1)首先只为mysql提供一个IP地址,tomcat的还没有提供

    [root@k8s-master pod]# ifconfig ens33:1 192.168.2.140 netmask 255.255.255.0 up

    (2)编写文件

    初始化容器中直到ping通两次指定的IP才算真正完成

    1. [root@k8s-master pod]# cat test-nginx.yaml
    2. apiVersion: v1
    3. kind: Pod
    4. metadata:
    5. name: test-nginx
    6. labels:
    7.   name: mytest
    8. namespace: myns
    9. spec:
    10. containers:
    11. - name: nginx
    12.   image: nginx
    13.   ports:
    14.   - name: nginx-port
    15.     containerPort: 80
    16. initContainers:
    17. - name: test-mysql
    18.   image: busybox
    19.   command: ["/bin/sh","-c","until ping 192.168.2.140 -c 2; do echo preparing mysql; sleep 2; done;"]
    20. - name: test-tomcat
    21.   image: busybox
    22.   command: ["/bin/sh","-c","until ping 192.168.2.141 -c 2; do echo preparing tomcat; sleep 2; done;"]

    (3)应用验证

    1. [root@k8s-master pod]# kubectl apply -f test-nginx.yaml
    2. [root@k8s-master pod]# kubectl get pods test-nginx -n myns   #始终位于初始化未完成状态,说明初始化容器中有未完成任务
    3. NAME         READY   STATUS     RESTARTS   AGE
    4. test-nginx   0/1     Init:1/2   0         2m24s
    5. [root@k8s-master pod]# kubectl describe pod test-nginx -n myns #describe查看详情
    6. Events:
    7. Type   Reason     Age   From               Message
    8. ----   ------     ---- ----               -------
    9. Normal Scheduled 100s default-scheduler Successfully assigned myns/test-nginx to k8s-node1
    10. Normal Pulling   99s   kubelet           Pulling image "busybox"
    11. Normal Pulled     95s   kubelet           Successfully pulled image "busybox" in 4.515s (4.515s including waiting)
    12. Normal Created   95s   kubelet           Created container test-mysql
    13. Normal Started   95s   kubelet           Started container test-mysql
    14. Normal Pulling   92s   kubelet           Pulling image "busybox"
    15. Normal Pulled     89s   kubelet           Successfully pulled image "busybox" in 3.365s (3.365s including waiting)
    16. Normal Created   89s   kubelet           Created container test-tomcat
    17. Normal Started   89s   kubelet           Started container test-tomcat  
    18. #可以看到卡在test-tomcat初始化容器的执行上,因为我们没有为其提供可用IP地址,它无法完成文件中的command(ping不通两次)部分,也就无法进入主容器nginx的创建启动

    (4)为redis提供可用IP地址,并应用验证

    1. [root@k8s-master pod]# ifconfig ens33:2 192.168.2.141 netmask 255.255.255.0 up
    2. [root@k8s-master pod]# kubectl get pods -n myns
    3. NAME         READY   STATUS   RESTARTS   AGE
    4. test-nginx   1/1     Running   0         14m
    5. Events:
    6. Type   Reason     Age   From               Message
    7. ----   ------     ----   ----               -------
    8. Normal Scheduled 3m40s default-scheduler Successfully assigned myns/test-nginx to k8s-node1
    9. Normal Pulling   3m39s kubelet           Pulling image "busybox"
    10. Normal Pulled     3m35s kubelet           Successfully pulled image "busybox" in 4.515s (4.515s including waiting)
    11. Normal Created   3m35s kubelet           Created container test-mysql
    12. Normal Started   3m35s kubelet           Started container test-mysql
    13. Normal Pulling   3m32s kubelet           Pulling image "busybox"
    14. Normal Pulled     3m29s kubelet           Successfully pulled image "busybox" in 3.365s (3.365s including waiting)
    15. Normal Created   3m29s kubelet           Created container test-tomcat
    16. Normal Started   3m29s kubelet           Started container test-tomcat #已有可用IP地址,执行完成
    17. Normal Pulling   38s   kubelet           Pulling image "nginx"   #进一步执行主容器nginx的任务
    18. Normal Pulled     12s   kubelet           Successfully pulled image "nginx" in 26.146s (26.146s including waiting)
    19. Normal Created   12s   kubelet           Created container nginx   #主容器执行成功
    20. Normal Started   12s   kubelet           Started container nginx

    六.主容器(main container)

    1.钩子函数简介

    主要是设置来感知生命周期事件,在特定的周期阶段执行用户特定的操作,又分为启动后(post start,指容器创建之后就执行的部分,此处执行失败会重启容器)和结束前(pre stop,指容器终止运行之前执行的部分,此处执行失败会导致删除容器失败)两种。

    钩子函数定义方式

    (1)exec,只在容器内执行一次

    1. apiVersion: v1
    2. kind: Pod
    3. metadata:
    4. name: mynginx
    5. namespace: myns
    6. labels:
    7.   run: nginx
    8.   user: sulibao
    9. spec:
    10. containers:
    11.   - name: mynginx
    12.     image: nginx
    13.     ports:
    14.     - name: nginx-port
    15.       containerPort: 80
    16.     lifecycle:
    17.       postStart:
    18.         exec:
    19.           command: ["/bin/bash","-c","cat /sdf.txt"] #此时这个文件不存在,钩子函数执行失败
    20.            
    21. #换一个存在的文件就能够成功
    22. [root@k8s-master pod]# kubectl get pods -n myns
    23. NAME     READY   STATUS   RESTARTS   AGE
    24. mynginx   1/1     Running   0         96s
    25. [root@k8s-master pod]# cat nginx.yaml
    26. apiVersion: v1
    27. kind: Pod
    28. metadata:
    29. name: mynginx
    30. namespace: myns
    31. labels:
    32.   run: nginx
    33.   user: sulibao
    34. spec:
    35. containers:
    36.   - name: mynginx
    37.     image: nginx
    38.     ports:
    39.     - name: nginx-port
    40.       containerPort: 80
    41.     lifecycle:
    42.       postStart:
    43.         exec:
    44.           command: ["/bin/bash","-c","ls /root"]

    (2)tcpSocket,在当前的容器中尝试访问指定socket,成功后继续执行

    1. apiVersion: v1
    2. kind: Pod
    3. metadata:
    4. name: mynginx
    5. namespace: myns
    6. labels:
    7.   run: nginx
    8.   user: sulibao
    9. spec:
    10. containers:
    11.   - name: mynginx
    12.     image: nginx
    13.     ports:
    14.     - name: nginx-port
    15.       containerPort: 80
    16.     lifecycle:
    17.       preStop:
    18.         tcpSocket:
    19.           port: 80

    (3)httpGet,在当前的容器中向某url发起http请求,成功后继续执行

    1. apiVersion: v1
    2. kind: Pod
    3. metadata:
    4. name: mynginx
    5. namespace: myns
    6. labels:
    7.   run: nginx
    8.   user: sulibao
    9. spec:
    10. containers:
    11.   - name: mynginx
    12.     image: nginx
    13.     ports:
    14.     - name: nginx-port
    15.       containerPort: 80
    16.     lifecycle:
    17.       preStop:
    18.         httpGet:
    19.           path: http://192.168.2.150
    20.           port: 80
    21.            
    22. [root@k8s-master pod]# kubectl get pods -n myns
    23. NAME     READY   STATUS   RESTARTS   AGE
    24. mynginx   1/1     Running   0         56s

    2.容器探测

    主要是用于检测容器中的应用实例工作状态是否正常,不符合预期的实例就会被剔除,不分配任务。两种容器探测探针也支持exec、tcpSocket、httpGet三种检测方式,用法和钩子函数中用法基本一致。

    (1)liveness probes

    存活性探针,用于检测应用实例是否处于正常状态,不正常则会重启容器

    (2)readiness probes

    就绪性探针,用于检测应用实例是否可以进行接受请求的工作,不能则不会为其分配工作

    (3)initialDelaySeconds和timeoutSeconds

    initialDelaySeconds是容器启动后多少秒开始探测,timeoutSeconds是探测超时时间为多少,默认单位是秒

    1. [root@k8s-master pod]# cat nginx.yaml
    2. apiVersion: v1
    3. kind: Pod
    4. metadata:
    5. name: mynginx
    6. namespace: myns
    7. labels:
    8. run: nginx
    9. user: sulibao
    10. spec:
    11. containers:
    12. - name: mynginx
    13. image: nginx
    14. ports:
    15. - name: nginx-port
    16. containerPort: 80
    17. livenessProbe:
    18. exec:
    19. command: ["/bin/bash","-c","ls /root"]
    20. initialDelaySeconds: 30
    21. timeoutSeconds: 5
  • 相关阅读:
    Android视图手册之Broadcast广播
    自行车无级变速器设计
    草料二维码提交数据自动通知企业微信
    作为程序员,如何刚入职公司快速接手项目,如何独自调试老项目
    Redis--List、Set、Zset、Hash、Bitmaps、HyperLogLog、Geospatial
    IDEA中明明导入jar包了,依旧报ClassNotFoundException
    230908-MetaGPT构建专属AI Agent的技术实践-视频笔记
    事务的ACID特性
    “200万天价床垫”引发的思考:普通床垫越卖越贵是推测还是事实
    LeetCode 46. 全排列
  • 原文地址:https://blog.csdn.net/weixin_64334766/article/details/134480101