mirror of
https://github.com/yeasy/docker_practice.git
synced 2026-03-02 05:39:51 +00:00
4.5 KiB
4.5 KiB
HEALTHCHECK 健康检查
基本语法
HEALTHCHECK [选项] CMD <命令>
HEALTHCHECK NONE
HEALTHCHECK 指令告诉 Docker 如何判断容器状态是否正常。这是保障服务高可用的重要机制。
为什么需要 HEALTHCHECK
在没有 HEALTHCHECK 之前,Docker 只能通过进程退出码来判断容器状态。
问题场景:
- Web 服务死锁,无法响应请求,但进程仍在运行
- 数据库正在启动中,尚未准备好接受连接
- 应用陷入死循环,CPU 爆满但进程存活
引入 HEALTHCHECK 后: Docker 定期执行指定的检查命令,根据返回值判断容器是否"健康"。
容器状态转换:
Starting ──成功──> Healthy ──失败N次──> Unhealthy
▲ │
└──────成功──────┘
基本用法
Web 服务检查
FROM nginx
RUN apt-get update && apt-get install -y curl && rm -rf /var/lib/apt/lists/*
HEALTHCHECK --interval=30s --timeout=3s --retries=3 \
CMD curl -fs http://localhost/ || exit 1
命令返回值
0: 成功 (healthy)1: 失败 (unhealthy)2: 保留值 (不使用)
常用选项
| 选项 | 说明 | 默认值 |
|---|---|---|
--interval |
两次检查的间隔 | 30s |
--timeout |
检查命令的超时时间 | 30s |
--start-period |
启动缓冲期(期间失败不计入次数) | 0s |
--retries |
连续失败多少次标记为 unhealthy | 3 |
屏蔽健康检查
如果基础镜像定义了 HEALTHCHECK,但你不想使用它:
FROM my-base-image
HEALTHCHECK NONE
常见检查脚本
HTTP 服务
使用 curl 或 wget:
## 使用 curl
HEALTHCHECK CMD curl -f http://localhost/ || exit 1
## 使用 wget (Alpine 默认包含)
HEALTHCHECK CMD wget -q --spider http://localhost/ || exit 1
数据库
## MySQL
HEALTHCHECK CMD mysqladmin ping -h localhost || exit 1
## Redis
HEALTHCHECK CMD redis-cli ping || exit 1
自定义脚本
COPY healthcheck.sh /usr/local/bin/
HEALTHCHECK CMD ["healthcheck.sh"]
在 Compose 中使用
可以在 docker-compose.yml 中覆盖或定义健康检查:
services:
web:
image: nginx
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost"]
interval: 1m30s
timeout: 10s
retries: 3
start_period: 40s
带健康检查的依赖启动:
services:
web:
depends_on:
db:
condition: service_healthy # 等待 db 变健康才启动 web
db:
image: mysql
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
查看健康状态
## 查看容器状态(包含健康信息)
$ docker ps
CONTAINER ID STATUS
abc123 Up 1 minute (healthy)
def456 Up 2 minutes (unhealthy)
## 查看详细健康日志
$ docker inspect --format '{{json .State.Health}}' mycontainer | jq
{
"Status": "healthy",
"FailingStreak": 0,
"Log": [
{
"Start": "...",
"End": "...",
"ExitCode": 0,
"Output": "..."
}
]
}
最佳实践
1. 避免副作用
健康检查会被频繁执行,不要在检查脚本中进行写操作或消耗大量资源的操作。
2. 使用轻量级工具
优先使用镜像中已有的工具(如 wget),避免为了健康检查安装庞大的依赖(如 curl)。
3. 设置合理的 Start Period
应用启动可能需要时间(如 Java 应用)。设置 --start-period 可以防止在启动阶段因检查失败而误判。
## 给应用 1 分钟启动时间
HEALTHCHECK --start-period=60s CMD curl -f http://localhost/ || exit 1
4. 只检查核心依赖
健康检查应主要关注当前服务是否可用,而不是检查其下游依赖(数据库等)。下游依赖的检查应由应用逻辑处理。
本章小结
| 要点 | 说明 |
|---|---|
| 作用 | 检测容器应用是否真实可用 |
| 命令 | HEALTHCHECK [选项] CMD command |
| 状态 | starting, healthy, unhealthy |
| Compose | 支持 condition: service_healthy 依赖 |
| 注意 | 避免副作用,节省资源 |
延伸阅读
- CMD 容器启动命令:启动主进程
- Compose 模板文件:Compose 中的健康检查
- Docker 调试:容器排障