必须同时配置 spring boot actuator 的 /actuator/health 端点暴露、应用监听 0.0.0.0:8080、docker healthcheck 使用 curl -f http://127.0.0.1:8080/actuator/health,并确保 kubernetes 中 liveness 与 readiness 探针语义分离且参数合理。

直接结论:不能只靠 Docker 的 HEALTHCHECK,必须让 Spring Boot Actuator 暴露 /actuator/health 端点,且 Java 进程要监听 0.0.0.0:8080(不是 localhost:8080),否则容器内 curl 会失败。
Spring Boot 必须暴露 health 端点
默认情况下,/actuator/health 不对外可见。不加配置时,Docker 的 HEALTHCHECK 命令访问会返回 404 或连接拒绝。
- 在
pom.xml中确认已引入spring-boot-starter-actuator -
application.yml中至少配置:management: endpoints: web: exposure: include: health - 如果用
application.properties,写成:management.endpoints.web.exposure.include=health - 注意:不要写
include: "*"上生产,仅调试时可用
Docker HEALTHCHECK 命令必须能访问到应用
常见错误是 Java 应用只绑定了 localhost:8080,而 HEALTHCHECK 在容器内执行 curl localhost:8080/actuator/health 看似合理,实则可能失败——因为某些 Spring Boot 版本或 JVM 参数下,localhost 解析行为不稳定;更稳妥的是确保应用监听 0.0.0.0:8080。
- 启动参数中显式指定:
java -jar app.jar --server.address=0.0.0.0 - 或在
application.yml中配:server.address: 0.0.0.0 -
HEALTHCHECK建议用curl -f http://127.0.0.1:8080/actuator/health(比localhost更可靠) - 避免用
|| exit 1写法以外的逻辑,Docker 只认退出码 0 = 健康,非 0 = 不健康
liveness 和 readiness 探针在 Kubernetes 中不能混用同一端点
虽然都调 /actuator/health,但语义和参数必须区分。共用一个端点却配相同参数,会导致滚动更新卡住或误杀 Pod。
-
livenessProbe:关注“是否还活着”,失败即重启。建议initialDelaySeconds设为应用冷启动耗时 + 5s(如 20s),periodSeconds≥ 10s,failureThreshold设为 3 -
readinessProbe:关注“能否接流量”,失败即摘流。建议initialDelaySeconds更短(如 5s),periodSeconds可设为 5s,failureThreshold设为 1 - Actuator 的
health默认只检查自身状态;若需数据库等依赖也参与就绪判断,得配置management.health.db.show-details=when_authorized并启用对应 HealthIndicator
Alpine 镜像里 curl 可能不存在
用 openjdk:17-jdk-alpine 类镜像时,HEALTHCHECK CMD curl ... 会报 /bin/sh: curl: not found。
- 要么换非 Alpine 镜像(如
openjdk:17-jdk-slim) - 要么在 Dockerfile 中手动安装:
RUN apk add --no-cache curl - 或者改用
nc(netcat)做 TCP 层探测:HEALTHCHECK CMD nc -z 127.0.0.1 8080,但该方式无法感知应用层是否 ready(比如 DB 连不上但端口通)
最易被忽略的一点:健康检查路径、端口、监听地址、Actuator 配置、Docker 网络模式这五者必须对齐。任一环节错位,HEALTHCHECK 就只是个摆设——它不会报错,只会永远显示 unhealthy 或 starting。











