【云原生 | 从零开始学Kubernetes】十三、k8s的容器探测以及启动探测 ...

打印 上一主题 下一主题

主题 842|帖子 842|积分 2526

该篇文章已经被专栏《从零开始学k8s》收录
上一篇文章:k8spod的生命周期与容器钩子点击跳转
  


  
存活性探测 livenessProbe 和停当性探测 readinessProbe

livenessProbe:存活性探测

许多应用程序颠末长时间运行,最终过渡到无法运行的状态,除了重启,无法规复。通常环境下,K8S 会发现应用程序已经终止,然后重启应用程序 pod。偶然应用程序大概因为某些原因(后端服务故障等)导致暂时无法对外提供服务,但应用软件没有终止,导致 K8S 无法隔离有故障的 pod,调用者大概会访问到有故障的 pod,导致业务不稳固。K8S 提供 livenessProbe 来检测容器是否正常运行,并且对相应状态进行相应的补救步伐。
readinessProbe:停当性探测

在没有配置 readinessProbe 的资源对象中,pod 中的容器启动完成后,就认为 pod 中的应用程序可以对外提供服务,该 pod 就会加入相对应的 service,对外提供服务。但偶然一些应用程序启动后,需要较长时间的加载才气对外服务,如果这时对外提供服务,执行效果一定无法达到预期效果,影响用户体验。好比使用 tomcat 的应用程序来说,并不是简单地说 tomcat 启动成功就可以 对外提供服务的,还需要等待 spring 容器初始化,数据库连接上等等。
现在 LivenessProbe 和 ReadinessProbe 两种探针都支持下面三种探测方法:
1、ExecAction:在容器中执行指定的命令,如果执行成功,退出码为 0 则探测成功。
2、TCPSocketAction:通过容器的 IP 地址和端口号执行 TCP 查抄,如果能够创建 TCP 连接, 则表明容器健康。
3、HTTPGetAction:通过容器的 IP 地址、端口号及路径调用 HTTP Get 方法,如果响应的状态码大于等于 200 且小于 400,则认为容器健康
探针探测效果有以下值:
1、Success:表现通过检测。
2、Failure:表现未通过检测。
3、Unknown:表现检测没有正常进行。
Pod 探针相关的属性

探针(Probe)有许多可选字段,可以用来更加精确的控制 Liveness 和 Readiness 两种探针的行为
initialDelaySeconds: Pod 启动后首次进行查抄的等待时间,单位“秒”。
periodSeconds: 查抄的隔断时间,默认为 10s,单位“秒”。
timeoutSeconds: 探针执行检测请求后,等待响应的超时时间,默认为 1s,单位“秒”。
successThreshold:连续探测几次成功,才认为探测成功,默认为 1,在 Liveness 探针中必须为 1,最小值为 1。
failureThreshold: 探测失败的重试次数,重试一定次数后将认为失败,在 readiness 探针中,Pod 会被标记为未停当,默认为 3,最小值为 1
两种探针区别:

ReadinessProbe 和 livenessProbe 可以使用类似探测方式,只是对 Pod 的处置方式不同:
readinessProbe 当检测失败后,将 Pod 的 IPort 从对应的 EndPoint 列表中删除。
livenessProbe 当检测失败后,将杀死容器并根据 Pod 的重启计谋来决定作出对应的步伐。
Pod 探针使用示例

1、LivenessProbe 探针使用示例

