Docker 容器如何配置健康检查脚本

作者:袖梨 2026-07-12
Docker健康检查通过HEALTHCHECK指令在镜像构建时定义或docker run时动态指定,以周期性执行命令并依据退出码(0=健康)更新状态;推荐在Dockerfile中固化配置,支持interval、timeout、start-period、retries等选项,并可使用curl、wget或自定义Shell脚本实现多维度检测。

Docker 容器的健康检查(Health Check)不是靠外部脚本“配置进去”,而是通过 HEALTHCHECK 指令在镜像构建时定义,或在 docker run 时用 --health-cmd 等参数动态指定。它本质是一个周期性执行的命令,Docker 根据该命令的退出码(0=健康,非0=不健康)来更新容器状态。

在 Dockerfile 中定义健康检查

这是最推荐的方式,让健康检查逻辑随镜像固化,便于复现和分发:

  • 使用 HEALTHCHECK 指令,格式为:
    HEALTHCHECK [OPTIONS] CMD command
  • 常用选项:
    --interval=30s:每30秒检查一次
    --timeout=3s:命令超时时间
    --start-period=40s:容器启动后等待40秒再开始检查(给应用冷启动留时间)
    --retries=3:连续3次失败才标记为 unhealthy
  • 示例(检查 Web 服务是否响应 HTTP 200):
    HEALTHCHECK --interval=60s --timeout=5s --start-period=30s --retries=3 <br>  CMD curl -f http://localhost:8080/health || exit 1
  • 注意:curl -f 会在 HTTP 状态码非 2xx 时自动返回非零退出码,适合直接用于健康检查;若用 wget 或自定义脚本,需确保成功时返回 exit 0,失败时返回非零值。

运行时通过 docker run 添加健康检查

适用于临时调试或不想重建镜像的场景:

  • 命令中加入健康检查参数:
    docker run -d <br>  --health-cmd="curl -f http://localhost:3000/readyz || exit 1" <br>  --health-interval=20s <br>  --health-timeout=3s <br>  --health-start-period=45s <br>  --health-retries=2 <br>  --name myapp nginx:alpine
  • 该方式不会影响镜像本身,只对当前容器生效。
  • 如果容器内没有 curl(如精简版 Alpine),可改用 sh -c 'wget --spider -q http://localhost:3000/readyz || exit 1',或提前把检查脚本 COPY 进镜像并赋予可执行权限。

编写自定义健康检查脚本(进阶用法)

当内置命令不够用(比如要查数据库连接、磁盘空间、多依赖服务连通性),可以写 Shell 脚本:

  • 将脚本放入镜像,例如 /health.sh
    #!/bin/sh<br>if ! nc -z localhost 5432; then<br>  echo "PostgreSQL not reachable"<br>  exit 1<br>fi<br>if ! curl -f http://localhost:8080/api/health > /dev/null 2>&1; then<br>  echo "API endpoint failed"<br>  exit 1<br>fi<br>exit 0
  • 构建时确保脚本可执行:
    RUN chmod +x /health.sh
    HEALTHCHECK CMD ["/health.sh"]
  • 注意:脚本中避免使用交互式命令(如 read)、长阻塞操作(应设超时),且路径、依赖工具(nccurl)必须存在于容器内。

验证和查看健康状态

健康检查配置后,可通过以下方式确认效果:

  • 查看容器实时状态:
    docker ps —— 健康状态会显示在 STATUS 列(如 healthyunhealthystarting
  • 查看详细健康信息:
    docker inspect myapp | jq '.[0].State.Health'(需安装 jq)或直接看原始 JSON 中 State.Health 字段
  • 手动触发一次检查(调试用):
    docker exec myapp curl -f http://localhost:8080/health(前提是应用暴露了该端点)——但这只是应用层检查,不是 Docker 的 HEALTHCHECK 执行结果
  • 日志里不会自动打印健康检查输出,如需调试,可在脚本中加 echo 并重定向到文件,或用 --log-level=debug 启动 dockerd(不推荐生产环境)。

相关文章

精彩推荐