## 7.12 HEALTHCHECK 健康检查 本节涵盖了相关内容与详细描述,主要探讨以下几个方面: ### 7.12.1 基本语法 如下代码块所示,展示了相关示例: ```docker HEALTHCHECK [选项] CMD <命令> HEALTHCHECK NONE ``` `HEALTHCHECK` 指令告诉 Docker 如何判断容器状态是否正常。这是保障服务高可用的重要机制。 --- ### 7.12.2 为什么需要 HEALTHCHECK 在没有 HEALTHCHECK 之前,Docker 只能通过 **进程退出码** 来判断容器状态。**问题场景**: - Web 服务死锁,无法响应请求,但进程仍在运行 - 数据库正在启动中,尚未准备好接受连接 - 应用陷入死循环,CPU 爆满但进程存活 **引入 HEALTHCHECK 后**: Docker 定期执行指定的检查命令,根据返回值判断容器是否 “健康”。 ```bash 容器状态转换: Starting ──成功──> Healthy ──失败N次──> Unhealthy ▲ │ └──────成功──────┘ ``` --- ### 7.12.3 基本用法 本节涵盖了相关内容与详细描述,主要探讨以下几个方面: #### 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 | --- ### 7.12.4 屏蔽健康检查 如果基础镜像定义了 HEALTHCHECK,但你不想使用它: ```docker FROM my-base-image HEALTHCHECK NONE ``` --- ### 7.12.5 常见检查脚本 本节涵盖了相关内容与详细描述,主要探讨以下几个方面: #### 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"] ``` --- ### 7.12.6 在 Compose 中使用 可以在 `compose.yaml` (或 `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"] ``` --- ### 7.12.7 查看健康状态 运行以下命令: ```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": "..." } ] } ``` --- ### 7.12.8 最佳实践 本节涵盖了相关内容与详细描述,主要探讨以下几个方面: #### 1. 避免副作用 健康检查会被频繁执行,不要在检查脚本中进行写操作或消耗大量资源的操作。 #### 2. 使用轻量级工具 优先使用镜像中已有的工具 (如 `wget`),避免为了健康检查安装庞大的依赖 (如 `curl`)。 #### 3. 设置合理的 Start Period 应用启动可能需要时间 (如 Java 应用)。设置 `--start-period` 可以防止在启动阶段因检查失败而误判。 ```docker ## 给应用 1 分钟启动时间 HEALTHCHECK --start-period=60s CMD curl -f http://localhost/ || exit 1 ``` #### 4. 只检查核心依赖 健康检查应主要关注 **当前服务** 是否可用,而不是检查其下游依赖 (数据库等)。下游依赖的检查应由应用逻辑处理。 ---