讲解
容器的主进程决定 Pod 的生死,restartPolicy 决定死后的处理方式:Always(默认,任何退出都重启,服务类用它)、OnFailure(仅异常退出重启,批处理用)、Never(不重启)。这里的「重启」是 kubelet 在同一节点上重启容器,Pod 的 IP 不变——和「重新调度一个新 Pod」是两回事。另外容器可以被 kill -9 式的意外杀死,也可以收到 SIGTERM 优雅退出:spec.terminationGracePeriodSeconds(默认 30 秒)是 SIGTERM 之后到 SIGKILL 之间的宽限期,应用应该监听 SIGTERM 完成收尾。
「进程活着」不等于「服务健康」——死锁的应用进程还在,但已经不能提供服务了。探针(probe)解决的就是这个问题,三种各管一件事。livenessProbe(存活探针)回答「容器还活着吗」:连续失败就重启容器,用来抓死锁类故障。readinessProbe(就绪探针)回答「能接流量吗」:失败期间 Pod 被从 Service 的端点列表摘除,流量不再打过来,恢复后自动加回——应用启动慢、依赖未就绪时用它防止「半开」状态接客。startupProbe(启动探针)是前两者的「启动宽限」:启动探针成功之前,存活/就绪探针不生效,专治老式应用启动慢被 liveness 误杀。
每种探针有三种检测方式:httpGet(对某端口某路径发 HTTP 请求,返回 200-399 算成功,最常用)、tcpSocket(能建立 TCP 连接就算活)、exec(在容器里执行命令,退出码 0 算成功)。关键参数:initialDelaySeconds(容器启动后多久开始探测)、periodSeconds(探测间隔)、failureThreshold(连续失败几次判定失败)、timeoutSeconds(单次探测超时)。配探针的原则:liveness 要保守(宁可晚重启,不可误杀),readiness 要积极(快速摘流),路径要选真正反映健康度的(比如检查依赖连接的 /healthz,而不是永远 200 的首页)。
示例
给 nginx Pod 配上 liveness 与 readiness 探针(HTTP 探测首页):
# wait: pod/ohmydocs-verify-probe
apiVersion: v1
kind: Pod
metadata:
name: ohmydocs-verify-probe
labels:
app: ohmydocs-verify-probe
spec:
containers:
- name: nginx
image: nginx:1.27-alpine
ports:
- containerPort: 80
readinessProbe:
httpGet:
path: /
port: 80
initialDelaySeconds: 2
periodSeconds: 5
livenessProbe:
httpGet:
path: /
port: 80
initialDelaySeconds: 5
periodSeconds: 10
failureThreshold: 3
确认探针配置已生效,并手动验证一次探针检测的端点确实可访问:
kubectl get pod ohmydocs-verify-probe -o jsonpath='readiness: {.spec.containers[0].readinessProbe.httpGet.path}:{.spec.containers[0].readinessProbe.httpGet.port}'
echo
kubectl exec ohmydocs-verify-probe -- wget -qO- http://127.0.0.1/ | head -2
restartPolicy 的行为对照:一个必然失败的容器,Never 策略下退出即终结(STATUS 变 Error,不会重启):
kubectl run ohmydocs-verify-once --image=busybox:1.36 --restart=Never --command -- sh -c 'echo 任务执行中; exit 1'
for i in 1 2 3 4 5 6; do
code=$(kubectl get pod ohmydocs-verify-once -o jsonpath='{.status.containerStatuses[0].state.terminated.exitCode}' 2>/dev/null || true)
[ -n "$code" ] && break
sleep 3
done
echo "退出码: $code"
kubectl get pod ohmydocs-verify-once --no-headers
kubectl logs ohmydocs-verify-once
kubectl delete pod ohmydocs-verify-once --wait
常见坑
- liveness 配得太敏感:initialDelaySeconds 太小、超时太短,应用启动慢就被反复重启——启动慢的应用用 startupProbe 兜底。
- readiness 和 liveness 用同一个深层检查:依赖的数据库抖动导致 liveness 失败 → 容器被重启 → 更不可用;深层依赖检查只放 readiness,liveness 只查「进程是否死透」。
- exec 探针里命令不存在:镜像里没有该命令(比如 alpine 里没有 curl)探测永远失败,用 wget 或换 httpGet/tcpSocket。
- 忽略优雅退出:应用不处理 SIGTERM,每次发布都要等满 30 秒再被强杀,请求被硬断——加上信号处理,必要时配 preStop 钩子。
小结
restartPolicy 管「死后怎么办」,探针管「健不健康」:liveness 失败重启容器、readiness 失败摘除流量、startup 给启动宽限;httpGet/tcpSocket/exec 三种手段,liveness 保守、readiness 积极。下一章开始告别裸 Pod,用 Deployment 管理副本。