LabHub
学习 学习路径 课程

CKAD — Kubernetes 应用开发者

配置与实际动作之间

在 LabHub 中继续学习

一句话总结

Probe、Job、QoS、配置注入全部由 kubelet 执行。没有 kubelet,可以练习编写 YAML,却永远看不到它真正做了什么。

概念图: 这些行为一个都不会实际发生。 · 继续推迟 · 重新创建 · 从 endpoint 移除

为什么必须观察实际行为

CKAD 询问的是“应用如何在集群上生存”,probe、Job、QoS、配置注入讲的都是这个问题。

但前面模块使用的模拟集群没有 kubelet,所以**这些行为一个都不会实际发生。**probe 不执行,Job 不完成,ConfigMap 也不会 mount。

三种 probe 的关系

probe 问题 失败后
startupProbe 启动完成了吗 继续推迟另外两个
livenessProbe 还活着吗 重新创建容器
readinessProbe 能接收请求吗 从 endpoint 移除

startupProbe 成功前,另外两个根本不会启动。没有它,只剩两个选择。

Job 的两个值

completions 表示需要成功多少次parallelism 表示同时运行多少个。混淆两者,Job 会永远不结束或消耗不必要的资源。

backoffLimit 的重试间隔会指数增长,默认值 6 意味着需要数分钟才会放弃,其间失败 Pod 会持续堆积。

QoS 不是手动指定的

不能直接写 qosClass 字段。kubelet 根据 requestslimits 的组合赋值;节点内存不足时会先驱逐 BestEffort

配置注入何时生效

修改 ConfigMap 和 Secret 后,Pod 是否立即看到变化取决于注入方式。环境变量在容器启动时复制一次,后续变更绝不会反映,必须重建 Pod。卷挂载的文件则由 kubelet 周期性更新,稍后会变成新内容;但应用如果不重新读取文件,更新也毫无意义。

实务中常用两种办法:把配置内容 hash 放入 Pod template annotation,配置变化时 template 也改变,自动触发 rolling update;或者让应用检测文件变化并重读。前者简单得多,也容易回退,大多数情况下更好。

还要知道引用不存在对象时的差异。环境变量引用不存在的 ConfigMap 时,无法创建容器,显示 CreateContainerConfigError;卷引用时 mount 无法完成,Pod 会停在 ContainerCreating。同一个拼写错误症状不同,记住映射能大幅缩短调查时间。

Probe 值应该依据什么确定

比添加 probe 更难的是填什么值。照搬默认值导致服务杀死自己的事故并不少见,因此要理解每个值改变什么。

含义 设置错误后
periodSeconds 多久询问一次 太短增加应用负担,太长延迟发现故障
timeoutSeconds 等待响应多久 默认 1 秒,受载时会把正常应用判为失败
failureThreshold 连续失败多少次后动作 设为 1 时短暂延迟也会重启

最常引发事故的组合是 liveness timeout 太短。负载使响应变慢,probe 失败并重启容器,负载转移到剩余 Pod,使其也变慢,最终全部反复重启。用重启解决负载导致的延迟,只会自我恶化。因此原则是:liveness 宽松,readiness 敏感。暂时移出流量可以恢复,重启却无法撤销。

检查内容同样重要。liveness 只应检查进程是否处于无法自愈的状态,不能连依赖数据库是否可达也一起检查。数据库短暂波动时若所有应用 Pod 重启,connection 会同时重新涌入,情况更加糟糕。**依赖检查属于 readiness。**失败时只退出流量,数据库恢复后悄然返回。

为启动缓慢的应用使用 startupProbe 时,只需记住 failureThreshold × periodSeconds 就是允许启动时间。每 30 秒检查、最多 20 次,表示最多等待 10 分钟,超过后才开始重启。

实际工作中真正重要的内容

**启动缓慢的应用应使用 startupProbe。**没有它,只有放宽 liveness 让真实死亡长期不被发现,或收紧 liveness 在启动中杀死应用、使其永久重启这两个选项。第三种 probe 正是为消除该困境而生。

**backoffLimit 默认值 6 比想象中更长。**指数增长的重试间隔会让放弃耗时数分钟,失败 Pod 在此期间持续累积。需要快速失败的 Job 应降低该值。

**QoS 不是写出来的,而是计算出来的。**kubelet 根据 requestslimits 组合决定,节点内存不足时先驱逐 BestEffort。重要 workload 不写 requests,等于写下“可以先杀死我”。

后续实验将通过实际行为验证全部内容。