今天要了解的是k8s的health check(健康检查)的功能。

一、默认的健康检查

Kubernetes默认的健康检查机制: 每个容器启动时都会执行一个进程, 此进程由Dockerfile的CMD或ENTRYPOINT指定。 如果进程退出时返回码非零, 则认为容器发生故障, Kubernetes就会根据restartPolicy重启容器。

先写出测试的yml文件:
在这里插入图片描述
可以看到pod的状态,已经重启了好几次
在这里插入图片描述
在上面的例子中, 容器进程返回值非零, Kubernetes则认为容器发生故障, 需要重启。 有不少情况是发生了故障, 但进程并不会退出。 比如访问Web服务器时显示500内部错误, 可能是系统超载, 也可能是资源死锁, 此时httpd进程并没有异常退出, 在这种情况下重启容器可能是最直接、 最有效的解决方案, 那我们如何利用HealthCheck机制来处理这类场景呢?

二、liveness探测(检查容器是否正常运行)

先写出测试的yml文件,
在这里插入图片描述
在这里插入图片描述
这里是要求容器执行的命令,创建/tmp/healthy,30秒后删除
在这里插入图片描述
这里是定义如何执行liveness探测
(1)exec:(执行成功就认为没问题)
要求进行exec里面的操作,如果成功执行(即返回值为0)则表示探测成功,如果非0则表示探测失败。这里的操作是通过cat命令来检查/tmp/healthy文件是否存在。
(2)initialDelaySeconds:
指定容器启动后多少秒后开始执行liveness探测。这里得根据容器启动的时间来设置,即不能少于容器启动的时间。
(3)periodSeconds:
指定每个多少秒执行一次liveness探测,k8s如果连续执行3次liveness探测均失败,就会杀掉原容器,并重启容器
通过命令,kubectl describe pod liveness来查询events的情况,如下图
在这里插入图片描述
可以看到在探测失败后,会杀死原来的容器并重新下载。

三、readiness探测(检查是否可以放进去service中)

书上写的关于liveness与readiness的区别:
用户通过Liveness探测可以告诉Kubernetes什么时候通过重启容器实现自愈; Readiness探测则是告诉Kubernetes什么时候可以将容器加入到Service负载均衡池中, 对外提供服务
修改刚才刚才的liveness.yml文件,
在这里插入图片描述
执行后查看情况,
在这里插入图片描述
连续3次readiness探测失败后,ready被设置为不可用。
总结:

  1. Liveness探测和Readiness探测是两种Health Check机制, 如果不特意配置, Kubernetes将对两种探测采取相同的默认行为, 即通过判断容器启动进程的返回值是否为零来判断探测是否成功
  2. 两种探测的配置方法完全一样, 支持的配置参数也一样。不同之处在于探测失败后的行为: Liveness探测是重启容器;Readiness探测则是将容器设置为不可用, 不接收Service转发的请求。
  3. Liveness探测和Readiness探测是独立执行的, 二者之间没有依赖, 所以可以单独使用, 也可以同时使用。 用Liveness探测判断容器是否需要重启以实现自愈; 用Readiness探测判断容器是否已经准备好对外提供服务(如果没准备好也不会重启容器)。

四、health check在scale up中的应用

在这里插入图片描述
点关注readinessProbe部分。 这里我们使用了不同于exec的另一种探测方法httpGet。 Kubernetes对于该方法探测成功的判断条件是http请求的返回代码在200~400之间。
在这里可以看到,一开始是启动了的,然后在探测3次失败后,容器又会从负载均衡中移除,知道下次探测成功重新加入。
在这里插入图片描述

五、health check在滚动更新中的应用(非常重要)

如果没有使用readinessProbe,新的副本即使有问题,但如果没有异常退出,rolling update后(有问题但正常的)新副本将会替换掉所有的副本,最终导致所有副本都正常运行,但应用down掉。所以需要readinessProbe来探测服务是否成功运行,如果没有通过探测,现有副本不会被全部替换,业务仍然可以正常进行。

先模拟一个10副本的应用,
在这里插入图片描述
可以看到,在没被检测成功时,哪怕status是running,仍然没有ready
在这里插入图片描述
隔了好久,所有pod都检查成功后,才是ready(即添加到service中)
在这里插入图片描述
接下来进行滚动更新,配置文件
在这里插入图片描述
由于新副本不存在/tmp/healthy,所以是无法通过readiness检测
我们来看看效果:
在这里插入图片描述
最后五个显然是新的副本,倒数5,4,3个副本,即时状态是running,依然不是ready,因为不能通过readinessProbe
对于命令

kubectl get deployment app

ready:指已经添加进service的pod
up-to-date:指当前已经完成更新的副本数,即5个新副本
available:指当前处于ready状态的副本数,即8个副本(这里都是旧副本)
在我们的设定中,新副本始终都无法通过readinessProbe,所以这种状态会一直持续下去。

对于滚动更新,可以通过maxSruge和maxUnavailable来控制副本替换的数量
书上写到:

  1. maxSurge
    此参数控制滚动更新过程中副本总数超过DESIRED的上限。maxSurge可以是具体的整数(比如3),也可以是百分百,向上取整。 maxSurge默认值为25%。在上面的例子中,DESIRED为10,那么副本总数的最大值为roundUp(10 + 10 * 25%) =13,所以我们看到CURRENT就是13。
  2. maxUnavailable
    此参数控制滚动更新过程中,不可用的副本相占DESIRED的最大比例。maxUnavailable可以是具体的整数(比如3),也可以是百分百,向下取整。maxUnavailable默认值为25%。在上面的例子中,DESIRED为10,那么可用的副本数至少要为10-roundDown(10 * 25%)= 8,所以我们看到AVAILABLE是8。maxSurge值越大,初始创建的新副本数量就越多;maxUnavailable值越大,初始销毁的旧副本数量就越多。
    数量变化的过程可以在这里看到
    在这里插入图片描述
    如果滚动更新失败,可以通过命令进行回滚
kubectl rollout undo deployment app --to-revision=1

执行效果如下:
在这里插入图片描述
可以看到k8s马上终止了所有新的副本,并开始创建新的副本。隔一段时间后,旧副本被重新创建,回到之前的版本
在这里插入图片描述
从时间可以明显的看到有两个副本是新的

Logo

K8S/Kubernetes社区为您提供最前沿的新闻资讯和知识内容

更多推荐