文章目录
- 深入理解 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"})这样的问题 会出现 雪崩式重启
- 数据库短暂不可用(网络抖动、主从切换)
- 所有 Pod 的
livenessProbe失败 - Kubernetes重启所有容器
- 容器重启后又连不上 DB → 再次失败 → 再次重启
- 整个服务彻底不可用,即使 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 被重启。
三者协同工作流程
Pod 启动
Startup Probe 开始执行
(如有配置)
- 若失败,继续重试,直到超时
- 若成功,标记 Pod 已启动
Readiness Probe 开始执行
- 成功 → Pod 加入 Service Endpoints,开始接收流量
- 失败 → 从 Endpoints 移除,不接收新流量
Liveness Probe 开始执行
- 失败 → 重启容器
- 成功 → 继续运行
即使 Readiness 失败,只要 Liveness 成功,容器就不会重启—— 这是两者的核心区别。
注意 Readiness 探针 和 Liveness 探针 是同时启用的, 并且 两者各自的initialDelaySeconds都从这一刻开始计时,并且探针将持续进行 探测下去,根据 periodSeconds 时间 循环探测
探针类型支持
Kubernetes 支持以下三种探针执行方式:
| 类型 | 说明 |
|---|---|
exec | 在容器内执行命令,退出码为 0 表示成功 |
httpGet | 发起 HTTP GET 请求,状态码 2xx/3xx 表示成功 |
tcpSocket | 尝试建立 TCP 连接,成功建立即表示健康 |
grpc | 是(需实现 gRPC 健康协议),应用是基于 gRPC 构建的 |
最佳实践建议
- 为所有关键服务配置 Readiness Probe,避免流量打到未就绪实例。
- 谨慎使用 Liveness Probe,确保探针逻辑不会因临时故障导致不必要的重启。
- 慢启动应用务必配置 Startup Probe,防止被 Liveness 误杀。
- 合理设置
initialDelaySeconds、periodSeconds、failureThreshold等参数,平衡响应速度与稳定性。 - 健康检查端点应轻量、快速、无副作用。
探针配置核心原则
| 探针类型 | 目标 | 配置哲学 |
|---|---|---|
startupProbe | 等应用“完全启动” | 宽限时间要长,避免慢启动被误杀 |
readinessProbe | 判断能否接流量 | 灵敏但不敏感,依赖失败时快速摘流 |
livenessProbe | 判断是否该重启 | 保守!宁可晚重启,不要乱重启 |
⚠️ 永远不要让
livenessProbe比readinessProbe更敏感!
更敏感通常指:
- 更容易失败(比如超时更短、失败阈值更低、探测频率更高)
- 更快触发负面动作(如重启容器 或 摘除流量)
场景举例:
- 应用连接的 Redis 短暂超时(500ms 延迟)。
livenessProbe配置:timeoutSeconds: 1,failureThreshold: 2readinessProbe配置:timeoutSeconds: 3,failureThreshold: 3
结果:
livenessProbe先失败(2 次 1 秒超时)→Kubernetes 重启容器!- 而其实应用只是暂时不能服务,完全可以通过摘流恢复。
后果:
- 不必要的重启:应用本可自愈,却被强制重启,延长恢复时间。
- 雪崩风险:如果多个 Pod 因同样原因被同时重启,可能导致整个服务不可用。
- 状态丢失:有状态应用(如缓存、长连接)重启后数据丢失。
- 与 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