关于 K8S 探针(startupProbe、livenessProbe、readinessProbe)的最佳实践

1 什么是就绪检测、存活检测、启动检测?

我们在 k8s 中使用【readiness】探针是用来判定容器是否准备就绪,是否可以接受流量。当 Pod 内所以容器均就绪,则 Pod 将被认为已 ready,如果没有,那么将从 service 的 Loader Blance 中剔除该 Pod。

而 k8s 中使用【liveness】探针是用于判定是否需要重启容器,通常情况下主要用于检查容器是否无响应,死锁等,从而通过重启来提高应用的可用性。

至于k8s 1.6中增加的【starup】探针是用于判定应用程序容器什么时候启动了,而启用这个探针主要目的是希望容器在启动成功后再进行存活性和就绪检查,确保这些存活、就绪探测器不会影响应用程序的启动。这可以用于对慢启动容器进行存活性检测,避免它们在启动运行之前就被杀掉。

用最简单的话概括liveness和startup的区别就是,startup是从0到1的检测过程,探测成功后再交由liveness接管,而liveness是从1到0的检测过程。

2 注意事项及最佳实践

在实际的使用中,很多就绪检测和存活检测配置一模一样,这是不合理的。

比较推荐的做法是:如果存活检测和就绪检测使用相同的健康检测方法,那么需要将 failureThreshold 设置的更大一些,比如就绪检测设置为3次失败就设置为未就绪,而存活设置为10次后才让存活检测失败。

原因是:当服务运行出现问题或者直接hang住,我们需要预留一定的缓冲空间,让就绪检测更灵敏一点,以在服务重启之前,先从K8S Service提供的负载均衡上将其流量摘掉,从Endpoint列表中去除。否则负载均衡将会把部分请求继续分发到已经发生重启的Pod实例上面。

还有一个地方需要特别注意,使用存活检测探针时,如果设置不当会引起应用可用性降低甚至是引发雪崩。即存活检测探针不能引入外部的故障注入,就绪检测探针是可以的,因为其并不会重启Pod实例。这个是我们在实践过程中遇到的比较严重的问题。比如在做存活检测的时候,如果数据库连接不上,rabbitmq无法连接,甚至于邮箱密码错误或者网络不稳定,那么可能导致存活检测不通过,而Pod被强制重启,从而导致业务中断,这肯定不是我们想要的情况,所以就需要避免这个外部依赖,避免引起雪崩。

所以最佳的实践需要区分就绪检测和存活检测的接口,存活检测探针可以仅检测程序运行与否,而和业务上重度耦合的一些健康检查可以留到就绪检测里去实现。

你可能感兴趣的:(k8s,运维,容器,kubernetes,云原生)