模板一:网络服务万金油(只要有网络端口,通杀)
如果容器是 Web 服务(如 Nginx、Tomcat、Node.js)、数据库(如 Redis、MySQL)或者各种中间件,只要它暴露了 TCP 端口,且容器内带有最基础的 sh,这就是最无敌的万金油配置。
它利用了 Linux 内核原生 </dev/tcp 漏洞,完全不依赖 curl 或 wget 。
healthcheck:
# 语法解释:尝试与容器本地的 8080 端口建立 TCP 连接,失败则退出码为 1
test: ["CMD-SHELL", "sh -c '</dev/tcp/127.0.0.1/8080' || exit 1"]
interval: 10s # 10秒探一次,既保证敏锐度,又不会给系统带来TCP连接压力
timeout: 3s # 握手超过3秒没反应,说明网络栈或主线程已经卡死
retries: 3 # 连续失败3次(大约30秒内)正式宣判死刑
start_period: 30s # 30秒新手保护期,给服务腾出启动和绑定端口的时间
注:使用时只需要把 8080 改成你容器内部的实际端口(如 Redis 改成 6379,Nacos 改成 8848)即可。
模板二:Java/Spring Boot 专属万金油(解决高 CPU 与 Full GC 假死)
对于 Java 应用,有时候端口虽然勉强能连上,但实际上 JVM 内部因为内存溢出(OOM)或者恐怖的 CPU 占用,已经完全无法处理业务了。
这时候用 Java 自带的诊断工具 jcmd 去拍 JVM 的脑袋,是最精准的万金油手段(前提是使用 JDK 镜像,非精简的 JRE)。
healthcheck:
# 语法解释:让 jcmd 去问容器内 PID 为 1 的 Java 进程要一个性能计数器数据
# 如果 JVM 彻底卡死或正在发生毁灭性的长时间 Full GC,该命令会直接超时或报错
test: ["CMD-SHELL", "jcmd 1 PerfCounter.print || exit 1"]
interval: 15s # Java 应用体检可以稍微放缓一点频率
timeout: 5s # 给 JVM 5秒的响应时间
retries: 3
start_period: 60s # 【重点】Java 启动普遍较慢(如重型 Spring Cloud 框架),保护期至少给 60 秒起步
模板三:极度精简/无命令容器的“外部看门狗”万金油
如果容器是纯静态的、或者用 Go 写的极简镜像,里面既没有 sh 也没有任何命令,那就采用反客为主的万金油策略——把监控挂在宿主机上。
直接在宿主机的定时任务(Crontab)里挂这行万金油命令,一行搞定所有同类容器:
* * * * * docker ps --format "{{.Names}}" | xargs -I {} sh -c 'docker inspect --format "{{.State.Health.Status}}" {} | grep -q "unhealthy" && docker restart {}'
【这行命令在干嘛?】
它每分钟自动扫描你机器上所有正在运行的 Docker 容器。只要发现任何一个容器的健康状态变成了 "unhealthy",它就会自动出手执行 docker restart 帮它复活。
有了这行宿主机命令,你只需要在那些有条件的容器里写上 healthcheck,后续的“卡死自动重启”逻辑就再也不用每个容器单独配置看门狗了。
- 能测 业务层(HTTP API) 最好;
- 没有工具就退而求其次测 网络层(TCP 端口);
- 连网络都没有就测 系统进程(JVM/PID)。