LabHub
学习 学习路径 课程

CKA — Kubernetes 管理员

先弄坏,再修好

在 LabHub 中继续学习

目标

亲手制造并修复实际工作中最常遇到的五类故障,在实践中掌握从症状逐步定位根因的排查顺序。

为什么重要

故障排查占 CKA 分值的 30%,是占比最大的领域。但仅仅查看已经修复好的结果无法真正学会排障。因此,本实验按照由学员制造故障状态、将症状保存到文件,然后再进行修复的顺序设计。每一步的评分不仅检查修复后的结果,还会同时检查故障确实曾经存在的证据

养成记录症状的习惯本身就是一项实务技能。故障结束后,证据就会消失。若要在之后说明根因,必须保留故障发生当时的事件和状态。

前面步骤中形成的集群状态(已 cordon 的节点、带污点的节点)会一直保留到后续步骤。最后一题需要准确记住这些状态才能完成。

步骤

  1. 创建命名空间 cka-broken,并创建 Deployment web(副本数 2),使用镜像 nginx:1.99-nonexistent。将能看到该错误镜像标签的输出保存到 /root/cka-broken/bad-image.txt,然后把镜像替换为 nginx:1.27,使其达到 2/2 Ready。不要删除 Deployment,只修复镜像。
  2. 创建 Pod heavy(镜像 nginx:1.27),将 requests 设为 cpu: 500memory: 2000Gi。确认它进入 Pending,并将包含原因的输出保存到 /root/cka-broken/pending.txt。保留 heavy,不要删除;再创建 Deployment heavy-fixed(副本数 1、镜像 nginx:1.27、requests 为 cpu: 500mmemory: 2000Mi),使其达到 1/1 Ready。
  3. 创建 Service api-svc(选择器 app=api,端口 80),再创建 Deployment api,并故意将 Pod 标签和选择器错误地设为 app=api-v2。把 api-svc 端点为空的状态保存到 /root/cka-broken/svc-before.txt,然后将 api 修正为标签 app=api,使 2 个副本均达到 Ready。Service 的选择器保持 app=api 不变。
  4. 创建命名空间 cka-broken-quota,并创建 ResourceQuota cka-quota,设置为 pods: "2"requests.cpu: "1"。创建 Deployment q-app(副本数 4、镜像 nginx:1.27、requests 为 cpu: 200m)后,只会有部分 Pod 启动。将显示 exceeded quota 的事件保存到 /root/cka-broken/quota.txt,然后把配额的 pods 提高到 5,使其达到 4/4 Ready。
  5. cka-broken 中创建 Deployment critical(副本数 2、镜像 nginx:1.27、Pod 标签 app=critical)和 PDB critical-pdb(选择器 app=criticalminAvailable: 2)。尝试 drain lab-node-2,将阻止操作的消息保存到 /root/cka-broken/pdb.txt;然后把 minAvailable 降为 1,对 lab-node-2 执行 cordon + drain,将其完全清空。
  6. lab-node-0 添加标签 disktype=ssd 和污点 maintenance=true:NoSchedule。创建 Pod needs-toleration(镜像 nginx:1.27、nodeSelector 为 disktype=ssd、无容忍),确认其处于 Pending,并将原因保存到 /root/cka-broken/taint.txt。保留 needs-toleration,再创建 Pod needs-toleration-fixed,使用相同的 nodeSelector 并添加容忍,将其调度到 lab-node-0
  7. 创建 Pod data-app(镜像 nginx:1.27),使其将 PVC app-data 挂载到 /data。此时 PVC 尚不存在,将 Pod 无法启动的原因保存到 /root/cka-broken/pvc.txt;然后创建 PV cka-fix-pv(1Gi、RWO、storageClassName cka-fix、hostPath /mnt/cka-fix)和 PVC app-data(1Gi、RWO、cka-fix),使其变为 Bound,并让 data-app 进入 Running。
  8. 创建 Deployment recovered(副本数 4、镜像 nginx:1.27、Pod 标签 app=recovered),将其部署到 cka-broken 中。requests 设置为 cpu: 100mmemory: 128Mi,添加 maintenance=true:NoSchedule 容忍;topologySpreadConstraints 设置为 maxSkew 1 / topologyKey kubernetes.io/hostname / whenUnsatisfiable ScheduleAnyway / labelSelector app=recovered。使其达到 4/4 Ready,并把已修复的五类问题整理到 /root/cka-broken/summary.md。该文件必须包含 imagetaintselectorquotapdb 这五个词。

参考

错误的镜像标签

创建命名空间 cka-broken,并创建 Deployment web(副本数 2),使用镜像 nginx:1.99-nonexistent。将能看到该错误镜像标签的输出保存到 /root/cka-broken/bad-image.txt,然后把镜像替换为 nginx:1.27,使其达到 2/2 Ready。不要删除 Deployment,只修复镜像。

