给容器加一道“健康检查”:Docker HEALTHCHECK 从入门到避坑

举报
yiboyun 发表于 2026/10/31 07:24:58 2026/10/31
【摘要】 很多服务“进程还在,服务已死”:端口监听着,但数据库连接池耗尽、死锁、依赖的接口一直超时,容器却始终显示 Up,负载均衡还继续往它身上送流量。Docker 的 HEALTHCHECK 就是为这种“假活”准备的:让容器自己定期证明它真的能干活,而不是仅仅还活着。最简单的写法是在 Dockerfile 里加一行:HEALTHCHECK --interval=30s --timeout=5s --...

很多服务“进程还在,服务已死”:端口监听着,但数据库连接池耗尽、死锁、依赖的接口一直超时,容器却始终显示 Up,负载均衡还继续往它身上送流量。Docker 的 HEALTHCHECK 就是为这种“假活”准备的:让容器自己定期证明它真的能干活,而不是仅仅还活着。

最简单的写法是在 Dockerfile 里加一行:

HEALTHCHECK --interval=30s --timeout=5s --start-period=20s --retries=3 \
  CMD curl -fsS http://127.0.0.1:8080/health || exit 1

四个参数各有分工。interval 是检查间隔,太短会给业务添负担,太长则发现故障太慢,30 秒是个稳妥的起点。timeout 是单次检查的超时,接口本身慢就别把超时设得比接口还苛刻,否则健康检查先把自己“查死”。start-period 是启动宽限期,应用刚启动、缓存还没预热时不计失败,避免容器一起步就被判死刑。retries 是连续失败几次才算不健康,单次抖动不应直接触发重启或摘流。

健康检查的命令要选“真正代表业务可用”的探针。只检查进程存在没有意义,pgrep 返回成功时服务可能早已不能响应;只检查端口监听也不够,端口在监听、请求却全部 500 同样算假活。正确的做法是调一个轻量的业务探针:HTTP 服务用 /health,数据库用一条只读查询,缓存用一次 PING。探针要轻、要幂等、不要产生副作用——在健康检查里写数据、发短信、调外部付费接口,都是在给自己埋雷。

状态变化后要让它产生实际效果。docker ps 里 healthy/unhealthy 只是结果,真正起作用的是编排层:Docker Compose 的 depends_on: condition: service_healthy 可以让依赖服务等数据库真正就绪再启动,避免“先启动、先报错、先重启”的死循环;Swarm 和 Kubernetes 则用健康状态决定是否继续送流量、不健康的副本会被摘掉而不是继续接单。只加 HEALTHCHECK 却不接编排策略,等于装了烟雾报警器却不接消防水带。

有几个坑值得提前知道。第一,健康检查跑在容器内部,curl、wget 这类工具不一定在精简镜像里,Alpine 镜像默认没有 curl,要么装上,要么改用自带工具写探针。第二,检查命令失败会留下日志和退出码,调试时用 docker inspect 看 Health 段的 Log,比猜要快。第三,不要在健康检查里依赖外部服务:检查本服务时顺带检查第三方接口,一旦第三方抖动,自己的容器会跟着被判不健康,故障面反而扩大了。第四,健康检查不是万能的,内存泄漏、慢查询这类渐进式恶化,单靠“这次请求通没通”很难提前发现,需要配合指标和日志一起看。

一句话总结:进程存活不等于服务可用。给容器加一个轻量、真实、不依赖外部的健康检查,再让编排层根据健康状态做启动顺序和流量决策,这道检查才算真正落地。明天可以顺手检查一下自己跑着的容器:有 HEALTHCHECK 的有几个,探针查的是端口还是业务,答案往往比想象中更值得改。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。