通过 exec 方式做健康探测
  1. [root@k8smaster node]# vim liveness-exec.yaml
  2. apiVersion: v1
  3. kind: Pod
  4. metadata:
  5.   name: liveness-exec
  6.   labels:
  7.     app: liveness
  8. spec:
  9.   containers:
  10.   - name: liveness
  11.     image: busybox
  12.     args: #创建测试探针探测的文件
  13.     - /bin/sh
  14.     - -c
  15.     - touch /tmp/healthy; sleep 30; rm -rf /tmp/healthy; sleep 600
  16.     livenessProbe:
  17.       initialDelaySeconds: 10 #延迟检测时间
  18.       periodSeconds: 5 #检测时间间隔
  19.       exec:
  20.         command:
  21.         - cat
  22.         - /tmp/healthy
  23. 容器启动设置执行的命令
  24. /bin/sh -c "touch /tmp/healthy; sleep 30; rm -rf /tmp/healthy; sleep 600" 容器在初始化后,首先创建一个 /tmp/healthy 文件,然后执行睡眠命令,睡眠 30 秒,到时间后执行删除 /tmp/healthy 文件命令。而设置的存活探针检检测方式为执行 shell 命令,用 cat 命令输出 healthy 文件的内容,如果能成功执行这条命令,存活探针就认为探测成功,否则探测失败。在前 30 秒内,由于文件存在,所以存活探针探测时执行 cat /tmp/healthy 命令成功执行。30 秒后 healthy 文件被删除,所以执行命令失败,Kubernetes 会根据 Pod 设置的重启策略来判断,是否重启 Pod。
  25. [root@k8smaster node]# kubectl apply -f liveness-exec.yaml
  26. pod/liveness-exec created
  27. [root@k8smaster node]# kubectl get pods
  28. NAME                    READY   STATUS    RESTARTS   AGE
  29. liveness-exec           1/1     Running   0          30s
  30. [root@k8smaster node]# kubectl exec -it liveness-exec -- /bin/sh
  31. / # cd /tmp/
  32. /tmp # ls
  33. /tmp #
  34. #进入容器之后发现文件被删除了
  35. [root@k8smaster node]# kubectl get pods
  36. NAME                    READY   STATUS    RESTARTS   AGE
  37. liveness-exec           1/1     Running   1          2m54s
  38. #然后过一会他就重启了 rest那里是1
  39. [root@k8smaster node]# kubectl describe pods liveness-exec
  40. Warning  Unhealthy  5s (x7 over 2m50s)   kubelet, k8snode2  Liveness probe failed: cat: can't open '/tmp/healthy': No such file or directory
  41. #可以在详细信息看到找不到文件
复制代码
通过 HTTP 方式做健康探测

  1. [root@k8smaster node]# vim liveness-http.yaml
  2. apiVersion: v1
  3. kind: Pod
  4. metadata:
  5.   name: liveness-http
  6.   labels:
  7.     app: liveness
  8. spec:
  9.   containers:
  10.   - name: liveness
  11.     image: mydlqclub/springboot-helloworld:0.0.1
  12.     livenessProbe:
  13.       initialDelaySeconds: 20 #延迟检测时间
  14.       periodSeconds: 5 #检测时间间隔
  15.       timeoutSeconds: 10  #超时时间设置
  16.       httpGet:
  17.         scheme: HTTP
  18.         port: 8081
  19.                 path: /actuator/health
  20.       readinessProbe:                #就绪型探测
  21.       initialDelaySeconds: 20
  22.       periodSeconds: 5
  23.       timeoutSeconds: 10
  24.       httpGet:
  25.         scheme: HTTP
  26.         port: 8081
  27.         path: /actuator/health
  28. 上面 Pod 中启动的容器是一个 SpringBoot 应用,其中引用了 Actuator 组件,提供了 /actuator/health 健康检查地址,存活探针可以使用 HTTPGet 方式向服务发起请求,请求 8081 端口的 /actuator/health 路径来进行存活判断。
  29. 任何大于或等于 200 且小于 400 的代码表示探测成功,任何其他代码表示失败。如果探测失败,则会杀死 Pod 进行重启操作。
  30. httpGet 探测方式有如下可选的控制字段:
  31. scheme: 用于连接 host 的协议,默认为 HTTP。
  32. host:要连接的主机名,默认为 Pod IP,可以在 http request head 中设置 host 头部。
  33. port:容器上要访问端口号或名称。
  34. path:http 服务器上的访问 URI。
  35. httpHeaders:自定义 HTTP 请求 headers,HTTP 允许重复 headers。
  36. [root@k8smaster node]# kubectl get pods
  37. NAME                    READY   STATUS             RESTARTS   AGE
  38. liveness-http           1/1     Running            0          35s
  39. [root@k8smaster node]# kubectl logs liveness-http | grep 8081
  40. 2022-07-10 19:04:19.392  INFO 1 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port(s): 8081 (http)
  41. 2022-07-10 19:04:19.510  INFO 1 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 8081 (http) with context path ''
  42. 2022-07-10 19:04:37.453  INFO 1 --- [nio-8081-exec-1] o.a.c.c.C.[Tomcat-1].[localhost].[/]     : Initializing Spring DispatcherServlet 'dispatcherServlet'
  43. 2022-07-10 19:04:37.453  INFO 1 --- [nio-8081-exec-1] o.s.web.servlet.DispatcherServlet        : Initializing Servlet 'dispatcherServlet'
  44. 2022-07-10 19:04:37.458  INFO 1 --- [nio-8081-exec-1] o.s.web.servlet.DispatcherServlet        : Completed initialization in 5 ms
  45. [root@k8smaster node]# curl http://10.244.1.7:8081/actuator/health
  46. {"status":"UP"}
  47. [root@k8smaster node]# curl -I http://10.244.1.7:8081/actuator/health
  48. HTTP/1.1 200
  49. Content-Type: application/vnd.spring-boot.actuator.v2+json;charset=UTF-8
  50. Transfer-Encoding: chunked
  51. Date: Sun, 10 Jul 2022 11:08:55 GMT
  52. #返回200状态码,启动成功!