先使用错误标签创建资源并留下证据,然后只替换镜像。如果删除并重新创建 Deployment,故障版本记录会消失,评分将无法通过。

资源请求单位错误

创建 Pod heavy(镜像 nginx:1.27),将 requests 设为 cpu: 500memory: 2000Gi。确认它进入 Pending,并将包含原因的输出保存到 /root/cka-broken/pending.txt。保留 heavy,不要删除;再创建 Deployment heavy-fixed(副本数 1、镜像 nginx:1.27、requests 为 cpu: 500mmemory: 2000Mi),使其达到 1/1 Ready。

cpu 值中漏写 m 时,单位就不是毫核,而是核。describe 输出的 Events 部分会原样说明调度器失败的原因。

Service 与标签不匹配的 Deployment

创建 Service api-svc(选择器 app=api,端口 80),再创建 Deployment api,并故意将 Pod 标签和选择器错误地设为 app=api-v2。把 api-svc 端点为空的状态保存到 /root/cka-broken/svc-before.txt,然后将 api 修正为标签 app=api,使 2 个副本均达到 Ready。Service 的选择器保持 app=api 不变。

Deployment 的 spec.selector 不可变。如果最初创建错误,就必须重新创建,而不能直接修改。不要改动 Service 一侧的选择器。

超出 ResourceQuota

创建命名空间 cka-broken-quota,并创建 ResourceQuota cka-quota,设置为 pods: "2"requests.cpu: "1"。创建 Deployment q-app(副本数 4、镜像 nginx:1.27、requests 为 cpu: 200m)后,只会有部分 Pod 启动。将显示 exceeded quota 的事件保存到 /root/cka-broken/quota.txt,然后把配额的 pods 提高到 5,使其达到 4/4 Ready。

受配额限制的 Pod 会以 ReplicaSet 事件的形式出现,而不是 Pod 事件。提高配额之前,先保存该事件。

被 PDB 阻止的 drain

cka-broken 中创建 Deployment critical(副本数 2、镜像 nginx:1.27、Pod 标签 app=critical)和 PDB critical-pdb(选择器 app=criticalminAvailable: 2)。尝试 drain lab-node-2,将阻止操作的消息保存到 /root/cka-broken/pdb.txt;然后把 minAvailable 降为 1,对 lab-node-2 执行 cordon + drain,将其完全清空。

当副本数为 2 且 minAvailable 为 2 时,一个 Pod 也无法驱逐。不要用 --force 强行执行,而应重新计算 PDB 要保护的可用数量。

缺少容忍

lab-node-0 添加标签 disktype=ssd 和污点 maintenance=true:NoSchedule。创建 Pod needs-toleration(镜像 nginx:1.27、nodeSelector 为 disktype=ssd、无容忍),确认其处于 Pending,并将原因保存到 /root/cka-broken/taint.txt。保留 needs-toleration,再创建 Pod needs-toleration-fixed,使用相同的 nodeSelector 并添加容忍,将其调度到 lab-node-0

NoSchedule 污点只会阻止新 Pod,不会影响已经运行的 Pod。不要删除故障 Pod,请将其保留下来。

不存在的 PVC

创建 Pod data-app(镜像 nginx:1.27),使其将 PVC app-data 挂载到 /data。此时 PVC 尚不存在,将 Pod 无法启动的原因保存到 /root/cka-broken/pvc.txt;然后创建 PV cka-fix-pv(1Gi、RWO、storageClassName cka-fix、hostPath /mnt/cka-fix)和 PVC app-data(1Gi、RWO、cka-fix),使其变为 Bound,并让 data-app 进入 Running。

先创建 Pod 并确认失败,再创建卷。PVC 绑定后,调度器会重新尝试调度该 Pod,稍等片刻即可。

综合:在保留现状的集群中部署恢复后的应用

创建 Deployment recovered(副本数 4、镜像 nginx:1.27、Pod 标签 app=recovered),将其部署到 cka-broken 中。requests 设置为 cpu: 100mmemory: 128Mi,添加 maintenance=true:NoSchedule 容忍;topologySpreadConstraints 设置为 maxSkew 1 / topologyKey kubernetes.io/hostname / whenUnsatisfiable ScheduleAnyway / labelSelector app=recovered。使其达到 4/4 Ready,并把已修复的五类问题整理到 /root/cka-broken/summary.md。该文件必须包含 imagetaintselectorquotapdb 这五个词。

当前集群中分别有一个已 cordon 的节点和一个带污点的节点。先判断若要使用其中某个节点需要满足什么条件,再进行部署。