深入理解 Kubernetes 中的探针
2026/9/8 21:05:12 网站建设 项目流程

文章目录

    • 深入理解 Kubernetes 中的探针
      • 为什么需要探针?
      • 1. Liveness Probe(存活探针)
        • 作用
        • 使用场景
        • 存活探针里面需要写什么?
      • 2. Readiness Probe(就绪探针)
        • 作用
        • 使用场景
        • 示例配置
      • 3. Startup Probe(启动探针)
        • 作用
        • 使用场景
        • 示例配置
      • 三者协同工作流程
      • 探针类型支持
      • 最佳实践建议
      • 探针配置核心原则
      • 探针配置实战
        • 对于Django的应用
        • FastAPI 应用
        • deployment配置文件
    • 总结
    • 官方文档

深入理解 Kubernetes 中的探针

在 Kubernetes 中,容器化应用的健康状态对整个系统的稳定性至关重要。为了确保应用始终处于可用、响应和就绪的状态,Kubernetes 提供了三种类型的探针(Probes)Liveness Probe(存活探针)Readiness Probe(就绪探针)Startup Probe(启动探针)。这些探针帮助 Kubernetes 自动判断容器是否健康、是否准备好接收流量,以及是否已经成功启动。


为什么需要探针?

在传统的单机部署中,我们通常通过进程是否存在来判断服务是否运行。但在分布式系统和微服务架构中,一个进程可能仍在运行,但其内部逻辑已经“卡死”或无法正常处理请求(例如数据库连接断开、死锁、无限循环等)。此时,仅靠进程状态无法准确反映服务的真实健康状况。

Kubernetes 的探针机制允许你自定义健康检查逻辑,让平台能够:

  • 自动重启“假死”的容器(Liveness)
  • 避免将流量转发给尚未准备好的 Pod(Readiness)
  • 给慢启动应用足够的时间完成初始化(Startup)

这大大提升了系统的自愈能力服务可靠性

探针的作用 可以 根据情况 来完成 自动重启 以及 流量转发到 ready的pod 上面。


1. Liveness Probe(存活探针)

作用

Liveness Probe 用于判断容器是否“还活着”。如果探针失败,Kubernetes 会认为该容器已进入不可恢复的错误状态,自动重启该容器

存活探针 探测失败 则会重启容器

使用场景
  • 应用出现死锁、内存泄漏导致无响应
  • 内部状态异常但进程未退出
  • 需要自动恢复机制而无需人工干预

spec.containers[0].livenessProbe

livenessProbe:failureThreshold:2# 连续失败 2 次才认为不健康(触发重启)httpGet:path:/health/port:8090# 容器启动端口scheme:HTTPinitialDelaySeconds:30# 容器启动后,等待 30 秒才开始第一次探测periodSeconds:30# 之后每 30 秒探测一次successThreshold:1# 只要 1 次成功就认为健康(对 liveness 来说通常固定为 1)timeoutSeconds:1# 每次 HTTP 请求最多等 1 秒,超时算失败
存活探针里面需要写什么?

livenessProbe只回答一个问题:这个进程还活着吗?
不应该因为外部依赖(DB、Redis、API 等)失败而返回失败。

错误的做法 在存活探针中检查数据库连接, 检查外部API 等

# ❌ 错误做法defhealthz(request):db_ok=check_database()# ← 查数据库ifnotdb_ok:returnJsonResponse({"status":"dead"},status=500)returnJsonResponse({"status":"alive"})

这样的问题 会出现 雪崩式重启

  1. 数据库短暂不可用(网络抖动、主从切换)
  2. 所有 Pod 的livenessProbe失败
  3. Kubernetes重启所有容器
  4. 容器重启后又连不上 DB → 再次失败 → 再次重启
  5. 整个服务彻底不可用,即使 DB 已恢复!

⚠️ 注意:不要在 Liveness 探针中加入过于严格的依赖(如数据库连接),否则可能导致频繁重启(“重启风暴”)。


2. Readiness Probe(就绪探针)

作用

Readiness Probe 用于判断容器是否准备好接收流量。如果探针失败,Pod 会被从 Service 的 Endpoints 中移除,不再接收新请求,但容器不会被重启。

使用场景
  • 应用启动后需要加载大量缓存或配置
  • 依赖的外部服务(如数据库、API)暂时不可用
  • 执行耗时的初始化任务
