探针设计与中断预算
目标
能够创建三类探针,明确指定检查方式(httpGet/tcpSocket/exec)及时间字段,并能够设计 Deployment 的就绪状态、终止行为和 PodDisruptionBudget。
为什么重要
没有配置探针的 Deployment 等于禁用了滚动更新的所有安全保障。即使设置 maxUnavailable: 0,容器一启动便会被视为 Ready,流量会进入仍在初始化的 Pod。反过来,如果探针过于激进,正常 Pod 会不断重启,反而制造故障。因此,关键不只是“是否配置了探针”,而是“是否经过计算后配置了合理数值”。
混淆 liveness 和 readiness 会放大事故。当依赖服务(DB)短暂故障时,如果用 liveness 检查它,所有 Pod 会同时反复重启,即使 DB 恢复,整体恢复也会变慢。外部依赖应使用 readiness 检查——只需暂停接收流量,没有理由重启。
startup 探针可以化解两者之间的矛盾。如果给 liveness 设置 initialDelaySeconds: 300,运行期间的故障检测也会延迟 5 分钟;但若用 startup 单独提供 300 秒启动预算,则启动完成后仍可保持高频 liveness 检查。
步骤
- 创建命名空间
ckad-obs和 Podweb-live。镜像nginx:1.27;livenessProbe使用httpGet,path/healthz、port80、initialDelaySeconds: 5、periodSeconds: 10。 - 创建 Pod
db-ready。镜像nginx:1.27;readinessProbe使用tcpSocket,port5432、initialDelaySeconds: 10、periodSeconds: 5、failureThreshold: 3。 - 创建 Pod
file-check。镜像busybox:1.36,command: ["/bin/sh","-c","sleep 3600"];livenessProbe使用exec,command: ["cat","/tmp/healthy"]、periodSeconds: 5、failureThreshold: 2。 - 创建 Pod
legacy-app。镜像nginx:1.27。startupProbe使用httpGet,path/startup、port8080、failureThreshold: 30、periodSeconds: 10(= 300 秒预算)。在同一容器上再添加livenessProbe,同样使用httpGet,path/healthz、port8080、periodSeconds: 10。 - 创建 Pod
budget-app。镜像nginx:1.27;readinessProbe使用httpGet,path/ready、port80、initialDelaySeconds: 15。自行确定periodSeconds和failureThreshold,使其在首次失败后的 20 秒内从 Endpoint 中移除。条件为periodSeconds × failureThreshold ≤ 20、failureThreshold ≥ 3、periodSeconds ≥ 2。 - 创建 Deployment
api。副本数 3,标签app=api,镜像nginx:1.27。为容器添加readinessProbe(httpGet/ready:8080)和livenessProbe(httpGet/healthz:8080),并指定terminationMessagePolicy: FallbackToLogsOnError。 - 创建 PodDisruptionBudget
api-pdb。minAvailable: 2,selector为app=api。 - 为 Deployment
api添加startupProbe——httpGetpath/startup、port8080、failureThreshold: 12、periodSeconds: 5。再将 Pod 规范的terminationGracePeriodSeconds设为60。保留原有 readiness/liveness 探针和 3 个副本。
参考
- 使用
kubectl explain pod.spec.containers.livenessProbe/.startupProbe查看字段名称。 - 使用
kubectl create deployment api --image=nginx:1.27 --replicas=3 -n ckad-obs --dry-run=client -o yaml > api.yaml生成骨架,再手动填写探针会更快。 - **在此环境中,
kubectl logs和kubectl exec无法使用。**这些命令会在本模块的测验中讲解。 - 常见错误 1:把探针写在 Pod 层级(
spec.livenessProbe)。它是容器层级字段。 - 常见错误 2:在 PDB 的
selector中填写 Deployment 名称。这里必须使用 Pod 标签。 - 常见错误 3:把
terminationGracePeriodSeconds写在容器下。它位于 Pod 规范层级。
HTTP liveness 探针
创建命名空间 ckad-obs 和 Pod web-live。镜像 nginx:1.27;livenessProbe 使用 httpGet,path /healthz、port 80、initialDelaySeconds: 5、periodSeconds: 10。
在 livenessProbe.httpGet 中设置 path 和 port。探针位于容器下,不在 Pod 层级。响应码为 200~399 时视为成功。
TCP readiness 探针
创建 Pod db-ready。镜像 nginx:1.27;readinessProbe 使用 tcpSocket,port 5432、initialDelaySeconds: 10、periodSeconds: 5、failureThreshold: 3。
tcpSocket 只需指定端口——连接成功即视为检查成功。readiness 失败不会触发重启,只会将 Pod 从 Endpoint 中移除。
exec 探针
创建 Pod file-check。镜像 busybox:1.36,command: ["/bin/sh","-c","sleep 3600"];livenessProbe 使用 exec,command: ["cat","/tmp/healthy"]、periodSeconds: 5、failureThreshold: 2。
exec.command 是字符串数组,不经过 Shell。退出代码为 0 即成功。只检查文件是否存在时,无需特意调用 Shell。
使用 startup 探针覆盖缓慢启动
创建 Pod legacy-app。镜像 nginx:1.27。startupProbe 使用 httpGet,path /startup、port 8080、failureThreshold: 30、periodSeconds: 10(= 300 秒预算)。在同一容器上再添加 livenessProbe,同样使用 httpGet,path /healthz、port 8080、periodSeconds: 10。
startup 探针成功前,liveness/readiness 根本不会启动。启动预算按 periodSeconds × failureThreshold 计算。此 Pod 还必须同时配置 liveness。
计算检测延迟后确定数值
创建 Pod budget-app。镜像 nginx:1.27;readinessProbe 使用 httpGet,path /ready、port 80、initialDelaySeconds: 15。自行确定 periodSeconds 和 failureThreshold,使其在首次失败后的 20 秒内从 Endpoint 中移除。条件为 periodSeconds × failureThreshold ≤ 20、failureThreshold ≥ 3、periodSeconds ≥ 2。
从首次失败到采取措施的时间约为 periodSeconds × failureThreshold。既要满足要求的上限,也要让 failureThreshold 足够大,避免因短暂故障而波动。答案不止一个。
为 Deployment 添加探针和终止消息策略
创建 Deployment api。副本数 3,标签 app=api,镜像 nginx:1.27。为容器添加 readinessProbe(httpGet /ready:8080)和 livenessProbe(httpGet /healthz:8080),并指定 terminationMessagePolicy: FallbackToLogsOnError。
Deployment 的探针位于 spec.template.spec.containers[] 下。终止消息策略也是同一容器层级字段,且只有两个可用值,请用 kubectl explain 确认。
使用 PodDisruptionBudget 限制自愿中断
创建 PodDisruptionBudget api-pdb。minAvailable: 2,selector 为 app=api。
PDB 使用 policy/v1,且 minAvailable 与 maxUnavailable 只能选择一个。selector 必须指向Pod 标签,而不是 Deployment。
综合:同时配置启动预算与终止预算
为 Deployment api 添加 startupProbe——httpGet path /startup、port 8080、failureThreshold: 12、periodSeconds: 5。再将 Pod 规范的 terminationGracePeriodSeconds 设为 60。保留原有 readiness/liveness 探针和 3 个副本。
在之前创建的 Deployment 上添加 startup 探针,并延长终止宽限期。terminationGracePeriodSeconds 位于 Pod 规范(spec.template.spec)层级,而非容器层级。保留现有 liveness/readiness。