flask应用应暴露独立轻量端点如/healthz供k8s探针调用:仅返回200状态码,不查db、不触发业务逻辑、绕过鉴权与日志;生产必须使用gunicorn或uvicorn等多worker服务器,并合理配置initialdelayseconds、timeoutseconds等参数以匹配实际响应延迟。

Flask 应用如何暴露 /healthz 端点供 K8s liveness/readiness 探针调用
K8s 的 livenessProbe 和 readinessProbe 默认依赖 HTTP 状态码,不是靠返回内容判断。所以 Flask 必须提供一个轻量、无副作用、快速响应的端点,且稳定返回 200 —— 不能连数据库、不查缓存、不触发业务逻辑。
常见错误是把 /health 写成带 DB 查询的“全链路健康检查”,结果探针超时失败,K8s 反复重启 Pod。
- 用
@app.route('/healthz')(推荐用z后缀,避免和业务路径冲突) - 函数体内只做内存级检查:例如
return 'OK', 200 - 不要加
@login_required或其他中间件拦截;确保该路由绕过所有鉴权和日志埋点(避免锁或 IO) - 如果必须检查关键依赖(如 Redis 连通性),用
socket.create_connection(..., timeout=1)替代真实客户端调用,且超时严格设为 ≤1s
为什么 Flask 默认不支持异步 healthz,以及怎么避免阻塞主线程
Flask 0.12–2.3 默认使用单线程同步 WSGI server(如 Werkzeug dev server),/healthz 被慢请求阻塞时,探针会卡住 —— 这在高并发或 debug 模式下极易复现。
生产中你不会用 app.run(),但很多人忘了替换 WSGI server。K8s 探针失败往往不是代码问题,而是部署方式没对齐。
- 必须用支持多 worker 的 WSGI server:推荐
gunicorn(配--workers 4 --worker-class sync)或uvicorn(配--workers 4) - 禁止在生产环境用
debug=True或use_reloader=True,它们会启用文件监听线程,干扰探针稳定性 - 如果用了
gevent或eventlet,确认/healthz路由未被 monkey patch 影响(某些版本 patch socket 后导致短连接异常)
K8s YAML 中 probe 配置的关键参数与 Flask 实际响应的匹配关系
YAML 里写的 initialDelaySeconds、timeoutSeconds 不是拍脑袋定的,得看 Flask 端点真实耗时。用 curl -w '@-'\n' %{http_code} %{time_total}' http://localhost:5000/healthz 实测。
典型失配:YAML 设 timeoutSeconds: 1,但 Flask 因日志模块阻塞实际响应 1.2s,K8s 就判定失败。
-
periodSeconds建议 ≥3s:太密(如 1s)会压垮小规格 Pod,尤其当应用刚启动时 -
timeoutSeconds必须 > Flask 端点 P95 响应时间,建议实测后 +0.5s 安全余量 -
failureThreshold别设成 1:网络抖动很常见,设 3 更合理;否则一次瞬时超时就重启 - 务必指定
httpHeaders(如[{"name": "User-Agent", "value": "kube-probe"}]),方便在 Flask 日志里过滤探针流量,避免和业务日志混在一起
如何验证 probe 是否真正生效,而不是“配置写了却没走通”
最常被忽略的一点:K8s 并不校验你的 path 是否真实存在,它只按配置发请求并看状态码。即使你写错成 /healhz,只要服务没崩,probe 就永远失败 —— 但你可能只看 Pod 状态是 Running,误以为正常。
验证必须分三层:本地、容器内、K8s 节点侧。
- 进容器执行:
curl -v http://localhost:5000/healthz,确认返回 200 且无重定向 - 在 K8s 节点上用
curl -v http://<pod-ip>:5000/healthz</pod-ip>(需先kubectl get pod -o wide查 IP),排除 Service 或 NetworkPolicy 拦截 - 删掉 probe 配置,观察
kubectl describe pod是否出现Liveness probe failed类事件;再加回来,看事件消失 —— 这才是闭环验证 - 临时把
/healthz改成返回 503,等 1–2 分钟,观察 Pod 是否被 K8s 重启(注意看RESTARTS列变化)
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











