当前位置: 首页 > article >正文

涨薪技术|Kubernetes(k8s)之Pod生命周期(下)

上次推文我们学习了Pod生命周期(上)知识:相位、创建与终止、初始化容器,今天继续分享完余下的3个知识:钩子函数、容器探测、重启策略。

01钩子函数

钩子函数能够感知自身生命周期中的事件,并在相应的时刻到来时运行用户指定的程序代码。

k8s在主容器的启动之后和停止之前提供了两个钩子函数.

  • post start:容器创建之后执行,如果失败了会重启容器;

  • pre stop:容器终止之前执行,执行完成之后容器将成功终止,在其完成之前会阻塞删除容器的操作;

钩子处理器支持使用下面三种方式定义动作:

1)Exec命令:在容器内执行一次命令

......lifecycle:postStart:exec:command:- cat- /tmp/healthy......

2)TCPSocket:在当前容器尝试访问指定的socket

......lifecycle:postStart:tcpSocket:

3)HttpGet:在当前容器中向某url发起http请求

......lifecycle:postStart:httpGet:path: #uri地址port:host:scheme: HTTP #支持的协议,http或者https......

下面演示钩子函数的使用

创建pod-hook-exec.yaml文件,内容如下:​​​​​​​

apiVersion: v1kind: Podmetadata:name: pod-hook-execnamespace: devspec:containers:- name: main-containerimage: nginx:1.17.1ports:- name: nginx-portcontainerPort: 80lifecycle:postStart:exec: #在容器启动的时候执行一个命令,修改掉nginx的默认首页内容command: ["/bin/sh","-c","echo postStart... >/usr/share/nginx/html/index.html"]preStop: #在容器停止之前停止nginx服务exec:command: ["/usr/sbin/nginx","-s","quit"]

使用配置文件​​​​​​​

[root@master ~]# vim pod-hook-exec.yaml[root@master ~]# kubectl create -f pod-hook-exec.yamlpod/pod-hook-exec created[root@master ~]# kubectl get pod pod-hook-exec -n test -o wideNAME READY STATUS RESTARTS AGE IP NODENOMINATED NODE READINESS GATESpod-hook-exec 1/1 Running 0 34s 10.244.104.24 node2<none> <none>[root@master ~]# curl 10.244.104.24:80postStart...

02容器探测

容器探测用于检测容器中的应用实例是否能正常工作,是保障业务可用性的一种传统机制。如果经过探测,实例的状态不符合预期,那么K8S就会把该问题实例“摘除”,不承担业务流量,k8s提供了两种探针来实现容器探测,分别是:

  • livenessprobes:存活性探针,用于检测应用实例当前是否处于正常运行状态,如果不是,k8s会重启容器;

  • readinessprobes:就绪性探针,用于检测应用实例当前是否可以接受请求,如果不能,k8s不会转发流量;

即livenessProbe决定是否重启容器,readinesProbe决定是否将请求转发给容器。

  • startupProbe:使用启动探针来了解应用容器何时启动,如果配置了这个类探针,就可以控制容器在启动成功后再进行存活性liveness和就绪态readiness的检查,确保存活、就绪探针不会影响应用的启动。

探针参数

探针有很多配置参数,可以使用这些参数精确地控制启动、存活和就绪检测的行为。

--initialDelaySeconds:容器启动后要等待多少秒后才启动存活、就绪和启动探针, 默认是 0 秒,最小值是 0;

--periodSeconds:执行探测的时间间隔(单位是秒),默认是 10 秒,最小值是 1;

--timeoutSeconds:探测的超时后等待多少秒,默认值是 1 秒,最小值是 1;

--successThreshold:连续探测成功多少次才被认定为执行成功,默认值是 1,存活和启动探测的这个值必须是 1,最小值是1;

--failureThreshold:连续探测失败多少次才被认定为执行失败。对于存活探测而言,失败就意味着重新启动容器。对就绪探测而言,失败意味着 Pod 会被打上未就绪的标签,默认值是 3,最小值是 1;

上面两种探针目前均支持三种探测方式:

1)Exec命令:在容器内执行一次命令,如果命令执行的退出码为0,则认为程序正常,否则不正常​​​​​​​

......livenessProbe:exec:command:- cat- /tmp/healthy......

创建文件exec-liveness.yaml​​​​​​​

apiVersion: v1kind: Podmetadata:labels:app: livenessname: liveness-execnamespace: probespec:containers:- name: tomcatimage: tomcat:latestargs:- /bin/sh- -c- touch /tmp/liveness-pod; sleep 30; rm -f /tmp/liveness-pod; sleep 100livenessProbe:exec:command:- cat- /tmp/liveness-podinitialDelaySeconds: 5periodSeconds: 5

在配置文件中,periodSeconds 字段指定了 kubelet 每 5 秒执行一次存活探测。initialDelaySeconds指定 kubelet 在执行第一次探测前应该等待 5 秒。kubelet 在容器内执行命令 cat /tmp/liveness 来进行探测, 如果命令执行成功并且返回值为 0,kubelet 就会认为这个容器是健康存活的,如果这个命令返回非0值,kubelet 会杀死这个容器并重新启动它在容器启动时,将执行如下命令:

/bin/sh -c "touch /tmp/liveness; sleep 30; rm -f /tmp/liveness; sleep 300"

容器生命的前 30 秒,/tmp/liveness 文件是存在的,即在容器启动后的 30 秒内,执行命令 cat/tmp/liveness 会返回成功,30 秒之后文件被删除,再次执行命令 cat /tmp/liveness 时就会返回失败,kubectl则会对容器进行重启操作。

创建Pod

[root@master ~]# kubectl apply -f exec-liveness.yaml

30秒内查看pod的状态

[root@master ~]# kubectl describe pod liveness-exec -n test

输出结果显示pod创建成功​​​​​​​

Events:Type Reason Age From Message---- ------ ---- ---- -------Normal Scheduled 9s Successfully assigned test/livenessexecto node2Normal Pulling 8s kubelet, node2 Pulling image "nginx:latest"Normal Pulled 4s kubelet, node2 Successfully pulled image"nginx:latest" in 3.344637979sNormal Created 4s kubelet, node2 Created container nginxNormal Started 4s kubelet, node2 Started container nginx

等到35秒再次查看pod的状态,显示liveness探测失败,Container nginx failed liveness probe, willbe restarted\n Container nginx failed liveness probe, will be restarted,容器被重启。​​​​​​​

Events:Type Reason Age From Message---- ------ ---- ---- -------Normal Scheduled 2m41s Successfully assignedtest/liveness-exec to node2Normal Pulled 2m37s kubelet, node2 Successfully pulledimage "nginx:latest" in 3.344637979sNormal Pulled 81s kubelet, node2 Successfully pulledimage "nginx:latest" in 3.13232767sWarning Unhealthy 39s (x6 over 2m4s) kubelet, node2 Liveness probe failed:cat: /tmp/liveness-pod: No such file or directoryNormal Killing 39s (x2 over 114s) kubelet, node2 Container nginx failedliveness probe, will be restartedNormal Pulling 9s (x3 over 2m41s) kubelet, node2 Pulling image"nginx:latest"Normal Created 5s (x3 over 2m37s) kubelet, node2 Created containernginxNormal Started 5s (x3 over 2m37s) kubelet, node2 Started containernginxNormal Pulled 5s kubelet, node2 Successfully pulledimage "nginx:latest" in 3.870334984s

此时查看pod状态,显示容器重启次数增加了1​​​​​​​

[root@master ~]# kubectl get pod liveness-exec -n testNAME READY STATUS RESTARTS AGEliveness-exec 1/1 Running 2 3m27s

TCPSocket:将会尝试访问同一个用户容器的端口,如果能够建立这条连接,则认为程序正常,否则不正常​​​​​​​

......livenessProbe:tcpSocket:port: 8080......

创建http-liveness.yaml​​​​​​​

apiVersion: v1kind: Podmetadata:labels:app: livenessname: liveness-httpnamespace: testspec:containers:- name: nginximage: nginx:latestlivenessProbe:httpGet:path: /testport: 80scheme: HTTPhttpHeaders:- name: Acceptvalue: application/jsoninitialDelaySeconds: 5periodSeconds: 5

