Kubernetes 健康检查之 Readiness 就绪检查

  • Post author:
  • Post category:其他


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        <none>        443/TCP        15d
webapp       NodePort    10.98.80.3       <none>        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

状态经历了如下变化:

  1. 刚被创建时,

    READY

    状态为不可用。

  2. 10 秒后(initialDelaySeconds + periodSeconds),第一次进行 Readiness 探测并成功返回,设置

    READY

    为可用。

  3. 之后我们手动删除了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 探测做个比较:

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

  2. 两种探测的配置方法完全一样,支持的配置参数也一样。不同之处在于探测失败后的行为:


    Liveness 探测是重启容器;Readiness 探测则是将容器设置为不可用,不接收 Service 转发的请求。

  3. Liveness 探测和 Readiness 探测是独立执行的,二者之间没有依赖,所以可以单独使用,也可以同时使用。


    用 Liveness 探测判断容器是否需要重启以实现自愈,用 Readiness 探测判断容器是否已经准备好对外提供服务。

理解了 Liveness 探测和 Readiness 探测的原理,下一节我们会讨论如何在业务场景中使用 Health Check。



版权声明:本文为qq_34556414原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。