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
状态经历了如下变化:
-
刚被创建时,
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。