docker healthcheck 是容器自我监控机制,通过定期执行检查命令并依据返回码判断健康状态,支持在 dockerfile 中声明或运行时覆盖,可提升服务可靠性。

Docker Healthcheck 是容器自我监控的核心机制,它让容器能主动向 Docker 守护进程报告自身运行状态,而非仅依赖进程是否存活(PID 1 是否在运行)。正确配置 healthcheck 能显著提升服务可靠性,避免流量被路由到实际已卡死、无响应但进程未退出的容器上。
Healthcheck 的基本原理与触发方式
Docker 在容器启动后,会按指定间隔执行你定义的检查命令。该命令在容器内部运行,返回码决定健康状态:
- 0:健康(healthy)
- 1:不健康(unhealthy)
- 2:保留值,Docker 不使用(不应返回)
每次检查结果都会记录,连续失败达到一定次数(--health-start-period 和 --health-retries 控制)后,容器状态变为 unhealthy。Docker CLI、Swarm 或编排工具(如 Kubernetes 配合 docker-compose v2.23+)可据此做自动剔除或重启决策。
在 Dockerfile 中声明 Healthcheck
推荐在镜像构建阶段就内建健康检查逻辑,确保所有基于该镜像的容器默认具备可观测性:
HEALTHCHECK --interval=30s --timeout=3s --start-period=40s --retries=3 \ CMD curl -f http://localhost:8080/health || exit 1
说明关键参数:
- --interval=30s:每 30 秒执行一次检查
- --timeout=3s:单次检查超时为 3 秒,超时即视为失败
- --start-period=40s:容器启动后前 40 秒为启动宽限期,期间失败不计入重试计数(避免应用尚未就绪就被判为 unhealthy)
- --retries=3:连续 3 次失败才标记为 unhealthy
注意:CMD 后的命令在容器内执行,需确保依赖工具存在(如用 curl 就得在镜像中安装 curl;也可改用 sh -c 'echo ok' || exit 1 做简单探活)。
运行时覆盖或添加 Healthcheck
若镜像未内置 healthcheck,或需临时调整策略,可在 docker run 时指定:
docker run -d \ --health-cmd="pg_isready -U postgres -d mydb" \ --health-interval=20s \ --health-timeout=5s \ --health-start-period=60s \ --health-retries=2 \ --name mypostgres postgres:15
此例对 PostgreSQL 容器使用 pg_isready 检查数据库连接就绪状态,比单纯检测端口更准确。同样适用于 Redis(redis-cli ping)、MySQL(mysqladmin ping)等有原生健康探测命令的服务。
验证与排查健康状态
通过以下命令实时观察容器健康状况:
-
docker ps:输出中STATUS列显示healthy、unhealthy或starting -
docker inspect <container> | jq '.[0].State.Health'</container>:查看详细健康历史(含最近几次检查时间、结果、输出) -
docker logs <container></container>:若 healthcheck 命令产生输出(如curl -v),且未重定向,可能出现在容器日志中(但不推荐依赖日志查健康)
常见问题:
- 容器显示
unhealthy但手动进容器执行相同命令却成功 → 检查--start-period是否过短,或网络/权限限制(healthcheck 运行在容器非特权上下文中) - healthcheck 命令报
command not found→ 确保镜像中已安装对应工具,或改用sh -c包装并检查 PATH - 想检查外部依赖(如下游 API)→ 可行,但要谨慎:这会让容器健康状态受外部系统影响,可能造成级联误判
不复杂但容易忽略。










