Docker镜像健康检查:上线前别跳过这一步

你刚写好一个 Python Web 服务,本地跑得飞起,打包成 ref="/tag/2019/" style="color:#8B0506;font-weight:bold;">Docker 镜像后推到测试环境,结果一启动就报错退出——连日志都来不及看,容器就死了。这时候别急着重写代码,先看看是不是忘了给镜像加健康检查

健康检查不是可选项,是上线标配

就像人每年体检查血压、血糖一样,Docker 镜像也需要定期‘量体温’。健康检查(HEALTHCHECK)指令能让容器自己回答一个问题:‘我还活着,而且干得动活儿吗?’它不是只看进程有没有挂,而是真正去验证服务是否可响应、数据库连得上、端口听得到。

三行代码,让镜像会自检

在 Dockerfile 里加这么几行:

HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
  CMD curl -f http://localhost:8000/health || exit 1

解释一下:每 30 秒发一次请求,超时 3 秒就判失败,启动后先等 5 秒再开始检查(留给应用初始化),连续 3 次失败才标记为 unhealthy。这个 /health 路由,你用 Flask 写两行就行:

@app.route('/health')
def health():
    return {'status': 'ok', 'db': check_db_connection()}

不加健康检查,K8s 和 Swarm 可能把你‘静音’

在 Kubernetes 里,没有健康检查的 Pod 很容易被误判为‘就绪但不健康’,流量进不去;在 Docker Swarm 中,unhealthy 容器会被自动下线重启。我们之前有个小项目,因为没加 HEALTHCHECK,负载均衡器一直把请求打到一个卡死但进程还在的容器上,用户刷半天白屏——加完检查后,15 秒内就切走了。

本地快速验证,不用等上线

构建完镜像后,直接运行并观察状态:

docker build -t myweb .
docker run -d -p 8000:8000 --name test-web myweb
docker ps --format "table {{.Names}}\t{{.Status}}"

你会看到状态里慢慢出现 (health: starting)(health: healthy)(health: unhealthy)。出问题时,docker inspect test-web | grep Health 一眼就能定位是网络不通还是接口返回了 500。