下载安卓APP箭头
箭头给我发消息

客服QQ:3315713922

[云原生] Kubernetes(k8s)健康检查详解与实战演示(就绪性探针 和 存活性探针)

作者:匿名     来源: 云计算点击数:301发布时间: 2023-02-11 22:28:04

标签: 云原生Kubernetesk8s

  liveness probes​ 在线检查机制,检查应用是否可用,如死锁,无法响应,异常时将根据restartPolicy来设置 Pod 状态会自动重启容器,如果容器不提供存活探针,则默认状态为 Success。

  一、概述

  Kubernetes中的健康检查主要使用 就绪性探针(readinessProbes​)和 存活性探针(livenessProbes) 来实现,service即为负载均衡,k8s保证 service 后面的 pod 都可用,是k8s中自愈能力的主要手段,主要基于这两种探测机制,可以实现如下需求:

  异常实例自动剔除,并重启新实例

  多种类型探针检测,保证异常pod不接入流量

  不停机部署,更安全的滚动升级

  官方文档:https://kubernetes.io/zh-cn/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/Kubernetes(k8s)环境部署可以参考我这篇文章:Kubernetes(k8s)最新版最完整版环境部署+master高可用实现(k8sV1.24.1+dashboard+harbor)

  1)k8s中的探针种类

  1、就绪检查(readinessProbe,就绪探针)

  readiness probes​ 准备就绪检查,通过readiness是否准备接受流量,准备完毕加入到Endpoint,否则剔除。如果容器不提供就绪探针,则默认状态为 Success。

  2、存活检查(livenessProbe,存活探针)

  liveness probes​ 在线检查机制,检查应用是否可用,如死锁,无法响应,异常时将根据restartPolicy来设置 Pod 状态会自动重启容器,如果容器不提供存活探针,则默认状态为 Success。

  restartPolicy有三个可选值:

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

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

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

  3、启动检查(startupProbe,启动探针,1.17 版本新增)

  startupProbes 启动检查机制,应用一些启动缓慢的业务,避免业务长时间启动而被前面的探针kill掉。

  判断容器内的应用程序是否已启动,主要针对于不能确定具体启动时间的应用。如果匹配了startupProbes 探测,则在 startupProbes 状态为 Success 之前,其他所有探针都处于无效状态,直到它成功后其他探针才起作用。

  如果startupProbe 失败,kubelet 将杀死容器,容器将根据 restartPolicy 来重启。如果容器没有配置 startupProbe,则默认状态为 Success。其实一般主要是设置上面两种即可。

  就绪、存活两种探针的区别:

  readinessProbe 和 livenessProbe 可以使用相同探测方式,只是对 Pod 的处置方式不同。

  livenessProbe 当检测失败后,将杀死容器并根据 Pod 的重启策略来决定作出对应的措施。

  readinessProbe 当检测失败后,将 Pod 的 IP:Port 从对应的 EndPoint 列表中删除。

  2)k8s中的三种探测方式

  每种探测机制支持三种健康检查方法,分别是命令行exec,httpGet和tcpSocket,其中exec通用性最强,适用与大部分场景,tcpSocket适用于TCP业务,httpGet适用于web业务。

  exec(自定义健康检查):在容器中执行指定的命令,如果执行成功,退出码为 0 则探测成功。

  httpGet:通过容器的IP地址、端口号及路径调用 HTTP Get方法,如果响应的状态码大于等于200且小于400,则认为容器 健康。

  tcpSocket:通过容器的 IP 地址和端口号执行 TCP 检 查,如果能够建立 TCP 连接,则表明容器健康。

  探针探测结果有以下值:

  Success:表示通过检测。

  Failure:表示未通过检测。

  Unknown:表示检测没有正常进行。

  二、readinessProbe(就绪性探针)

  readiness probe 就绪性探针,用于判断容器内的程序是否存活(或者说是否健康),只有程序(服务)正常, 容器开始对外提供网络访问(启动完成并就绪);

  容器启动后按照readiness probe配置进行探测,无问题后结果为成功即状态为 Success;

  pod的READY状态为 true,从0/1变为1/1。如果失败继续为0/1,状态为 false;

  若未配置就绪探针,则默认状态容器启动后为Success​。对于此pod、此pod关联的Service资源、EndPoint 的关系也将基于 Pod 的 Ready 状态进行设置;

  如果 Pod 运行过程中Ready 状态变为 false,则系统自动从 Service​资源 关联的 EndPoint​列表中去除此pod,届时service资源接收到GET请求后,kube-proxy将一定不会把流量引入此pod中,通过这种机制就能防止将流量转发到不可用的 Pod 上。

  如果Pod 恢复为 Ready 状态。将再会被加回 Endpoint​ 列表。kube-proxy也将有概率通过负载机制会引入流量到此pod中。

  三、livenessProbe(存活性探针)

  liveness probe存活性探针,用于判断容器是不是健康,如果不满足健康条件,那么 Kubelet 将根据 Pod 中设置的 restartPolicy (重启策略)来判断,Pod 是否要进行重启操作;

  LivenessProbe按照配置去探测 (进程、或者端口、或者命令执行后是否成功等等),来判断容器是不是正常;

  如果探测不到,代表容器不健康(可以配置连续多少次失败才记为不健康),则 kubelet 会杀掉该容器,并根据容器的重启策略做相应的处理;

  如果未配置存活探针,则默认容器启动为通过(Success)状态。即探针返回的值永远是 Success。即Success后pod状态是RUNING。

  四、实战演示

  常用的探针可选参数:

参数名称 默认值 最小值 描述
initialDelaySeconds 0秒 0秒 探测延迟时长,容器启动后多久开始进行第一次探测工作。
periodSeconds 10秒 1秒 探测频度,频率过高会对pod带来较大的额外开销,频率过低则无法及时反映容器产生的错误。
timeoutSeconds 1秒 1秒 探测的超时时长。
failureThreshold 3 1 处于成功状态时,探测连续失败几次可被认为失败。
successThreshold 1 1 处于失败状态时,探测连续成功几次,被认为成功。

  1)exec方式

  复制

  1.  cat >exec-liveness.yaml<<eof< p="">

  2.  apiVersion: v1

  3.  kind: Pod

  4.  metadata:

  5.  labels:

  6.  test: liveness

  7.  name: liveness-exec

  8.  spec:

  9.  # 为了测试方便,指定调度机器

  10.  nodeName: local-168-182-110

  11.  containers:

  12.  - name: liveness

  13.  image: registry.aliyuncs.com/google_containers/busybox

  14.  args:

  15.  - /bin/sh

  16.  - -c

  17.  - touch /tmp/healthy; sleep 30; rm -f /tmp/healthy; sleep 600

  18.  livenessProbe:

  19.  exec:

  20.  command:

  21.  - cat

  22.  - /tmp/healthy

  23.  initialDelaySeconds: 5

  24.  periodSeconds: 5

  25.  EOF

  解释:

  initialDelaySeconds 字段告诉 kubelet 在执行第一次探测前应该等待 5 秒。

  periodSeconds 字段指定了 kubelet 应该每 5 秒执行一次存活探测。

  kubelet 在容器内执行命令cat /tmp/healthy 来进行探测。

  如果命令执行成功并且返回值为 0,kubelet 就会认为这个容器是健康存活的。

  如果这个命令返回非 0 值,kubelet 会杀死这个容器并重新启动它。

  当容器启动时,执行如下的命令:

  复制

  1.  /bin/sh -c "touch /tmp/healthy; sleep 30; rm -f /tmp/healthy; sleep 600"

  这个容器生命的前 30 秒,/tmp/healthy 文件是存在的。 所以在这最开始的 30 秒内,执行命令 cat /tmp/healthy 会返回成功代码。 30 秒之后,执行命令 cat /tmp/healthy 就会返回失败代码。

  创建 Pod:

  复制

  1.  # 最好先拉取镜像,如果是使用docker,就换成docker就行

  2.  crictl pull registry.aliyuncs.com/google_containers/busybox

      3.

  4.  kubectl apply -f exec-liveness.yaml

  【问题】ERRO[0000] unable to determine image API version: rpc error: code = Unavailable desc = connection error: desc = “transport: Error while dialing dial unix /var/run/dockershim.sock: connect: no such file or directory”【解决】原因:未配置endpoints

  复制

  1.  crictl config runtime-endpoint unix:///run/containerd/containerd.sock

  2.  crictl config image-endpoint unix:///run/containerd/containerd.sock

  查看

  复制

  1.  kubectl describe pod liveness-exec

  【现象】30s之后检查失败后就重启pod了,又正常了。

  2)httpGet 方式

  复制

  1.  cat >http-liveness.yaml<<eof< p="">

  2.  apiVersion: v1

  3.  kind: Pod

  4.  metadata:

  5.  name: liveness-httpget

  6.  namespace: default

  7.  spec:

  8.  # 为了测试方便,指定调度机器

  9.  nodeName: local-168-182-110

  10.  containers:

  11.  - name: liveness-httpget-container

  12.  image: nginx

  13.  imagePullPolicy: IfNotPresent

  14.  ports:

  15.  - name: nginx

  16.  containerPort: 80

  17.  livenessProbe:

  18.  httpGet:

  19.  port: nginx

  20.  path: /index.html

  21.  initialDelaySeconds: 1

  22.  periodSeconds: 3

  23.  timeoutSeconds: 10

  24.  EOF

  解释:

  initialDelaySeconds字段告诉 kubelet 在执行第一次探测前应该等待 1 秒。

  periodSeconds 字段指定了 kubelet 每隔 3 秒执行一次存活探测。

  kubelet 会向容器内运行的服务(服务在监听 80 端口)发送一个 HTTP GET 请求来执行探测。

  如果服务器上/index.html路径下的处理程序返回成功代码,则 kubelet 认为容器是健康存活的。

  如果处理程序返回失败代码,则 kubelet 会杀死这个容器并将其重启。

  返回大于或等于 200​ 并且小于 400 的任何代码都标示成功,其它返回代码都标示失败。

  执行并查看

  复制

  1.  crictl pull nginx

  2.  kubectl apply -f http-liveness.yaml

  3.  kubectl describe pod liveness-httpget

  删除 Pod 的 index.html 文件

  复制

  1.  kubectl exec -it liveness-httpget -- rm -rf /usr/share/nginx/html/index.html

  2.  # 再查看

  3.  kubectl describe pod liveness-httpget

  4.  kubectl get pod liveness-httpget

  重启原因是 HTTP 探测得到的状态返回码是 404,Liveness probe failed: HTTP probe failed with statuscode: 404。

  重启完成后,不会再次重启,因为重新拉取的镜像中包含了 index.html 文件。

  HTTP Probes 允许针对 httpGet 配置额外的字段:

  host:连接使用的主机名,默认是 Pod 的 IP。也可以在 HTTP 头中设置 “Host” 来代替。

  scheme :用于设置连接主机的方式(HTTP 还是 HTTPS)。默认是 "HTTP"。

  path:访问 HTTP 服务的路径。默认值为 "/"。

  httpHeaders:请求中自定义的 HTTP 头。HTTP 头字段允许重复。

  port:访问容器的端口号或者端口名。如果数字必须在 1~65535 之间。

  你可以通过为探测设置 .httpHeaders 来重载默认的头部字段值;例如:

  复制

  1.  livenessProbe:

  2.  httpGet:

  3.  httpHeaders:

  4.  - name: Accept

  5.  value: application/json

      6.

  7.  startupProbe:

  8.  httpGet:

  9.  httpHeaders:

  10.  - name: User-Agent

  11.  value: MyUserAgent

  3)tcpSocket 方式

  复制

  1.  cat >tcp-liveness-readiness.yaml<<eof< p="">

  2.  apiVersion: v1

  3.  kind: Pod

  4.  metadata:

  5.  name: liveness-readiness-tcpsocket

  6.  labels:

  7.  app: liveness-readiness-tcpsocket

  8.  spec:

  9.  # 为了测试方便,指定调度机器

  10.  nodeName: local-168-182-110

  11.  containers:

  12.  - name: liveness-readiness-tcpsocket

  13.  image: nginx

  14.  ports:

  15.  - containerPort: 80

  16.  readinessProbe:

  17.  tcpSocket:

  18.  port: 80

  19.  initialDelaySeconds: 5

  20.  periodSeconds: 10

  21.  livenessProbe:

  22.  tcpSocket:

  23.  port: 80

  24.  initialDelaySeconds: 15

  25.  periodSeconds: 20

  26.  EOF

  解释:

  kubelet 会在容器启动 5 秒后发送第一个就绪探测(livenessProbe)。

  探测器会尝试连接 goproxy 容器的 80 端口。 如果探测成功,这个 Pod 会被标记为就绪状态,kubelet 将继续每隔 10 秒运行一次检测。

  除了就绪探测,这个配置包括了一个存活探测(livenessProbe)。

  kubelet 会在容器启动15 秒后进行第一次存活探测(livenessProbe)。

  与就绪探测类似,活跃探测器会尝试连接 goproxy 容器的 80 端口。 如果存活探测失败,容器会被重新启动。执行

  复制

  1.  kubectl apply -f tcp-liveness-readiness.yaml

  2.  kubectl get pod liveness-readiness-tcpsocket

  3.  kubectl describe pod liveness-readiness-tcpsocket

  4)使用命名端口

  对于 HTTP 或者 TCP 存活检测可以使用命名的 port。

  复制

  1.  ports:

  2.  - name: nginx

  3.  containerPort: 80

  4.  hostPort: 80

      5.

  6.  livenessProbe:

  7.  httpGet:

  8.  path: /index.html

  9.  port: nginx

  完整版配置

  复制

  1.  ports:

  2.  - name: nginx

  3.  containerPort: 80

  4.  hostPort: 80

      5.

  6.  # readinessProbe,就绪探针

  7.  livenessProbe:

  8.  httpGet:

  9.  path: /index.html

  10.  port: nginx

  11.  # 延迟多久后开始探测

  12.  initialDelaySeconds: 10

  13.  # 执行探测频率(秒) 【 每隔秒执行一次 】

  14.  periodSeconds: 10

  15.  # 超时时间

  16.  timeoutSeconds: 1

  17.  # 处于成功状态时,探测连续失败几次可被认为失败。

  18.  failureThreshold: 3

  19.  # 处于失败状态时,探测连续成功几次,被认为成功。

  20.  successThreshold: 1

      21.

  22.  # livenessProbe,存活探针

  23.  livenessProbe:

  24.  httpGet:

  25.  path: /index.html

  26.  port: nginx

  27.  # 延迟多久后开始探测

  28.  initialDelaySeconds: 10

  29.  # 执行探测频率(秒) 【 每隔秒执行一次 】

  30.  periodSeconds: 10

  31.  # 超时时间

  32.  timeoutSeconds: 1

  33.  # 处于成功状态时,探测连续失败几次可被认为失败。

  34.  failureThreshold: 3

  35.  # 处于失败状态时,探测连续成功几次,被认为成功。

  36.  successThreshold: 1

      37.

  38.  # startupProbe,启动探针

  39.  startupProbe:

  40.  httpGet:

  41.  path: /index.html

  42.  port: nginx

  43.  # 延迟多久后开始探测

  44.  initialDelaySeconds: 10

  45.  # 执行探测频率(秒) 【 每隔秒执行一次 】

  46.  periodSeconds: 10

  47.  # 超时时间

  48.  timeoutSeconds: 1

  49.  # 处于成功状态时,探测连续失败几次可被认为失败。

  50.  failureThreshold: 3

  51.  # 处于失败状态时,探测连续成功几次,被认为成功。

  52.  successThreshold: 1

  一般使用控制器去创建管理pod,对k8s 控制器不清晰的小伙伴,可以参考我之前的文章:Kubernetes(k8s)Deployment、StatefulSet、DaemonSet、Job、CronJob五种控制器详解

  下面是一个完整版的示例:

  复制

  1.  apiVersion: apps/v1

  2.  kind: Deployment

  3.  metadata:

  4.  name: deployment-probe

  5.  spec:

  6.  replicas: 3

  7.  selector:

  8.  matchLabels:

  9.  app: deployment-probe

  10.  template:

  11.  metadata:

  12.  labels:

  13.  app: deployment-probe

  14.  spec:

  15.  containers:

  16.  - name: nginx

  17.  image: nginx:1.17.1

      18.

  19.  # readinessProbe,就绪探针

  20.  readinessProbe:

  21.  httpGet:

  22.  path: /index.html

  23.  port: nginx

  24.  # 延迟多久后开始探测

  25.  initialDelaySeconds: 10

  26.  # 执行探测频率(秒) 【 每隔秒执行一次 】

  27.  periodSeconds: 10

  28.  # 超时时间

  29.  timeoutSeconds: 1

  30.  # 处于成功状态时,探测连续失败几次可被认为失败。

  31.  failureThreshold: 3

  32.  # 处于失败状态时,探测连续成功几次,被认为成功。

  33.  successThreshold: 1

      34.

  35.  # livenessProbe,存活探针

  36.  livenessProbe:

  37.  httpGet:

  38.  path: /index.html

  39.  port: nginx

  40.  # 延迟多久后开始探测

  41.  initialDelaySeconds: 10

  42.  # 执行探测频率(秒) 【 每隔秒执行一次 】

  43.  periodSeconds: 10

  44.  # 超时时间

  45.  timeoutSeconds: 1

  46.  # 处于成功状态时,探测连续失败几次可被认为失败。

  47.  failureThreshold: 3

  48.  # 处于失败状态时,探测连续成功几次,被认为成功。

  49.  successThreshold: 1

      50.

  51.  # startupProbe,启动探针

  52.  startupProbe:

  53.  httpGet:

  54.  path: /index.html

  55.  port: nginx

  56.  # 延迟多久后开始探测

  57.  initialDelaySeconds: 10

  58.  # 执行探测频率(秒) 【 每隔秒执行一次 】

  59.  periodSeconds: 10

  60.  # 超时时间

  61.  timeoutSeconds: 1

  62.  # 处于成功状态时,探测连续失败几次可被认为失败。

  63.  failureThreshold: 3

  64.  # 处于失败状态时,探测连续成功几次,被认为成功。

  65.  successThreshold: 1

  执行查看

  复制

  1.  crictl pull nginx:1.17.1

  2.  kubectl apply -f deployment-probe.yaml

  3.  kubectl get pod,deploy

  Kubernetes(k8s)健康检查详解与实战演示就先到这里了,健康检查会伴随所有k8s编排任务,所以非常重要,其实也不难,小伙伴有什么疑问,欢迎给我留言哦~

  来源: 大数据与云原生技术分享

    >>>>>>点击进入计算专题

赞(10)
踩(0)
分享到:
华为认证网络工程师 HCIE直播课视频教程