在配置文件中,periodSeconds 指定了 kubelet 应该每 5 秒执行一次存活探测,initialDelaySeconds指定 kubelet 在容器启动后等待 5 秒再开始探测。kubelet 会向容器内运行的服务(host-默认为pod的ip,port为80)发送一个HTTP GET 请求来执行探测, 如果服务器上 "/" 路径下的处理程序返回成功,则 kubelet 认为容器是健康存活的,如果处理程序返回失败,则 kubelet 会杀死这个容器并将其重启

判断标准:返回大于或等于 200 并且小于 400 的任何代码都标示成功,其它返回代码都标示失败;

创建pod​​​​​​​

[root@master ~]# kubectl apply -f http-liveness.yamlpod/liveness-http created

此时,kubelet访问的探测地址为http://podid:80/abc,因容器内nginx服务不存在该路径地址,则会返回404状态码,查看pod状态显示健康检查失败,Liveness probe failed: HTTP probe failed with  statuscode: 404,kubelet 会杀死容器并再次重新启动容器。​​​​​​​

Events:Type Reason Age From Message---- ------ ---- ---- -------Normal Scheduled 14m Successfully assignedtest/liveness-http to masterNormal Pulled 11m kubelet, master Successfully pulledimage "nginx:latest" in 2m17.669916167sNormal Pulled 11m kubelet, master Successfully pulledimage "nginx:latest" in 3.366871547sNormal Created 11m (x3 over 11m) kubelet, master Created containernginxNormal Pulled 11m kubelet, master Successfully pulledimage "nginx:latest" in 3.539110367sNormal Started 11m (x3 over 11m) kubelet, master Started containernginxNormal Killing 10m (x3 over 11m) kubelet, master Container nginxfailed liveness probe, will be restartedNormal Pulling 10m (x4 over 14m) kubelet, master Pulling image"nginx:latest"Warning Unhealthy 9m9s (x18 over 11m) kubelet, master Liveness probefailed: HTTP probe failed with statuscode: 404Warning BackOff 4m3s (x28 over 10m) kubelet, master Back-off restartingfailed container

HTTPGet:调用容器内Web应用的URL,如果返回的状态码在200和399之间,则认为程序正常,否则不正常。​​​​​​​

......lifecycle:postStart:httpGet:path: #uri地址port:host:scheme: HTTP #支持的协议,http或者https......

TCP 检测的配置和 HTTP 检测方式相近,只需要配置端口即可。如果能建立连接,这个容器就被看作是健康的,脚本片断如下:

containers:- name: nginximage: nginx:latestreadinessProbe:tcpSocket:port: 8080initialDelaySeconds: 5periodSeconds: 10livenessProbe:tcpSocket:port: 8080initialDelaySeconds: 15periodSeconds: 20

03重启策略

重启策略:Pod在遇到故障之后重启的动作

  • 1. Always:当容器终止退出后,总是重启容器,默认策略

  • 2. OnFailure:当容器异常退出(退出状态码非0)时,重启容器

  • 3. Never:当容器终止退出,从不重启容器。

(注意:k8s中不支持重启Pod资源,只有删除重建,重建)

重启策略适用于pod对象中的所有容器,首次需要重启的容器,将在其需要时立即进行重启,随后再次需要重启的操作将由kubelet延迟一段时间后进行,且反复的重启操作的延迟时长为10s,20s,40s,80s,160s,300s,300s是最大延迟时长;

重启策略设置建议:

因为重启策略默认的就是Always,这也是合理的,因此在一般情况下,重启策略不需要设置,这里仅仅是作为知识点拿出来展示一下,在实际使用中,在大多数情况下都不需要进行重启策略配置。

1)Always​​​​​​​

[root@master test]# vim always.yamlapiVersion: v1kind: Podmetadata:name: always-restartnamespace: testspec:containers:- name: busyboximage: busyboxargs:- /bin/sh- -c- sleep 30; exit 3

创建pod

[root@master ~]# kubectl apply -f always.yaml

查看pod重启情况​​​​​​​

