给 Docker 容器加上 HEALTHCHECK:让编排层知道服务真的活着
给 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 同级的标配即可。
- 点赞
- 收藏
- 关注作者
评论(0)