mirror of
https://github.com/yeasy/docker_practice.git
synced 2026-03-10 11:54:37 +00:00
224 lines
4.6 KiB
Go
224 lines
4.6 KiB
Go
## HEALTHCHECK 健康检查
|
||
|
||
### 基本语法
|
||
|
||
具体内容如下:
|
||
|
||
```docker
|
||
HEALTHCHECK [选项] CMD <命令>
|
||
HEALTHCHECK NONE
|
||
```
|
||
|
||
`HEALTHCHECK` 指令告诉 Docker 如何判断容器状态是否正常。这是保障服务高可用的重要机制。
|
||
|
||
---
|
||
|
||
### 为什么需要 HEALTHCHECK
|
||
|
||
在没有 HEALTHCHECK 之前,Docker 只能通过**进程退出码**来判断容器状态。
|
||
|
||
**问题场景**:
|
||
- Web 服务死锁,无法响应请求,但进程仍在运行
|
||
- 数据库正在启动中,尚未准备好接受连接
|
||
- 应用陷入死循环,CPU 爆满但进程存活
|
||
|
||
**引入 HEALTHCHECK 后**:
|
||
Docker 定期执行指定的检查命令,根据返回值判断容器是否"健康"。
|
||
|
||
```
|
||
容器状态转换:
|
||
Starting ──成功──> Healthy ──失败N次──> Unhealthy
|
||
▲ │
|
||
└──────成功──────┘
|
||
```
|
||
|
||
---
|
||
|
||
### 基本用法
|
||
|
||
#### Web 服务检查
|
||
|
||
具体内容如下:
|
||
|
||
```docker
|
||
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,但你不想使用它:
|
||
|
||
```docker
|
||
FROM my-base-image
|
||
HEALTHCHECK NONE
|
||
```
|
||
|
||
---
|
||
|
||
### 常见检查脚本
|
||
|
||
#### HTTP 服务
|
||
|
||
使用 `curl` 或 `wget`:
|
||
|
||
```docker
|
||
## 使用 curl
|
||
|
||
HEALTHCHECK CMD curl -f http://localhost/ || exit 1
|
||
|
||
## 使用 wget(Alpine 默认包含)
|
||
|
||
HEALTHCHECK CMD wget -q --spider http://localhost/ || exit 1
|
||
```
|
||
|
||
#### 数据库
|
||
|
||
具体内容如下:
|
||
|
||
```docker
|
||
## MySQL
|
||
|
||
HEALTHCHECK CMD mysqladmin ping -h localhost || exit 1
|
||
|
||
## Redis
|
||
|
||
HEALTHCHECK CMD redis-cli ping || exit 1
|
||
```
|
||
|
||
#### 自定义脚本
|
||
|
||
具体内容如下:
|
||
|
||
```docker
|
||
COPY healthcheck.sh /usr/local/bin/
|
||
HEALTHCHECK CMD ["healthcheck.sh"]
|
||
```
|
||
|
||
---
|
||
|
||
### 在 Compose 中使用
|
||
|
||
可以在 `docker-compose.yml` 中覆盖或定义健康检查:
|
||
|
||
```yaml
|
||
services:
|
||
web:
|
||
image: nginx
|
||
healthcheck:
|
||
test: ["CMD", "curl", "-f", "http://localhost"]
|
||
interval: 1m30s
|
||
timeout: 10s
|
||
retries: 3
|
||
start_period: 40s
|
||
```
|
||
|
||
带健康检查的依赖启动:
|
||
|
||
```yaml
|
||
services:
|
||
web:
|
||
depends_on:
|
||
db:
|
||
condition: service_healthy # 等待 db 变健康才启动 web
|
||
db:
|
||
image: mysql
|
||
healthcheck:
|
||
test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
|
||
```
|
||
|
||
---
|
||
|
||
### 查看健康状态
|
||
|
||
运行以下命令:
|
||
|
||
```bash
|
||
## 查看容器状态(包含健康信息)
|
||
|
||
$ 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` 可以防止在启动阶段因检查失败而误判。
|
||
|
||
```docker
|
||
## 给应用 1 分钟启动时间
|
||
|
||
HEALTHCHECK --start-period=60s CMD curl -f http://localhost/ || exit 1
|
||
```
|
||
|
||
#### 4. 只检查核心依赖
|
||
|
||
健康检查应主要关注**当前服务**是否可用,而不是检查其下游依赖(数据库等)。下游依赖的检查应由应用逻辑处理。
|
||
|
||
---
|
||
|
||
### 本章小结
|
||
|
||
| 要点 | 说明 |
|
||
|------|------|
|
||
| **作用** | 检测容器应用是否真实可用 |
|
||
| **命令** | `HEALTHCHECK [选项] CMD command` |
|
||
| **状态** | starting, healthy, unhealthy |
|
||
| **Compose** | 支持 `condition: service_healthy` 依赖 |
|
||
| **注意** | 避免副作用,节省资源 |
|
||
|
||
### 延伸阅读
|
||
|
||
- [CMD 容器启动命令](cmd.md):启动主进程
|
||
- [Compose 模板文件](../../compose/9.5_compose_file.md):Compose 中的健康检查
|
||
- [Docker 调试](../../15_appendix/15.2_debug.md):容器排障
|