给 Docker 容器加上 HEALTHCHECK:让编排层知道服务真的活着

举报
yd_257918670 发表于 2026/10/23 06:40:08 2026/10/23
【摘要】 给 Docker 容器加上 HEALTHCHECK:让编排层知道服务真的活着很多人写 Dockerfile 时只关心「进程起没起来」,却忽略了「进程起来了,业务是否健康」。容器里的主进程还在跑,但 HTTP 端口已经卡死、依赖的数据库连不上,对编排系统和负载均衡来说,这样的容器仍被当成可用节点,流量照样打进来。Docker 的 HEALTHCHECK 指令就是为了解决这个问题:让 Dock...

给 Docker 容器加上 HEALTHCHECK:让编排层知道服务真的活着

很多人写 Dockerfile 时只关心「进程起没起来」,却忽略了「进程起来了,业务是否健康」。容器里的主进程还在跑,但 HTTP 端口已经卡死、依赖的数据库连不上,对编排系统和负载均衡来说,这样的容器仍被当成可用节点,流量照样打进来。Docker 的 HEALTHCHECK 指令就是为了解决这个问题:让 Docker 定期在容器内执行一条检查命令,把结果标成 healthy / unhealthy,编排层再据此决定是否摘流或重启。

一、HEALTHCHECK 写在哪

最常见的写法是在 Dockerfile 里:

FROM nginx:1.27-alpine

COPY nginx.conf /etc/nginx/nginx.conf
COPY html/ /usr/share/nginx/html/

HEALTHCHECK --interval=30s --timeout=3s --start-period=10s --retries=3 \
  CMD wget -qO- http://127.0.0.1/ || exit 1

几个参数的含义:

  • --interval:两次检查的间隔,默认 30 秒。
  • --timeout:单次检查允许跑多久,超时就算失败。
  • --start-period:容器刚启动时的宽限期,这段时间失败不计入重试次数,适合启动较慢的应用。
  • --retries:连续失败多少次后才标记为 unhealthy,默认 3 次。

也可以在 docker run 时覆盖:

docker run -d --name web \
  --health-cmd='curl -fsS http://127.0.0.1:8080/ready || exit 1' \
  --health-interval=20s \
  --health-retries=3 \
  my-app:latest

二、检查命令怎么选

原则很简单:检查命令要能代表业务是否可服务,而不是只探测进程是否存在。

  • Web / API:请求一个轻量的健康端点,例如 /healthz 或 /ready,要求返回 2xx。
  • 带依赖的服务:就绪探针可以顺手 ping 一下数据库或消息队列;存活探针则只看本进程,避免依赖抖动把整个容器打成 unhealthy。
  • 没有 HTTP 的进程:用 pgrep、检查 Unix socket 是否存在,或跑一条业务侧提供的 cli status。

反例:

# 不好:只要进程在,就算健康
HEALTHCHECK CMD pgrep myapp || exit 1

正例:

HEALTHCHECK --interval=15s --timeout=2s --retries=3 \
  CMD curl -fsS http://127.0.0.1:8080/ready || exit 1

应用侧最好单独暴露 /ready,内部检查线程池、连接池、关键配置是否加载完成,不要把完整业务接口拿来当探针,避免探针本身打爆服务。

三、怎么看状态

docker ps
# STATUS 列会显示 (healthy) 或 (unhealthy)

docker inspect --format='{{json .State.Health}}' web | jq .

Log 数组里能看到最近几次检查的退出码和输出,排查「为什么刚起来就被标 unhealthy」时很有用。常见原因是 start-period 太短,或检查命令依赖了容器外的域名而容器 DNS 还没就绪——这时把探测目标改成 127.0.0.1 往往就能稳住。

四、和编排、发布的关系

  • Docker Compose:healthcheck 字段与 Dockerfile 同义;配合 depends_on: condition: service_healthy,可以让依赖方等上游真正就绪再启动。
  • Swarm / Kubernetes:Docker 的 HEALTHCHECK 会被 Swarm 消费;到了 Kubernetes 更推荐用它自己的 livenessProbe / readinessProbe,语义更清晰,也别两套探针互相打架。
  • 滚动发布:健康检查通过后再把流量切过去,能明显降低「半启动就接请求」造成的 5xx。

五、小结

给关键服务加一条靠谱的 HEALTHCHECK,成本很低,但能让 Docker、Compose、负载均衡都「看见」真实可用性。记住三点:探测业务而不是进程;给足 start-period;把探针打到 127.0.0.1 上的专用健康端点。下一次写 Dockerfile 时,把 HEALTHCHECK 当成和 EXPOSE 同级的标配即可。

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

评论(0)

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

全部回复

上滑加载中

设置昵称

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

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

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