我们可以通过Readiness检测来告诉K8s什么时候可以将pod加入到服务Service的负载均衡池中,对外提供服务,这个在生产场景服务发布新版本时非常重要,当我们上线的新版本发生程序错误时,Readiness会通过检测发布,从而不导入流量到pod内,将服务的故障控制在内部,在生产场景中,建议这个是必加的,Liveness不加都可以,因为有时候我们需要保留服务出错的现场来查询日志,定位问题,告之开发来修复程序。
Readiness 检测的配置语法与 Liveness 检测完全一样,下面是个例子:
apiVersion: v1
kind: Pod
metadata:
labels:
test: liveness
name: liveness
spec:
restartPolicy: OnFailure
containers:
- name: liveness
image: busybox
args:
- /bin/sh
- -c
- touch /tmp/healthy; sleep 30; rm -f /tmp/healthy; sleep 600
readinessProbe: # 这里将livenessProbe换成readinessProbe即可,其它配置都一样
exec:
command:
- cat
- /tmp/healthy
initialDelaySeconds: 10 # 容器启动 10 秒之后开始检测
periodSeconds: 5 # 每隔 5 秒再检测一次
保存上面这个配置为readiness.yaml,并执行它生成pod:
# kubectl apply -f readiness.yaml
pod/liveness created
# 观察,在刚开始创建时,文件并没有被删除,所以检测一切正常
# kubectl get pod
NAME READY STATUS RESTARTS AGE
liveness 1/1 Running 0 50s
# 然后35秒后,文件被删除,这个时候READY状态就会发生变化,K8s会断开Service到pod的流量
# kubectl describe pod liveness
......
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 56s default-scheduler Successfully assigned default/liveness to 10.0.1.203
Normal Pulling 56s kubelet Pulling image "busybox"
Normal Pulled 40s kubelet Successfully pulled image "busybox"
Normal Created 40s kubelet Created container liveness
Normal Started 40s kubelet Started container liveness
Warning Unhealthy 5s (x2 over 10s) kubelet Readiness probe failed: cat: can't open '/tmp/healthy': No such file or directory
# 可以看到pod的流量被断开,这时候即使服务出错,对外界来说也是感知不到的,这时候我们运维人员就可以进行故障排查了
# kubectl get pod
NAME READY STATUS RESTARTS AGE
liveness 0/1 Running 0 61s
下面对 Liveness 检测和 Readiness 检测做个比较:
Liveness 检测和 Readiness 检测是两种 Health Check 机制,如果不特意配置,Kubernetes 将对两种检测采取相同的默认行为,即通过判断容器启动进程的返回值是否为零来判断检测是否成功。
两种检测的配置方法完全一样,支持的配置参数也一样。不同之处在于检测失败后的行为:Liveness 检测是重启容器;Readiness 检测则是将容器设置为不可用,不接收 Service 转发的请求。
Liveness 检测和 Readiness 检测是独立执行的,二者之间没有依赖,所以可以单独使用,也可以同时使用。用 Liveness 检测判断容器是否需要重启以实现自愈;用 Readiness 检测判断容器是否已经准备好对外提供服务。