示例配置
readinessProbe:failureThreshold:2httpGet:path:/ready/port:8090scheme:HTTPinitialDelaySeconds:5periodSeconds:10successThreshold:1timeoutSeconds:1

只有当 http://pod_id:8090 ,返回200,才认为 Pod 就绪。否则,即使容器在运行,也不会被加入到负载均衡中。

✅ 优势:实现优雅上线/下线,避免请求打到未准备好的实例上。


Ready 探针中一般要检查 所有重要依赖和状态,比如redis, mysql 是否可以正常连接,外部依赖是否连通

3. Startup Probe(启动探针)

作用

Startup Probe 是为启动缓慢的应用设计的。在 Startup Probe 成功之前,Liveness 和 Readiness 探针不会执行。一旦 Startup Probe 成功,其他两个探针才开始工作。

使用场景
  • Java 应用(如 Spring Boot)冷启动时间长
  • 机器学习模型加载耗时
  • 需要预热或初始化大量资源的服务
示例配置
startupProbe:failureThreshold:20httpGet:path:/startup/port:8090scheme:HTTPinitialDelaySeconds:5periodSeconds:5successThreshold:1timeoutSeconds:2

最多等待 5 × 20 + 5 = 105 秒(5 分钟)让应用启动。在此期间,Liveness/Readiness 不会干扰启动过程。

💡 这是 Kubernetes 1.18+ 引入的重要特性,解决了“慢启动应用被误杀”的经典问题。

最大启动容忍时间为:initialDelaySeconds + periodSeconds × failureThreshold

5 × 20 + 5 = 105

Kubernetes 会在前 105 秒内(含)最多尝试 20 次探测.

如果在这20次内有一次成功(successThreshold: 1),就认为启动成功,后续由 liveness/readiness 接管, 此后不再进行探测。

如果20次都失败,则在第 105 秒左右(具体略小于或等于 105 秒)判定启动失败,Pod 被重启。


三者协同工作流程

  1. Pod 启动

  2. Startup Probe 开始执行

    (如有配置)

    • 若失败,继续重试,直到超时
    • 若成功,标记 Pod 已启动
  3. Readiness Probe 开始执行

    • 成功 → Pod 加入 Service Endpoints,开始接收流量
    • 失败 → 从 Endpoints 移除,不接收新流量
  4. Liveness Probe 开始执行

    • 失败 → 重启容器
    • 成功 → 继续运行

即使 Readiness 失败,只要 Liveness 成功,容器就不会重启—— 这是两者的核心区别。

注意 Readiness 探针 和 Liveness 探针 是同时启用的, 并且 两者各自的initialDelaySeconds都从这一刻开始计时,并且探针将持续进行 探测下去,根据 periodSeconds 时间 循环探测

探针类型支持

Kubernetes 支持以下三种探针执行方式:

类型说明
exec在容器内执行命令,退出码为 0 表示成功
httpGet发起 HTTP GET 请求,状态码 2xx/3xx 表示成功
tcpSocket尝试建立 TCP 连接,成功建立即表示健康
grpc是(需实现 gRPC 健康协议),应用是基于 gRPC 构建的

最佳实践建议

  1. 为所有关键服务配置 Readiness Probe,避免流量打到未就绪实例。
  2. 谨慎使用 Liveness Probe,确保探针逻辑不会因临时故障导致不必要的重启。
  3. 慢启动应用务必配置 Startup Probe,防止被 Liveness 误杀。
  4. 合理设置initialDelaySecondsperiodSecondsfailureThreshold等参数,平衡响应速度与稳定性。
  5. 健康检查端点应轻量、快速、无副作用。

探针配置核心原则

探针类型目标配置哲学
startupProbe等应用“完全启动”宽限时间要长,避免慢启动被误杀
readinessProbe判断能否接流量灵敏但不敏感,依赖失败时快速摘流
livenessProbe判断是否该重启保守!宁可晚重启,不要乱重启

⚠️ 永远不要让livenessProbereadinessProbe更敏感!

更敏感通常指:

  • 更容易失败(比如超时更短、失败阈值更低、探测频率更高)
  • 更快触发负面动作(如重启容器 或 摘除流量)

场景举例:

  • 应用连接的 Redis 短暂超时(500ms 延迟)。
  • livenessProbe配置:timeoutSeconds: 1,failureThreshold: 2
  • readinessProbe配置:timeoutSeconds: 3,failureThreshold: 3

