关于k8s的健康检查
强大的自愈能力是k8s这类容器编排引擎的一个重要特性。自愈的默认实现方式是自动重启发生故障的容器。除此之外,用户还可以利用liveness和readiness探测机制设置更精细的健康检查,进而实现以下需求:
- 零停机部署
- 避免部署无效的镜像
- 更加安全的滚动升级
默认的健康检查:
每个容器启动的时候都会执行一个进程,此进程由dockerfile的CMD或者是ENTRYPOINT指定。如果进程退出时返回码非零,则认为容器发生故障,k8s会根据restartPolicy重启容器。
但是有可能会出现发生了故障但是进程不退出的情况,比如访问web服务器时显示500内部错误,可能是系统超载,可能是资源死锁,此时httpd进程并没有异常退出,对于这种我们可以通过liveness探测来处理这类场景。
liveness
liveness探测让用户自定义判断容器是否健康的条件,如果探测失败k8s就会重启容器。
启动进程首先创建/tmp/healthy,30秒以后删除,在这里设定中,如果/tmp/healthy存在,则容器处于正常状态,否则为故障。
liveness部分:
1、探测的方式是:通过cat命令去检查/tmp/healthy文件是否存在,如果命令执行成功,返回值则为零,k8s则认为这次探测成功,否则就是失败。
2、initialDelaySeconds:10,指定容器启动10秒后开始执行liveness探测,这里的话一般会根据容器的准备时间来设置,如果业务容量启动需要30秒那么则应该大于30秒。
3、periodSeconds:5,每5秒执行一次探测,k8s如果连续执行3次探测失败,则会杀掉进程并且重启。
readiness
用户通过liveness探测什么时候通过重启实现自愈,readiness探测则是告诉k8s什么时候可以将容器加入到service负载均衡池里面,对外提供服务。
15秒以后(initialDelaySecond+periodSeconds),第一次进行探测,此时成功,设置为READY。
30秒以后,/tmp/healthy被删除,连续3次readiness探测失败,设置为不可用
对比
1、readiness和liveness探测是两种health check,如果不特意配置,k8s将对两种探测采取相同的默认行为,即通过判断容器启动进程的返回值是否为0来判断探测是否成功。
2、两种判断的配置方法完全一样,支持的配置参数也一样,不同在于失败后的行为:liveness探测是重启容器;readiness则是将容器设置为不可用,不接受service转发的请求。
3、liveness探测和readiness探测都是独立执行的,两个之前没有依赖,用liveness探测判断容器是否需要重启以实现自愈;用readiness判断是否准备好对外提供服务。
关于一些配置参数:
1 | • exec:通过执行命令来检查服务是否正常,针对复杂检测或无HTTP接口的服务,命令返回值为0则表示容器健康。 |
在scale中的应用
对于多副本的应用,当执行scale up操作的时候,新副本会作为backend被添加到service的负载均衡中,与已有的副本一起处理客户的请求。考虑到应用启动需要一个准备的过程,此时我们可以通过readiness来判断是否准备好,避免将请求发送到还没有准备好的backend上。比如:
这里使用了httpGet方法,该方法探测成功的判断条件是http请求的返回代码在200-400之间。
其中:
- schema:指定协议,http(默认)和HTTPS
- path:指定访问路径
- port:指定端口
- host:要连接的主机名,默认为Pod IP,可以在http request head中设置host头部。
- httpHeaders:自定义HTTP请求headers,HTTP允许重复headers。
上面配置的作用是:
1、容器启动10秒后开始检测
2、如果http://[container_ip]:8080/healthy返回代码不是200~400,表示容器没有就绪,不接收service web-svc的请求。
3、每个5秒检测一次
4、直到返回代码为200~400,表明容器已经就绪,然后将其加入到web-svc的负载均衡中,开始
处理客户请求。
5、探测会继续以5秒的时间间隔执行,如果连续发生3次失败,容器又会从负载均衡中移除,直到下次探测成功又重新加入。