三种探针都叫“健康检查”,失败后的后果却完全不同:摘流量、杀容器、还是什么都不做?这篇每种都让它真的失败一次,量出多久起效、Service 的端点和容器的重启次数各发生了什么变化,并验证 startupProbe 怎么保护慢启动的程序。
Pod rd 就绪:Ready=True;EndpointSlice 里端点的 ready 条件=true
删掉 /tmp/ok 后 4.0 秒 Pod 变成 NotReady(periodSeconds=2,failureThreshold=2);容器 restartCount=0(没有重启);EndpointSlice 里端点 ready=false
事件:[('Unhealthy', 3, "Readiness probe failed: cat: can't open '/tmp/ok': No such file or directory")]
恢复 /tmp/ok 后 1.6 秒 Pod 重新 Ready,EndpointSlice 里端点 ready=true探针命令 cat /tmp/ok,periodSeconds: 2、failureThreshold: 2。删掉文件 4.0 秒后 Pod 变成 NotReady,EndpointSlice 里这个端点的 ready 从 true 变成 false(Service 不再把流量发给它),容器 restartCount 仍是 0。恢复文件 1.6 秒后重新 Ready。readiness 失败是可恢复的状态,不会动容器。
删掉 /tmp/ok 后 7.9 秒容器被重启(periodSeconds=2,failureThreshold=3 → 约 3 次失败 ≈ 6 秒);restartCount=1;容器 ID 23e6f439387b… → 8c09339d789e…(是新容器);lastState.terminated.reason=Error exitCode=137
事件:[('Unhealthy', 3, "Liveness probe failed: cat: can't open '/tmp/ok': No such file or directory"), ('Killing', 1, 'Container c failed liveness probe, will be restarted')]
重启后的新容器里 /tmp/ok 又被命令重新创建,probe 通过:Ready=True同样的探针放在 livenessProbe、failureThreshold: 3:连续失败 3 次(约 6 秒加调度误差,实测 7.9 秒)之后,kubelet 打出 Killing: Container c failed liveness probe, will be restarted,容器以 exitCode=137(128+9,被 SIGKILL)退出并重启,restartCount=1,容器 ID 换了。重启发生在同一个 Pod 里。
+ 0.0s containerStatuses[0]:started=False ready=False restartCount=0
+22.7s containerStatuses[0]:started=True ready=True restartCount=0
容器启动后 20 秒才创建 /tmp/started(startupProbe 通过);liveness 的 failureThreshold 只有 1,如果它在启动阶段就执行,这个容器早被杀了:最终 restartCount=0
对照 —— 没有 startupProbe、只有同样的 liveness 的容器:
26 秒后 restartCount=3;lastState=Error(liveness 一启动就开始检查,/tmp/ok 还不存在,被反复杀)程序要 20 秒才创建 /tmp/ok。只配 failureThreshold: 1 的 liveness,26 秒内被杀了 3 次;加上 startupProbe(每 2 秒一次,最多失败 15 次 = 30 秒预算)之后,started 一直是 false,到 +22.7 秒才变成 true、ready=true,期间 liveness 和 readiness 都没有执行,restartCount=0。慢启动的程序应该用 startupProbe 而不是把 liveness 的 initialDelaySeconds 设得很大。
httpGet(/healthz 返回 200)+ tcpSocket(8080 端口能连上):Ready=True restartCount=0
删掉 /www/healthz(接口变 404,端口还通):3.0 秒后 Ready=False;restartCount=0(tcpSocket 仍通过);最后一个 Unhealthy 事件:[('Unhealthy', 4, 'Readiness probe failed: HTTP probe failed with statuscode: 404')]
exec 命令要 3 秒才结束而 timeoutSeconds=1:Ready=False;事件:[('Unhealthy', 7, 'Readiness probe failed: command timed out: "sh -c sleep 3; cat /tmp/ok" timed out after 1s')]httpGet:状态码 200~399 算成功,接口变成 404 就是失败(HTTP probe failed with statuscode: 404),而同一容器的 tcpSocket 只看端口能不能连上,仍然通过,所以 readiness 是 False、liveness 没动静。exec 命令的耗时超过 timeoutSeconds 也算失败(command timed out … timed out after 1s)。