结果:

  • livenessProbe先失败(2 次 1 秒超时)→Kubernetes 重启容器!
  • 而其实应用只是暂时不能服务,完全可以通过摘流恢复。

后果:

  1. 不必要的重启:应用本可自愈,却被强制重启,延长恢复时间。
  2. 雪崩风险:如果多个 Pod 因同样原因被同时重启,可能导致整个服务不可用。
  3. 状态丢失:有状态应用(如缓存、长连接)重启后数据丢失。
  4. 与 readiness 设计初衷冲突:readiness 的存在就是为了“隔离问题而不重启”。

上面的设置就是不合理的。

比如下面的例子:

ready探针时间设置相对比较合理 , 超时时间短,检测周期也非常短,失败阀值也比 livessness 小, 这个 ready探针就是比liveness探针更加敏感。

因为ready 探针,Pod 会被从 Service 的 Endpoints 中移除,不会再让pod 接收流量, 此时容器可能并不需要重启。有可能因为网络波动引起的探测失败,说不定下一个周期又能自动恢复了。

# readiness:灵敏,快速摘流readinessProbe:httpGet:path:/readyport:8080initialDelaySeconds:10periodSeconds:5timeoutSeconds:2# 较短超时failureThreshold:2# 快速失败# liveness:保守,避免误杀livenessProbe:httpGet:path:/liveport:8080initialDelaySeconds:60periodSeconds:30timeoutSeconds:5# 更长超时failureThreshold:3# 容忍多次失败

探针配置实战

这里使用 http Get 请求来配置探针, 首先应用层 要提供三个http 的api 接口

我这里定义为 /startup/ /health/ , /ready/ 分别对应为启动探针, 存活探针,就绪探针

对于Django的应用

在 项目主目录 创建一个probes.py

fromdjango.httpimportJsonResponsefromdjango.dbimportconnectionfromdjango.views.decorators.csrfimportcsrf_exemptfromdjango.views.decorators.httpimportrequire_http_methodsimportlogging logger=logging.getLogger(__name__)@csrf_exempt@require_http_methods(["GET"])defhealthz(request):""" Liveness probe: 只检查进程是否活着,不查外部依赖。 """logger.info("Liveness check")returnJsonResponse({"status":"alive"},status=200)@csrf_exempt@require_http_methods(["GET"])defready(request):""" Readiness probe: 检查关键依赖(如数据库)。 """try:withconnection.cursor()ascursor:cursor.execute("SELECT 1")returnJsonResponse({"status":"ready"},status=200)exceptExceptionase:logger.error("Readiness check failed: %s",e)returnJsonResponse({"status":"not ready","error":str(e)},status=503)@csrf_exempt@require_http_methods(["GET"])defstartup(request):""" Startup probe: 可与 liveness 共用,或做更宽松检查。 这里我们让它和 liveness 一样,只确认进程运行。 """returnJsonResponse({"status":"starting"},status=200)

在urls.py 添加路由

fromdjango.urlsimportpathfrom.importprobes# 整个项目的总路由进行分发urlpatterns=[# probes relationpath('health/',probes.healthz),path('ready/',probes.ready),path('startup/',probes.startup),]
FastAPI 应用

probes.py

fromfastapiimportAPIRouter,HTTPException,statusfromfastapi.responsesimportJSONResponsefrombase.dbimportdb_managerfrombase.loggingimportlogger router=APIRouter()@router.get("/health/",status_code=status.HTTP_200_OK)asyncdefhealth():logger.info("health check")returnJSONResponse(content={"status":"alive"})@router.get("/ready/",status_code=status.HTTP_200_OK)asyncdefready():# 可以在这里添加数据库、缓存等依赖检查# 示例:简单返回 ready,后续可扩展logger.info("ready check")# 获取所有依赖的状态 mockstatus_info=db_manager.get_status()logger.info(f"status_info:{status_info}")# 定义必须连接的关键服务required_services=["elasticsearch","mongodb","redis","postgresql"]# 检查是否有任何关键服务断开forserviceinrequired_services:ifstatus_info.get(service,"")=="disconnected":logger.warning(f"service:{service}failed")raiseHTTPException(status_code=503,detail=f"Service{service}is disconnected")# 所有服务正常,返回 readyreturnJSONResponse(content={"status":"ready"},status_code=status.HTTP_200_OK)@router.get("/startup/",status_code=status.HTTP_200_OK)asyncdefstartup():logger.info("startup check")returnJSONResponse(content={"status":"starting"},status_code=status.HTTP_200_OK)

