虚拟化容器,大数据,DBA,中间件,监控。

Kubernetes 健康检查之 Readiness 就绪检查

21 12月
作者:admin|分类:容器虚拟化

 

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。

浏览324 评论0
返回
目录
返回
首页
Kubernetes 生命周期 钩子 pod hook Kubernetes 健康检查之 livenessProbe 存活检查