复制代码
通过 TCP 方式做健康探测

  1. [root@k8smaster node]# vim liveness-tcp.yaml
  2. apiVersion: v1
  3. kind: Pod
  4. metadata:
  5.   name: liveness-tcp
  6.   labels:
  7.     app: liveness
  8. spec:
  9.   containers:
  10.   - name: liveness
  11.     image: nginx
  12.     livenessProbe:
  13.       initialDelaySeconds: 15
  14.       periodSeconds: 20   
  15.           tcpSocket:
  16.         port: 80
  17. TCP 检查方式和 HTTP 检查方式非常相似,在容器启动 initialDelaySeconds 参数设定的时间后,kubelet 将发送第一个 livenessProbe 探针,尝试连接容器的 80 端口,如果连接失败则将杀死 Pod 重启容器。
  18. [root@k8smaster node]# kubectl apply -f liveness-tcp.yaml
  19. pod/liveness-tcp created
  20. [root@k8smaster node]# kubectl get pods
  21. NAME                    READY   STATUS    RESTARTS   AGE
  22. liveness-tcp            1/1     Running   0          19s
复制代码
2、ReadinessProbe 探针使用示例

Pod 的 ReadinessProbe 探针使用方式和 LivenessProbe 探针探测方法一样,也是支持三种,只是一个是用于探测应用的存活,一个是判定是否对外提供流量的条件。好比Springboot 项目,设置 ReadinessProbe 探测 SpringBoot 项目标 8081 端口下的 /actuator/health 接口,如果探测成功则代表内部程序以及启动,就开放对外提供接口访问,否则内部应用没有成功启动,暂不对外提供访问,直到停当探针探测成功。
两个也可以一起用。
  1. [root@k8smaster node]# vim readiness-exec.yaml
  2. apiVersion: v1
  3. kind: Service
  4. metadata:
  5.   name: springboot
  6.   labels:
  7.     app: springboot
  8. spec:
  9.   type: NodePort
  10.   ports:
  11.   - name: server
  12.     port: 8080
  13.     targetPort: 8080
  14.     nodePort: 31180
  15.   - name: management  
  16.     port: 8081
  17.     targetPort: 8081
  18.     nodePort: 31181
  19.   selector:
  20.     app: springboot
  21. ---
  22. apiVersion: v1
  23. kind: Pod
  24. metadata:
  25.   name: springboot
  26.   labels:
  27.     app: springboot
  28. spec:
  29.   containers:
  30.   - name: springboot
  31.     image: mydlqclub/springboot-helloworld:0.0.1
  32.     ports:
  33.     - name: server
  34.       containerPort: 8080
  35.     - name: management
  36.       containerPort: 8081
  37.     readinessProbe:
  38.       initialDelaySeconds: 20
  39.       periodSeconds: 5
  40.       timeoutSeconds: 10
  41.       httpGet:
  42.         scheme: HTTP
  43.         port: 8081
  44.         path: /actuator/health
  45. [root@k8smaster node]# kubectl apply -f readiness-exec.yaml
  46. service/springboot created
  47. pod/springboot created
  48. [root@k8smaster node]# kubectl get pods -o wide | grep springboot
  49. springboot              1/1     Running   0          42s     10.244.1.9    k8snode2   <none>         