[root@master ~]# kubectl get pods -n testNAME READY STATUS RESTARTS AGEalways-restart 0/1 Error 1 107s[root@master ~]# kubectl describe pods always-restart -n testEvents:Type Reason Age From Message---- ------ ---- ---- -------Normal Scheduled 4m6s Successfully assignedtest/always-restart to masterNormal Pulled 3m28s kubelet, master Successfully pulledimage "busybox" in 36.172410045sNormal Pulled 2m54s kubelet, master Successfully pulledimage "busybox" in 3.248301356sNormal Pulled 2m10s kubelet, master Successfully pulledimage "busybox" in 3.068738872sNormal Created 73s (x4 over 3m28s) kubelet, master Created containerbusyboxNormal Started 73s (x4 over 3m28s) kubelet, master Started containerbusyboxNormal Pulled 73s kubelet, master Successfully pulledimage "busybox" in 3.686230207sWarning BackOff 15s (x6 over 2m23s) kubelet, master Back-off restartingfailed containerNormal Pulling 1s (x5 over 4m4s) kubelet, master Pulling image"busybox"

2)never​​​​​​​

[root@master test]# vim never.yamlapiVersion: v1kind: Podmetadata:name: never-alwaysnamespace: testspec:containers:- name: busyboximage: busyboxargs:- /bin/sh- -c- sleep 30; exit 3restartPolicy: Never

创建pod​​​​​​​

[root@master ~]# kubectl apply -f never.yamlpod/never-restart created

查看pod重启情况​​​​​​​

[root@master ~]# kubectl get pod never-restart -n testNAME READY STATUS RESTARTS AGEnever-restart 0/1 Error 0 73s

3)onfailure

终止退出容器,并且是非零状态的退出​​​​​​​

[root@master test]# vim onfailure.yamlapiVersion: v1kind: Podmetadata:name: onfailure1-restartnamespace: testspec:containers:- name: busyboximage: busyboxargs:- /bin/sh- -c- sleep 20; exit 3restartPolicy: OnFailure

创建pod​​​​​​​

[root@master ~]# kubectl apply -f onfailure.yamlpod/onfailure1-restart created

查看pod的状态​​​​​​​

[root@master ~]# kubectl get pod onfailure1-restart -n testNAME READY STATUS RESTARTS AGEonfailure1-restart 1/1 Running 2 74s

将退出状态改为0​​​​​​​

apiVersion: v1kind: Podmetadata:name: onfailure1-restartnamespace: testspec:containers:- name: busyboximage: busyboxargs:- /bin/sh- -c- sleep 20; exit 0restartPolicy: OnFailure

创建pod​​​​​​​

[root@master ~]# kubectl apply -f onfailure.yamlpod/onfailure1-restart created

查看 pod状态​​​​​​​

[root@master ~]# kubectl get pod onfailure1-restart -n testNAME READY STATUS RESTARTS AGEonfailure1-restart 0/1 Completed 0 74s

http://www.kler.cn/a/586303.html

相关文章:

  • 面向神经机器翻译的多语言去噪预训练
  • 力扣 Hot 100 刷题记录 - 对称二叉树
  • C++前缀和
  • env.development.local 和 env.development 的区别
  • MySQL EXPLAIN 详解
  • python 提取视频中的音频
  • 9月论文学习
  • Houdini学习笔记
  • 蓝桥杯15届省C
  • Apache Shiro反序列化漏洞深度剖析:从原理到利用
  • 32、构造函数
  • MySQL的行级锁锁的到底是什么?
  • 高防ip有哪些优点?ip欺骗攻击的原理是什么
  • 添加 ChatGPT/Grok/Gemini 到浏览器搜索引擎
  • 【Python】PyQt5在PyCharm的配置与应用
  • 【 PyQt】事件的触发:信号与槽
  • js原型链污染
  • AI辅助编程!DeepSeek vs ChatGPT- AI在地图网络分析(最佳路径)上的应用
  • 虚拟展览馆小程序:数字艺术与文化展示的新形式探索
  • 【蓝桥杯集训·每日一题2025】AcWing 6134. 哞叫时间II