docker容器健康检查通过healthcheck指令实现,支持--interval、--timeout、--start-period、--retries等参数,cmd返回0为healthy、1为unhealthy;常用curl检测http、nc检测tcp或自定义脚本,需轻量、快速、真实反映服务状态,并注意启动期等待与readiness/liveness区分。
dockerfile 中配置健康检查(healthcheck)能让容器编排系统(如 docker swarm、kubernetes)准确判断容器是否真正就绪并持续可用,而不仅依赖进程是否存活。关键在于:探针逻辑要轻量、快速、语义明确,且与应用实际状态一致。
用 HEALTHCHECK 指令定义探针
Dockerfile 中通过 HEALTHCHECK 指令声明容器健康检测方式,它不会影响镜像构建,只在容器运行时生效。基本语法如下:
HEALTHCHECK [OPTIONS] CMD command
常用选项包括:
- --interval=30s:默认每30秒执行一次检查(可缩短至10s,避免编排系统过早判定失败)
- --timeout=3s:单次检查超时时间,必须小于 interval
- --start-period=40s:容器启动后宽限期,期间失败不计入连续失败次数(适合冷启动慢的应用)
- --retries=3:连续失败3次才标记为 unhealthy
例如,一个 Node.js Web 服务可这样写:
HEALTHCHECK --interval=15s --timeout=5s --start-period=60s --retries=3 \
CMD curl -f http://localhost:3000/health || exit 1
探针命令必须真实反映业务可用性
别只检查端口通不通或进程在不在。应验证核心依赖和业务逻辑是否就绪,比如:
- 数据库连接是否正常(
mysqladmin ping -h db -u user -ppass --silent &> /dev/null) - API 路由是否返回 200 且含预期字段(
curl -s http://localhost:8080/readyz | jq -e '.status == "ok"' > /dev/null) - 关键缓存服务是否响应(
redis-cli -h redis ping &> /dev/null)
避免使用耗时操作(如大文件读取、复杂计算),否则会拖慢探测频率或导致误判。
配合编排工具的关键适配点
Docker Swarm 和 Kubernetes 对健康检查的使用方式不同,需注意兼容性:
- Docker Swarm 直接读取 Dockerfile 中的 HEALTHCHECK,自动用于服务更新、任务调度和故障恢复
-
Kubernetes 不读取 Dockerfile 的 HEALTHCHECK,需在 Pod spec 中单独配置
livenessProbe和readinessProbe;但建议保持两者逻辑一致,便于统一维护 - 若同时面向两种环境,可在 Dockerfile 中保留通用探针,并在 k8s YAML 中复用相同命令或脚本路径(如
cmd: ["/health.sh"])
调试与验证技巧
健康检查配置后务必验证效果:
- 运行容器后执行
docker inspect <container> | grep -A 10 Health</container>查看当前健康状态和历史 - 手动触发探针:
docker exec <container> curl -f http://localhost:3000/health</container>,确认返回值和耗时 - 模拟故障:临时停掉依赖服务,观察容器状态是否在 retries 次后变为
unhealthy,再恢复后是否自动恢复 - 日志中留意
health check failed或health check passed记录(需开启容器日志级别)