复制代码
pod的启动探测

Kubernetes 的三种探针

livenessProbe:用于探测容器是否运行。如果存活探测失败,则 kubelet 会杀死容器,并且容器将受到其重启计谋的影响决定是否重启。如果容器不提供存活探针,则默认状态为 Success。
readinessProbe:一般用于探测容器内的程序是否健康,容器是否准备好服务请求。如果停当探测失败,endpoint 将从与 Pod 匹配的所有 Service 的端点中删除该 Pod 的 IP 地址。初始延迟之前的停当 状态默认为 Failure。如果容器不提供停当探针,则默认状态为 Success。
startupProbe: 探测容器中的应用是否已经启动。如果提供了启动探测(startup probe),则禁用所有其他探测,直到它成功为止。如果启动探测失败,kubelet 将杀死容器,容器服从其重启计谋进行重启。 如果容器没有提供启动探测,则默认状态为成功 Success。
可以自界说在 pod 启动时是否执行这些检测,如果不设置,则检测效果均默认为通过,如果设置, 则序次为 startupProbe>readinessProbe>livenessProbe。
为什么要用 startupProbe?

在 k8s 中,通过控制器管理 pod,如果更新 pod 的时候,会创建新的 pod,删除老的 pod,但是如果新的 pod 创建了,pod 里的容器还没完成初始化,老的 pod 就被删除了,会导致访问 service 大概 ingress 时候,访问到的 pod 是有题目标,所以 k8s 就加入了一些存活性探针:livenessProbe、停当性探针 readinessProbe 以及启动探针 startupProbe。
  1. startupProbe 是在 k8s v1.16 加入了 alpha 版,官方对其作用的解释是:
  2. Indicates whether the application within the Container is started. All other probes are disabled if a startup probe is provided, until it succeeds. If the startup probe fails, the kubelet kills the Container, and the Container is subjected to its restart policy. If a Container does not provide a startup probe, the default state is Success
  3. 翻译:判断容器内的应用程序是否已启动。如果提供了启动探测,则禁用所有其他探测,直到它成功为止。如果启动探测失败,kubelet 将杀死容器,容器将服从其重启策略。如果容器没有提供启动探测,则默认状态为成功。
复制代码
注意:不要将 startupProbe 和 readinessProbe 混淆。
什么时候会用 startupProbe 呢?

正常环境下,我们会在 pod template 中配置 livenessProbe 来探测容器是否正常运行,如果异常则会触发 restartPolicy 重启容器(因为默认环境下 restartPolicy 设置的是 always)
  1. livenessProbe:
  2.   httpGet:
  3.     path: /test
  4.     prot: 80
  5.   failureThreshold: 1
  6.   initialDelay:10
  7.   periodSeconds: 10
