亲眼看调度器怎么挑位置
本实验在资源真正不足的集群中进行
VM 中运行着真正的 k3s。节点 CPU 确实有限,因此如果请求过大, 就会真的因为没有位置而一直处于 Pending。
CKA 课程中的其他调度实验使用模拟集群,其中有多个模拟节点, 且没有资源压力,所以无论请求什么都能被调度。因此,过去无法确认 调度器实际依据什么拒绝调度。
首次启动大约需要 2 分钟。
目标
通过真正制造无法调度的情况,确认调度器选择位置的五种机制, 并进一步观察低优先级 Pod 被驱逐。
为什么这很重要
调度设置的问题,往往不是“写对后能放到期望的位置”,而是
“写错后哪里都放不下”。它的症状永远相同——Pod 处于 Pending。
原因分散在多个层面。
- 资源请求大于节点容量 →
Insufficient cpu - 未容忍 taint →
untolerated taint - 没有符合
requiredaffinity 的节点 →didn't match node affinity - anti-affinity 阻止放到同一节点
- 拓扑分布为
DoNotSchedule,但没有可用于分布的节点
调度器总会在事件中记录无法调度的原因。 本实验的核心就是训练如何阅读这些信息。
步骤
所有对象都创建在 csch namespace 中。只有一个节点。
- 将节点的
capacity、allocatable,以及当前已请求的数量保存到/root/csch/capacity.txt。 - 创建
hog-a、hog-b、hog-c三个 Pod 争夺资源。前两个应成功调度,第三个应保持Pending。将调度器原因保存到/root/csch/pressure.txt。 - 为节点添加
lab=only:NoScheduletaint,对比没有 toleration 的no-tol与有 toleration 的with-tol,并将结果保存到/root/csch/taint.txt。 - 为节点添加标签
disktype=ssd,创建aff-required(可匹配)、aff-impossible(将不存在的标签设为 required)、aff-preferred(将不存在的标签设为 preferred)三个 Pod,并将结果保存到/root/csch/affinity.txt。 - 为
spreadDeployment(副本数 2)配置 required anti-affinity。由于只有一个节点,应只有一个副本能够运行。将结果保存到/root/csch/anti.txt。 - 创建
low-prio、high-prioPriorityClass,先用低优先级 Pod 填满节点,再加入高优先级的important,使其发生抢占。将结果保存到/root/csch/preempt.txt。 - 为
evenDeployment 配置topologySpreadConstraints,将其设为ScheduleAnyway,并将结果保存到/root/csch/spread.txt。 - 在
/root/csch/report.md中写入pending_reason=Insufficient、taint_effect=NoSchedule、high_priority_value=三行及相关说明。
参考
- 节点信息位于
kubectl describe node输出的 Capacity、Allocatable、Allocated resources 三个部分,它们代表不同的值。 - 调度器原因位于
kubectl -n csch describe pod <이름>的 Events,或.status.conditions[?(@.type=="PodScheduled")].message中。 - 使用
kubectl taint node <노드> lab=only:NoSchedule添加 taint,删除时在末尾加上-。 - 第 7 步若将
whenUnsatisfiable设为DoNotSchedule,由于只有一个节点,所有副本都无法运行。 请使用ScheduleAnyway。 - 常见错误 1:不用
requests,却试图用limits争夺调度位置。调度器只看requests。limits是运行期间由内核强制执行的值。 - 常见错误 2:添加 taint 后疑惑为什么现有 Pod 没有被驱逐。
NoSchedule只阻止新调度;若要驱逐现有 Pod,需要使用NoExecute。
节点有多少资源
将节点的 capacity、allocatable,以及当前已请求的数量保存到 /root/csch/capacity.txt。
capacity 是硬件总量,allocatable 是扣除系统预留后的剩余量,Allocated resources 是当前已经请求的总和。
资源不足时等待调度
创建 hog-a、hog-b、hog-c 三个 Pod 争夺资源。前两个应成功调度,第三个应保持 Pending。将调度器原因保存到 /root/csch/pressure.txt。
将 CPU requests 设得足够大,使节点只能容纳两个 Pod。调度器只查看 requests。
节点拒绝调度
为节点添加 lab=only:NoSchedule taint,对比没有 toleration 的 no-tol 与有 toleration 的 with-tol,并将结果保存到 /root/csch/taint.txt。
taint 设置在节点上,toleration 配置在 Pod 上。NoSchedule 只阻止新调度。
required 与 preferred
为节点添加标签 disktype=ssd,创建 aff-required(可匹配)、aff-impossible(将不存在的标签设为 required)、aff-preferred(将不存在的标签设为 preferred)三个 Pod,并将结果保存到 /root/csch/affinity.txt。
required 无法满足时会永久保持 Pending;preferred 无法满足时仍可调度。
避开相同节点
为 spread Deployment(副本数 2)配置 required anti-affinity。由于只有一个节点,应只有一个副本能够运行。将结果保存到 /root/csch/anti.txt。
topologyKey: kubernetes.io/hostname 表示“必须位于不同节点”。只有一个节点时,第二个副本无处可放。
高优先级抢占位置
创建 low-prio、high-prio PriorityClass,先用低优先级 Pod 填满节点,再加入高优先级的 important,使其发生抢占。将结果保存到 /root/csch/preempt.txt。
先用低优先级 Pod 填满节点,再加入高优先级 Pod,调度器就会驱逐低优先级 Pod。
均匀分布
为 even Deployment 配置 topologySpreadConstraints,将其设为 ScheduleAnyway,并将结果保存到 /root/csch/spread.txt。
因为只有一个节点,所以必须设置 whenUnsatisfiable: ScheduleAnyway。如果使用 DoNotSchedule,所有副本都无法运行。
总结所学内容
在 /root/csch/report.md 中写入 pending_reason=Insufficient、taint_effect=NoSchedule、high_priority_value= 三行及相关说明。
除 pending_reason=、taint_effect=、high_priority_value= 三行外,还要写明缩小 Pending 原因范围的排查顺序。