Kubernetes三种探针
k8s支持存活livenessProbe和就绪readinessProbe两种探针,两种探针都支持以下三种方式


一、exec

通过执行shell命令的方式,判断退出状态码是否是0,示例:

  exec:
    command:
    - cat
    - /tmp/healthy

二、tcp

通过TCP请求的方式,是否能建立tcp连接,示例:

  tcpSocket:
    port: 8080
  initialDelaySeconds: 15
  periodSeconds: 20

三、httpGet

通过发起http请求,判断返回结果是否符合预期,示例:

...
livenessProbe:
httpGet:
path: /healthz
port: 8080
httpHeaders:

  • name: X-Custom-Header
    value: Awesome
    initialDelaySeconds: 3
    periodSeconds: 3
    initialDelaySeconds指定了容器启动后多少秒后进行探测
    periodSeconds指定每隔多少秒进行探测

Readiness 探测
健康检查有以下两种类型:

• livenessProbe(存活检查):如果检查失败,将杀死容器,根据Pod的restartPolicy来操作。

• readinessProbe(就绪检查):如果检查失败,Kubernetes会把Pod从service endpoints中剔除。(不会接收新的流量)

• startupProbe(启动检查):

访问service的时候实际上会帮你转发到后面的pod当中。配置健康检查的目的,第一种存活性探测如果应用挂了,尝试帮你重启看能不能恢复。第二种就绪性检查会判断pod当中的应用程序是否准备就绪,如果没有准备就绪就直接在servcie这里摘除,service就像负载均衡一样转发到后端的3个pod,如果其中一个pod有问题,就需要将其摘除,这样再访问负载均衡器service就不会转发到后端有问题的pod上了,就绪健康检查就起到这么一个作用。

所以健康检查和就绪性检查时不同维度的

启动检查是来判断容器有没有启动好了,1.16版本之后支持的,这种使用不是特别多,使用上面两种足够满足大部分应用场景

除了 Liveness探测,Kubernetes Health Check 机制还包括 Readiness 探测。

用户通过 Liveness 探测可以告诉 Kubernetes 什么时候通过重启容器实现自愈。Readiness 探测则是告诉 Kubernetes 什么时候可以将容器加入到 Service 负载均衡池中,对外提供服务。

Readiness 探测的配置语法与 Liveness 探测完全一样,下面是个例子:

[root@k8s-master ~]# cat readiness-pod.yml
apiVersion: apps/v1
kind: Deployment
metadata:
name: pod-readiness
namespace: default
spec:
replicas: 3
selector:
matchLabels:
app: readiness
template:
metadata:
labels:
app: readiness
spec:
containers:

  • name: web-readniness
    image: nginx
    ports:

    • name: http
      containerPort: 80
      readinessProbe:
      httpGet:
      port: http
      path: /index.html
      initialDelaySeconds: 5
      periodSeconds: 5

      apiVersion: v1
      kind: Service
      metadata:
      name: webapp
      namespace: default
      spec:
      ports:

      • port: 80
        protocol: TCP
        targetPort: 80
        selector:
        app: readiness
        type: NodePort
        这个配置文件只是将前面例子中的 liveness 替换为了 readiness,我们看看有什么不同的效果。

[root@k8s-master ~]# kubectl apply -f readiness-pod.yml
deployment.apps/pod-readiness created

[root@k8s-master ~]# kubectl get pod
NAME READY STATUS RESTARTS AGE
pod-readiness-5f9486d555-8gx54 1/1 Running 0 4m30s
pod-readiness-5f9486d555-9956t 1/1 Running 0 4m28s
pod-readiness-5f9486d555-qp77t 1/1 Running 0 4m28s

[root@k8s-master ~]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 443/TCP 15d
webapp NodePort 10.98.80.3 80:30891/TCP 6m34s

[root@k8s-master ~]# kubectl get ep
NAME ENDPOINTS AGE
kubernetes 192.168.179.102:6443 15d
webapp 10.244.169.148:80,10.244.36.96:80,10.244.36.97:80 6m2s
如果删除网页,那么就不会将pod关联到后端

[root@k8s-master ~]# kubectl get ep -w
NAME ENDPOINTS AGE
kubernetes 192.168.179.102:6443 15d
webapp 10.244.169.148:80,10.244.36.96:80,10.244.36.97:80 6m25s

[root@k8s-master ~]# kubectl exec -it pod-readiness-5f9486d555-8gx54 -- sh

rm -rf /usr/share/nginx/html/index.html

exit

由于健康检查没有通过,所以pod处于未就绪状态

