因为k8s中采用大量的异步机制、以及多种对象关系设计上的解耦,当应用实例数 增加/删除、或者应用版本发生变化触发滚动升级时,系统并不能保证应用相关的service、ingress配置总是及时能完成刷新。在一些情况下,往往只是新的Pod完成自身初始化,系统尚未完成EndPoint负载均衡器等外部可达的访问信息刷新,老得Pod就立即被删除,最终造成服务短暂的额不可用,这对于生产来说是不可接受的,所以k8s就加入了一些存活性探针:livenessProbereadinessProbe以及我们今天要介绍的startupProbe

    startupProbe是在k8s v1.16加入了alpha版,官方对其作用的解释是:
    Indicates whether the application within the Container is started. All other probes are disabled if a startup probe is provided, until it succeeds. If the startup probe fails, the kubelet kills the Container, and the Container is subjected to its restart policy. If a Container does not provide a startup probe, the default state is Success

    大概是意思是:判断容器内的应用程序是否已启动。如果提供了启动探测,则禁用所有其他探测,直到它成功为止。如果启动探测失败,kubelet将杀死容器,容器将服从其重启策略。如果容器没有提供启动探测,则默认状态为成功。

    注意:不要将startupProbe和readinessProbe混淆。

    那么在什么时候会用startupProbe呢?
    正常情况下,我们会在pod template中配置livenessProbe来探测应用程序是否正常运行,如果异常则会触发restartPolicy重启Pod(因为默认情况下restartPolicy设置的是always)。

    如下:

    1. livenessProbe:
    2. httpGet:
    3. path: /test
    4. prot: 80
    5. failureThreshold: 1
    6. initialDelay10
    7. periodSeconds: 10

    上面配置的意思是容器启动10s后每10s检查一次,允许失败的次数是1次。如果失败次数超过1则会触发restartPolicy。

    但是有时候会存在特殊情况,比如服务A启动时间很慢,需要60s。这个时候如果还是用上面的探针就会进入死循环,因为上面的探针10s后就开始探测,这时候我们服务并没有起来,发现探测失败就会触发restartPolicy。这时候有的朋友可能会想到把initialDelay调成60s不就可以了?但是我们并不能保证这个服务每次起来都是60s,假如新的版本起来要70s,甚至更多的时间,我们就不好控制了。有的朋友可能还会想到把失败次数增加,比如下面配置:

    1. livenessProbe:
    2. httpGet:
    3. path: /test
    4. prot: 80
    5. failureThreshold: 5
    6. initialDelay60
    7. periodSeconds: 10

    这在启动的时候是可以解决我们目前的问题,但是如果这个服务挂了呢?如果failureThreshold=1则10s后就会报警通知服务挂了,如果设置了failureThreshold=5,那么就需要5*10s=50s的时间,在现在大家追求快速发现、快速定位、快速响应的时代是不被允许的。

    在这时候我们把startupProbelivenessProbe结合起来使用就可以很大程度上解决我们的问题。

    如下:

    1. livenessProbe:
    2. httpGet:
    3. path: /test
    4. prot: 80
    5. failureThreshold: 1
    6. initialDelay10
    7. periodSeconds: 10
    8. startupProbe:
    9. httpGet:
    10. path: /test
    11. prot: 80
    12. failureThreshold: 10
    13. initialDelay10
    14. periodSeconds: 10

    上面的配置是只有startupProbe探测成功后再交给livenessProbe。我们startupProbe配置的是10*10s,也就是说只要应用在100s内启动都是OK的,而且应用挂掉了10s就会发现问题。

    有眼尖的朋友可能会说,这种还是不能确定具体时间,只能给出一个大概的范围。我个人认为对服务启动时间的影响因素太多了,有可能是应用本身,有可能是外部因素,比如主机性能等等。我们只有在最大程度上追求高效、稳定,但是我们不能保证100%稳定,像阿里这样的大企业对外宣称的也是5个9,6个9的稳定率,如果出问题了,不好意思你恰恰不在那几个9里面,所以我们自己要做好监控有效性,告警的及时性,响应的快速性,处理的高效性。