Pod 健康检查三种探针区别

解读

在国内一线/二线互联网公司的 PHP 面试中,这个问题常被用来区分“只会写业务代码”与“真正参与过 K8s 交付”的候选人。
PHP 服务多以 FPM 或 Swoole 容器化部署,K8s 通过探针决定流量是否接入、容器是否重启、是否下线。
三种探针看似只是“配置字段”,但用错一次就可能导致线上 502/大量重启/优雅下线失败,因此面试官希望听到:

  1. 三种探针的触发时机与执行频率
  2. 对 PHP 生命周期的影响(FPM 慢日志、Swoole 协程挂起、OPcache 重置)
  3. 实际排障案例(如 readiness 探针误把“连接数高”当失败,导致 Pod 被频繁摘掉)

知识点

  1. 探针类型

    • startupProbe:K8s 1.16+ 引入,只在新 Pod 启动后运行;成功后不再执行,失败按 failureThreshold 重试,直到成功或超时。
    • livenessProbe:Pod 生命周期内持续运行;失败即 kubelet 重启容器。
    • readinessProbe:Pod 生命周期内持续运行;失败即把 Pod 从 Service Endpoints 摘掉,不重启容器。
  2. 关键字段差异(面试必须能口述)

    • initialDelaySeconds:对 readiness/liveness 有效;startupProbe 不需要,因为它本身就是“延迟”语义。
    • periodSeconds:liveness/readiness 默认 10s;startupProbe 可配更长,避免慢启动 PHP 应用被误杀。
    • successThreshold:readiness 默认 1,liveness 只能是 1;startupProbe 可为 1。
    • failureThreshold:三种探针都有,但含义不同——startupProbe 的阈值决定“最长给多久”,liveness 的阈值决定“连续失败几次就重启”。
  3. PHP 场景注意点

    • FPM 模式:readiness 建议探 php-fpm-ping 或 Nginx status 接口,避免直接 include 框架入口,防止 OPcache 频繁编译。
    • Swoole 常驻内存:liveness 探 HTTP 200 即可,但 readiness 需额外检查连接池、队列积压,否则流量进来后依旧 502。
    • 优雅下线:preStop 先睡 3s,让 readiness 失败 → Endpoint 摘掉 → 再睡 5s,保证 SLB/K8s 两层都同步完毕,最后才退出 FPM Master。

答案

“Pod 健康检查的三种探针分别是 startupProbe、livenessProbe、readinessProbe,它们的核心区别体现在执行阶段、结果动作以及对 PHP 容器的实际影响。

  1. startupProbe 只在容器启动阶段运行,用来保护慢启动的 PHP 应用(如 Composer 优化、大量缓存预热)。成功一次后永久退出,防止 liveness/readiness 过早介入导致无限重启。
  2. livenessProbe 伴随整个生命周期,连续失败达到阈值后 kubelet 会重启容器,适用于检测死锁、内存泄漏等“非死不可”的场景;对 PHP-FPM 来说,如果子进程全部卡住,ping 接口无响应,就会触发重启。
  3. readinessProbe 也伴随整个生命周期,但失败只会把 Pod 从 Service 中摘流,不会重启;适合判断 PHP 是否已连接数据库、Redis,是否处于“可服务”状态。
    配置时要特别注意 initialDelaySeconds、periodSeconds、failureThreshold 的语义差异:startupProbe 的 failureThresholdperiodSeconds 就是最长等待时间;livenessProbe 的 failureThreshold 决定连续失败次数;readinessProbe 的 successThreshold 可大于 1,用于防止抖动。
    在 PHP 容器化实践中,我通常给 startupProbe 30s
    20 次,保证框架启动、缓存预热完成;readinessProbe 探 /health?type=ready,检测 MySQL、Redis、队列连接;livenessProbe 只探 /health?type=live,返回 200 即认为进程活着,避免过度重启。”

拓展思考

  1. 如果 PHP 应用需要 2 分钟才能预热完 500 个路由缓存,三种探针如何组合才能既不被 kill,又不提前接流?
  2. 当 Swoole 的 TaskWorker 全部阻塞,HTTP 接口仍返回 200,此时 livenessProbe 应如何设计才能发现“业务假死”?
  3. 国内云厂商的 SLB 与 K8s Service 同步存在 3~5s 延迟,如何借助 readinessProbe+preStop 实现“零损”发布,确保用户在滚动更新期间不撞 502?