首页 / Kubernetes (k8s) 入门教程 / 自愈与故障恢复

Kubernetes (k8s) 入门教程

自愈与故障恢复

本教程共 65 篇 · 第 52 篇 · 更新于 2026-08-14 · 约 16 分钟阅读

Kubernetes自愈故障恢复控制器探针kubelet高可用

本节目标:搞懂 Kubernetes 凭什么”自己修自己”——副本挂了能补、容器崩了能重启、节点没了能挪走,以及这些能力分别由谁在背后默默干活。

前面几十章你建过那么多对象,有没有想过一个问题:Pod 跑着跑着崩了,是谁把它重新拉起来的?节点突然断电,原本上面的副本去哪了?答案就是 Kubernetes 的**自愈(Self-healing)**能力。

这不是魔法,而是一套”有人盯着、发现不对就纠正”的机制。本章把散落在全书的自愈本领串成一条线。

52-1 自愈的本质:调谐循环

Kubernetes 里几乎所有控制器都运行同一个模式——调谐循环(Reconcile Loop)

  1. 读取你期望的状态(比如 Deployment 说”我要 3 个副本”)。
  2. 观察集群实际状态(现在只有 2 个在跑)。
  3. 发现不一致,就采取行动让实际靠拢期望(再起 1 个)。
  4. 过一会儿再检查,循环往复。

Deployment、ReplicaSet、StatefulSet、DaemonSet……全靠这个循环兜底。所以副本数少了会自动补,多了会自动减。这就是最基础的自愈。

Note

调谐循环是”声明式”的核心红利。你只管说”我要什么样”,不用写”怎么修”。控制器永远在努力把现实掰向你写的期望。

52-2 kubelet 守卫着节点上的 Pod

节点上的”现场总指挥”是 kubelet。它盯着本节点每个 Pod 的容器:

  • 容器进程退出了?按 restartPolicy 重启它。
  • 磁盘上的镜像没了?重新拉。
  • 节点要关机了?执行节点体面关闭(Graceful Node Shutdown),先通知 Pod 优雅退出。

静态 Pod(第 23 章提过)更特殊:它在节点本地由 kubelet 直接看守,即使 API 服务器连不上,kubelet 也会按本地清单把它跑起来。所以控制平面挂了,关键静态 Pod(如 kube-apiserver 本身)依然能持续服务。

Tip

想看自愈现场?故意 kubectl delete pod 一个由 Deployment 管的 Pod,再用 kubectl get pods 观察——新 Pod 几乎立刻被补上。这就是 ReplicaSet 控制器在调谐。

52-3 探针:让自愈更”懂事”

光会重启还不够。有些故障不是”进程崩了”,而是”进程活着但卡死了”。这时要靠第 14 章讲的三种探针:

  • livenessProbe(存活探针):失败 = 容器”没救了”,kubelet 按重启策略重启它。这是自愈的”触发器”。
  • readinessProbe(就绪探针):失败 = 容器”还没好”,从 Service 端点摘掉,不再接流量,但不重启。等它好了再放回。
  • startupProbe(启动探针):给慢启动应用一个”宽限期”,宽限期内别的探针先别急着判死刑。

一个经典自愈链路:

  1. 应用死锁,liveness 连续失败。
  2. kubelet 杀掉容器,按 restartPolicy: Always 重启。
  3. 重启后 readiness 还没过,Service 不导流量,避免把请求打给没准备好的实例。
  4. 应用真正就绪,readiness 通过,重新接流量。
Warning

别把 liveness 和 readiness 设成同一个探针。如果共用,一旦就绪失败,liveness 也会失败→不断重启→永远起不来。两者职责不同,务必分开配置。

52-4 重启策略 restartPolicy

Pod 层面的 restartPolicy 决定容器退出的处理方式,只有三个值:

含义典型用途
Always永远重启(默认)长期运行的服务
OnFailure只在非零退出码时重启一次性任务(常配 Job)
Never绝不重启跑完即弃、自己看日志

注意:kubelet 的重启是同节点原地重启,不是换节点。如果节点本身坏了,重启也没用——这时要靠控制器把 Pod 调度到别的节点(见下节)。

Note

Job/CronJob(第 22 章)常用 OnFailureNever,配合任务本身的重试次数,避免无限重启。普通 Deployment 几乎都用 Always

52-5 节点故障:副本会”搬家”

当整个节点失联(宕机、网络隔离),自愈怎么表现?

  1. 节点控制器(Node Controller)在 node-monitor-grace-period 内收不到心跳,把节点标记为 NotReady
  2. 再经过一段时间,节点上的 Pod 被标记为 Terminating / Unknown
  3. 这些 Pod 的 owner(如 Deployment)发现”我的副本少了一块”,于是在别的可用节点上补齐副本。
  4. 被删的 Pod 如果节点后来恢复,会因 UID 不匹配被当作孤儿清理掉。

这就是”节点没了,副本挪走”的全过程。前提是:你的应用跑了多个副本且分布在不同节点(用第 40 章的反亲和性可以强制分散)。

Tip

自愈的前提是”有冗余”。单副本 Deployment 节点一挂就真没了——所以生产服务务必设 replicas ≥ 2,并用反亲和性避免全压一个节点。

52-6 资源压力与节点驱逐

节点资源(CPU/内存/磁盘)吃紧时,kubelet 会触发节点压力驱逐(Node-pressure Eviction):挑出”最该让位”的 Pod 杀掉,腾出资源保住别的。被驱逐的 Pod 同样会被控制器在别处重建。

配合第 15 章的资源请求/限制和 QoS 等级,你能决定”谁先死”:requests 与 limits 相等的是 Guaranteed,最不容易被赶;只设 requests 的是 Burstable;啥都没设的 BestEffort 第一个被牺牲。

Warning

节点压力驱逐属于非自愿干扰,PDB(第 51 章)拦不住它,但它会占用 PDB 的预算额度。所以高可用既要 PDB,也要留冗余、设好资源请求。

52-7 故障恢复实战要点

把全书的自愈本领收成一张清单,排障时照着看:

  1. 副本少了不补 → 看 owner 控制器在不在、ReplicaSet 是不是被手动删了。
  2. 容器反复重启kubectl describe podLast StateRestart Count,多半是 liveness 误杀或应用真崩。
  3. 流量打到坏实例 → 查 readiness 探针是否正确地把坏 Pod 摘出端点。
  4. 节点挂了服务断 → 确认 replicas ≥ 2 且跨节点分布;单副本无解。
  5. 节点升级时被一波带走 → 用 PDB 限制同时下线数,让 drain 排队进行。
  6. 关键组件失联仍要活 → 考虑静态 Pod + 多控制平面节点。
Note

自愈让”小故障自动消化”,但不能替代备份与容灾。数据库主从、跨可用区、定期备份,这些永远要单独设计。自愈管的是” Pod 和节点”这一层。

小结

Kubernetes 的自愈,是三层守护叠加的结果:

  1. 控制器调谐:让副本数永远向你写的期望靠拢。
  2. kubelet + 探针 + 重启策略:让单个容器崩了能拉起、卡死能重启、没好不透流量。
  3. 节点故障处理 + 调度:让节点没了副本能搬到别处。

记住一句总纲:冗余是自愈的前提,声明式是自愈的发动机。副本够多、期望写清,Kubernetes 就会日夜不停地帮你把系统修回正轨。

至此,本教程的”弹性与发布”部分(第 48–52 章)讲完。你已掌握从扩缩、发布到中断保护、自愈的完整韧性能力。