复制代码
上面配置的意思是容器启动 10s 后每 10s 查抄一次,允许失败的次数是 1 次。如果失败次数超过 1 则会触发 restartPolicy。
但是偶然候会存在特殊环境,好比服务 A 启动时间很慢,需要 60s。这个时候如果照旧用上面的探针就会进入死循环,因为上面的探针 10s 后就开始探测,这时候我们服务并没有起来,发现探测失败就会触发 restartPolicy。这时候有的朋侪大概会想到把 initialDelay 调成 60s 不就可以了?但是我们并不能保证这个服务每次起来都是 60s,假如新的版本起来要 70s,甚至更多的时间,我们就不好控制了。有的朋侪大概还会想到把失败次数增长,好比下面配置:
  1. livenessProbe:
  2.   httpGet:
  3.     path: /test
  4.     prot: 80
  5.   failureThreshold: 5
  6.   initialDelay:60
  7.   periodSeconds: 10
复制代码
这在启动的时候是可以解决我们现在的题目,但是如果这个服务挂了呢?如果 failureThreshold=1 则 10s 后就会报警关照服务挂了,如果设置了 failureThreshold=5,那么就需要 5*10s=50s 的时间,在如今大家追求快速发现、快速定位、快速响应的时代是不被允许的。
在这时候我们把 startupProbe 和 livenessProbe 结合起来使用就可以很大程度上解决我们的题目。
  1. livenessProbe:
  2.   httpGet:
  3.     path: /test
  4.     prot: 80
  5.   failureThreshold: 1
  6.   initialDelay:10
  7.   periodSeconds: 10
  8. startupProbe:   httpGet:     path: /test     prot: 80   failureThreshold: 10   initialDelay:10   periodSeconds: 10
复制代码
上面的配置是只有 startupProbe 探测成功后再交给 livenessProbe。我们 startupProbe 配置的是 10*10s,也就是说只要应用在 100s 内启动都是 OK 的,而且应用挂掉了 10s 就会发现题目。
实在这种照旧不能确定详细时间,只能给出一个大概的范围。我个人认为对服务启动时间的影响因素太多了,有大概是应用本身,有大概是外部因素,好比主机性能等等。我们只有在最大程度上追求高效、 稳固,但是我们不能保证 100%稳固,所以我们本身要做好监控有用性,告警的实时性,响应的快速性,处理的高效性。
K8s 的 LivenessProbe 和 ReadinessProbe 的启动序次题目

LivenessProbe 会导致 pod 重启,ReadinessProbe 只是不提供服务。我们最初的理解是 LivenessProbe 会在 ReadinessProbe 成功后开始查抄,但究竟并非云云。
kubelet 使用存活探测器来知道什么时候要重启容器。例如,存活探测器可以捕捉到死锁(应用程序在运行,但是无法继承执行背面的步骤)。这样的环境下重启容器有助于让应用程序在有题目标环境下可用。
kubelet 使用停当探测器可以知道容器什么时候准备好了并可以开始担当请求流量, 当一个 Pod 内的所有容器都准备好了,才气把这个 Pod 看作停当了,这种信号的一个用途就是控制哪个 Pod 作为 Service 的后端,在 Pod 还没有准备好的时候,会从 Service 的负载均衡器中被剔除的。
kubelet 使用启动探测器(startupProbe)可以知道应用程序容器什么时候启动了。如果配置了这类探测器,就可以控制容器在启动成功后再进行存活性和停当查抄,确保这些存活,停当探测器不会影响应用程序的启动。这可以用于对慢启动容器进行存活性检测,制止它们在启动运行之前就被杀掉。
真正的启动序次
官方文档:Caution: Liveness probes do not wait for readiness probes to succeed. If you want to wait before executing a liveness probe you should use initialDelaySeconds or a startupProbe.
也就是 Liveness probes 并不会比及 Readiness probes 成功之后才运行,根据上面的官方文档,Liveness 和 readiness 应该是某种并发的关系。
写在最后

创作不易,如果以为内容对你有资助,麻烦给个三连关注支持一下我!如果有错误,请在批评区指出,我会实时更改!
现在正在更新的系列:从零开始学k8s
感谢各位的观看,文章掺杂个人理解,如有错误请接洽我指出~


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

温锦文欧普厨电及净水器总代理

金牌会员
这个人很懒什么都没写!
快速回复 返回顶部 返回列表