在入口文件 app.py

fromprobesimportrouterashealth_router app=FastAPI(lifespan=lifespan)# ...# 引入路由app.include_router(health_router)
deployment配置文件
apiVersion:apps/v1kind:Deploymentmetadata:annotations:k8s.kuboard.cn/displayName:算法-合同审查服务k8s.kuboard.cn/workload:contract-review-svclabels:k8s.kuboard.cn/layer:svck8s.kuboard.cn/name:contract-review-svcname:contract-review-svcnamespace:prodspec:minReadySeconds:10progressDeadlineSeconds:600replicas:3revisionHistoryLimit:10selector:matchLabels:k8s.kuboard.cn/layer:svck8s.kuboard.cn/name:contract-review-svcstrategy:rollingUpdate:maxSurge:25%maxUnavailable:25%type:RollingUpdatetemplate:metadata:labels:k8s.kuboard.cn/layer:svck8s.kuboard.cn/name:contract-review-svcpod-template-hash:7b847c7476spec:affinity:nodeAffinity:preferredDuringSchedulingIgnoredDuringExecution:-preference:matchExpressions:-key:envoperator:Invalues:-prod_highweight:80-preference:matchExpressions:-key:envoperator:Invalues:-prodweight:20containers:-command:-gunicorn-main:app--c-gunicorn.conf.pyenv:-name:TZvalue:Asia/Shanghaiimage:zhihe-acr-registry-vpc.cn-shanghai.cr.aliyuncs.com/xxxxxx/contract-review-service:xxxxxxx-xxxxximagePullPolicy:IfNotPresentlifecycle:preStop:exec:command:-sleep-"600"livenessProbe:failureThreshold:2httpGet:path:/health/port:8090scheme:HTTPinitialDelaySeconds:30periodSeconds:30successThreshold:1timeoutSeconds:1name:contract-reviewports:-containerPort:8090name:c-reviewprotocol:TCPreadinessProbe:failureThreshold:2httpGet:path:/ready/port:8090scheme:HTTPinitialDelaySeconds:5periodSeconds:10successThreshold:1timeoutSeconds:1resources:limits:cpu:"2"memory:3000Mirequests:cpu:1500mmemory:2000MistartupProbe:failureThreshold:20httpGet:path:/startup/port:8090scheme:HTTPinitialDelaySeconds:5periodSeconds:5successThreshold:1timeoutSeconds:2terminationMessagePath:/dev/termination-logterminationMessagePolicy:FilevolumeMounts:-mountPath:/usr/src/app/logsname:volume-3wnyy-mountPath:/usr/src/app/.envname:volume-35k4ereadOnly:truesubPath:.env-mountPath:/usr/src/app/gunicorn.conf.pyname:volume-3ydcpreadOnly:truesubPath:gunicorn.conf.py-mountPath:/usr/src/app/config/config.ininame:volume-35k4ereadOnly:truesubPath:config.inidnsPolicy:ClusterFirstimagePullSecrets:-name:acr-zhihe-secret-internalrestartPolicy:AlwaysschedulerName:default-schedulersecurityContext:{}terminationGracePeriodSeconds:660volumes:-hostPath:path:/tmp/logs/prod/contract-review-svctype:DirectoryOrCreatename:volume-3wnyy-configMap:defaultMode:420items:-key:.envpath:.env-key:config.inipath:config.ininame:contract-reviewname:volume-35k4e-configMap:defaultMode:420items:-key:gunicorn.conf.pypath:gunicorn.conf.pyname:contract-reviewname:volume-3ydcp

这样一个基本上完整的配置 就已经可以了,当然根据应用的不同 ,可以调节不同的参数。

总结

Kubernetes 的探针机制是实现自愈、弹性、高可用微服务架构的关键组件。通过合理配置 Liveness、Readiness 和 Startup 探针,你可以:

  • 自动恢复故障实例
  • 保障服务流量只打到健康节点
  • 容忍慢启动应用的初始化过程

掌握这三种探针的原理与使用方法,是每一位 Kubernetes 开发者和运维工程师的必备技能。

官方文档

liveness-probe

configure-liveness-readiness-startup-probes

分享快乐,留住感动. '2026-01-06 22:24:42' --frank

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询