[root@k8s-master ~]# kubectl get pod
NAME READY STATUS RESTARTS AGE
pod-readiness-5f9486d555-8gx54 0/1 Running 0 10m
pod-readiness-5f9486d555-9956t 1/1 Running 0 10m
pod-readiness-5f9486d555-qp77t 1/1 Running 0 10m

[root@k8s-master ~]# kubectl describe pod pod-readiness-5f9486d555-8gx54
Events:
Type Reason Age From Message


Normal Pulling 8h kubelet, k8s-node2 Pulling image "nginx"
Normal Pulled 8h kubelet, k8s-node2 Successfully pulled image "nginx" in 34.499922944s
Normal Created 8h kubelet, k8s-node2 Created container web-readniness
Normal Started 8h kubelet, k8s-node2 Started container web-readniness
Warning Unhealthy 8h (x23 over 8h) kubelet, k8s-node2 Readiness probe failed: HTTP probe failed with statuscode: 404

可以看到由于就绪健康检查没有通过,其中一个pod被踢出了service(这个时看到从service后端剔除,也就是从负载均衡里剔除)

[root@k8s-master ~]# kubectl get ep -w
NAME ENDPOINTS AGE
kubernetes 192.168.179.102:6443 15d
webapp 10.244.169.148:80,10.244.36.96:80,10.244.36.97:80 6m25s

webapp 10.244.36.96:80,10.244.36.97:80 7m36s
Pod readiness 的 READY 状态经历了如下变化:

刚被创建时,READY 状态为不可用。

10 秒后(initialDelaySeconds + periodSeconds),第一次进行 Readiness 探测并成功返回,设置 READY 为可用。

之后我们手动删除了index.html文件,连续 3 次 Readiness 探测均失败后,READY 被设置为不可用。

通过 kubectl describe pod readiness 也可以看到 Readiness 探测失败的日志。

[root@k8s-master ~]# kubectl describe pod pod-readiness-5f9486d555-8gx54
Events:
Type Reason Age From Message


Normal Pulling 8h kubelet, k8s-node2 Pulling image "nginx"
Normal Pulled 8h kubelet, k8s-node2 Successfully pulled image "nginx" in 34.499922944s
Normal Created 8h kubelet, k8s-node2 Created container web-readniness
Normal Started 8h kubelet, k8s-node2 Started container web-readniness
Warning Unhealthy 8h (x23 over 8h) kubelet, k8s-node2 Readiness probe failed: HTTP probe failed with statuscode: 404
如果我们手动恢复一下之前删除的index.html再来看看会发生什么

[root@k8s-master ~]# kubectl exec -it pod-readiness-5f9486d555-8gx54 -- sh

echo "" > /usr/share/nginx/html/index.html

健康检查通过加入service

[root@k8s-master ~]# kubectl get ep -w
NAME ENDPOINTS AGE
kubernetes 192.168.179.102:6443 15d
webapp 10.244.169.148:80,10.244.36.96:80,10.244.36.97:80 6m25s

webapp 10.244.36.96:80,10.244.36.97:80 7m36s

webapp 10.244.169.148:80,10.244.36.96:80,10.244.36.97:80 13m

[root@k8s-master ~]# kubectl get pod
NAME READY STATUS RESTARTS AGE
pod-readiness-5f9486d555-8gx54 1/1 Running 0 16m
pod-readiness-5f9486d555-9956t 1/1 Running 0 16m
pod-readiness-5f9486d555-qp77t 1/1 Running 0 16m
可以看到进行 Readiness 探测并成功返回,设置 READY 为可用。

总结Liveness 和 Readiness
下面对 Liveness 探测和 Readiness 探测做个比较:

Liveness 探测和 Readiness 探测是两种 Health Check 机制,如果不特意配置,Kubernetes 将对两种探测采取相同的默认行为,即通过判断容器启动进程的返回值是否为零来判断探测是否成功。

两种探测的配置方法完全一样,支持的配置参数也一样。不同之处在于探测失败后的行为:Liveness 探测是重启容器;Readiness 探测则是将容器设置为不可用,不接收 Service 转发的请求。

Liveness 探测和 Readiness 探测是独立执行的,二者之间没有依赖,所以可以单独使用,也可以同时使用。用 Liveness 探测判断容器是否需要重启以实现自愈,用 Readiness 探测判断容器是否已经准备好对外提供服务。

理解了 Liveness 探测和 Readiness 探测的原理,下一节我们会讨论如何在业务场景中使用 Health Check。
原文链接:https://blog.csdn.net/qq_34556414/article/details/108798751

最后修改日期: 2021年4月10日

作者

留言

撰写回覆或留言

发布留言必须填写的电子邮件地址不会公开。