Docker 健康检查:它能发现故障,但不会替你恢复服务
本文参考《Docker 健康检查的目的、影响和处理》的选题,并根据当前 Docker 官方文档重写。其中一个关键修正是:普通 Docker Engine 将容器标记为 unhealthy 后,不会自动把它移出网络,也不会因此触发 restart policy。 容器的主进程还活着,不代表服务还能工作。线程死锁、连接池耗尽、事件循环卡死,都可能让 PID 1 继续运行,却无法处理请求。 Docker HEALTHCHECK 正是为这种差异准备的:它给正常运行状态之外再加一个 starting、healthy 或 unhealthy 的健康状态。不过它首先是检测和信号机制,不是完整的故障恢复系统。 running、healthy 和 restarted 是三件事 需要先把三个机制分开: 机制 判断什么 默认会做什么 容器状态 PID 1 是否仍在运行 进程退出后容器停止 健康检查 自定义命令是否连续成功 更新 health status,发出 health_status event restart policy 容器是否停止或异常退出 按策略重新启动已停止的容器 restart: always 或 restart: unless-stopped 关注的是“容器停止”,不是“健康状态变为 unhealthy”。如果进程卡死但没有退出,restart policy 不会被触发。 同样,Docker Engine 的普通网络不会因为某个容器 unhealthy 就自动修改 DNS 解析或隔离流量。是否摘除实例、重建任务,要看上层编排器或负载均衡器是否消费这个健康信号。 一个好的健康检查应该检查什么 健康命令应回答一个窄问题:这个容器此刻是否具备继续承担其核心职责的最低条件? 推荐特征: 检查本机回环地址,不绕公网域名和外部负载均衡; 快速、确定、资源消耗小; 有严格 timeout; 允许启动预热期; 连续失败多次才转为 unhealthy,避免单次抖动; 输出简短但可诊断,不包含密钥和个人信息。 不要把所有下游依赖都塞进一个探针。数据库短暂抖动时,如果几十个应用容器同时变 unhealthy 并被重启,可能把局部故障放大成重启风暴。应用应区分:自身已经不可恢复,还是某个下游暂时不可用但可以退避重试。 ...