【Kubernetes从入门到精通】第62篇:Controller Manager——K8s的“自动驾驶仪“,让集群永动机一样自我修复

📅 2026/8/21 3:18:51
【Kubernetes从入门到精通】第62篇:Controller Manager——K8s的“自动驾驶仪“,让集群永动机一样自我修复
上一篇【第61篇】第61篇etcd——K8s的“记忆中枢“集群的“命根子“就这么会被你搞丢下一篇【第63篇】Informer机制——K8s高性能事件驱动的核心摘要前面讲了API Server前台和etcd档案室。现在问一个深刻的问题为什么你在K8s里写个replicas: 3它就真的给你保持3个Pod少一个自动补、多一个自动删这背后的功臣是Controller Manager——它里面跑着一群永动机般的控制器每个控制器盯一种资源Deployment控制器盯Deployment、Node控制器盯Node……。它们的共同哲学是不断对比你期望的状态和实际的状态不一样就动手把它们拉齐。这就是K8s声明式自愈的本质。这篇文章讲清控制器的多架构、核心的协调循环模式并以Deployment控制器为例看它怎么把声明变成现实。一、Controller Manager里有什么1.1 一群控制器【Controller Manager 里的部门】 kube-controller-manager 进程里同时跑着 • Deployment Controller → 管Deployment/ReplicaSet • ReplicaSet Controller → 管Pod副本数 • Node Controller → 管节点增删/心跳 • Endpoint Controller → 维护Service的Endpoints • ServiceAccount Controller → 管SA和token • ResourceQuota Controller → 管资源配额 • Namespace Controller → 管namespace生命周期 • StatefulSet Controller → 管有状态应用 • DaemonSet Controller → 管节点守护 • Job Controller → 管批处理任务 • ... 还有十几个 每个控制器都是独立goroutine并发运行要点注意这里的架构智慧——每种资源一个专门的控制器而不是一个大杂烩。这样每个控制器逻辑清晰、可以独立开发测试、出问题时不影响其他控制器。它们都只通过API Server操作互不直连完美解耦。1.2 leader选举【高可用多个Controller Manager但只有一个干活】 生产环境会跑多个 kube-controller-manager 实例 但同一时刻只有一个是 Leader(真正在调谐) 其他是 Standby(待命) 通过 etcd 的租约(lease)做 leader 选举 • 大家都抢着在 etcd 写一个 key • 谁抢到谁当 Leader • Leader 定期续租挂了 → 租约过期 → 别人上位 → 避免两个控制器同时调谐导致冲突二、控制器模式协调循环2.1 核心思想所有控制器的本质是同一个循环【控制器模式——永动机三步走】 loop forever: 1. Observe (观察): 通过Informer拿到 • 期望值(Spec): 用户写的 replicas: 3 • 实际值(Status): 当前实际有几个Running Pod 2. Diff (对比): 期望 vs 实际 • 实际2个期望3个 → 差1个 • 实际5个期望3个 → 多2个 3. Act (行动): 让实际靠拢期望 • 少 → 创建Pod • 多 → 删除Pod → 然后继续loop直到 期望实际【声明式 vs 命令式的本质区别】 命令式(老方式): 创建3个Pod! (一次性指令做完就完了) → Pod挂了没人管 声明式(K8s): 我要3个Pod常驻 (持续目标) → 控制器一直盯着少一个补一个 → 这就是自愈的来源2.2 一个通俗比喻【控制器像 thermostat 恒温器】 你设: 温度 25°C (期望值/Spec) 实际: 现在 22°C (实际值/Status) 恒温器: 22 25 → 开暖气 (Act) 过了一会: 25°C → 关暖气 之后温度掉了 → 又开 K8s控制器完全一样 你设: replicas: 3 实际: 2个Pod在跑 控制器: 创建1个Pod 之后有Pod挂了 → 又创建三、Deployment控制器实战拆解3.1 它怎么工作【Deployment Controller 的内部运转】 你 apply deployment.yaml (replicas: 3) │ ▼ Deployment Controller 看到新Deployment │ ▼ 1. 确保有对应的 ReplicaSet (没有就创建) │ ▼ 2. ReplicaSet Controller 看到 RS 期望3个 │ ▼ 3. 实际Pod数 3 → 创建Pod (打到API Server) │ ▼ 4. kubelet 看到新Pod → 真正起容器 │ ▼ 5. Pod Running → 状态回写etcd │ ▼ 6. 控制器再Observe → 实际期望 → 本轮结束 ── 之后某个Pod挂了 ── 7. kubelet上报Pod Failed 8. ReplicaSet Controller发现少1个 → 再创建 9. 自愈完成3.2 滚动更新时控制器在干啥# 你改了镜像版本kubectlsetimage deployment/webnginxnginx:1.25# Deployment Controller 做的事# 1. 创建新的 ReplicaSet (new-RS, 期望0)# 2. 逐步: new-RS 1, old-RS -1 (滚动)# 3. 直到 new-RS3, old-RS0# 4. 保留 old-RS 用于回滚(默认历史留10个)四、控制器的三件套Informer/WorkQueue/Lister4.1 标准实现【一个控制器的标准零件】 ┌──────────────────────────────────────────┐ │ Informer (情报员) │ │ • 通过Watch实时监听资源变化 │ │ • 维护本地缓存(Indexer) │ │ • 变化时把key塞进WorkQueue │ └────────────────┬─────────────────────────┘ │ key (如 default/web-abc) ▼ ┌──────────────────────────────────────────┐ │ WorkQueue (工作队列) │ │ • 存放需要处理的资源key │ │ • 去重(同一key不重复处理) │ │ • 限速(避免疯狂重试) │ └────────────────┬─────────────────────────┘ │ 取出key ▼ ┌──────────────────────────────────────────┐ │ Reconcile (调谐函数) │ │ • 用Lister从本地缓存取对象 │ │ • 对比期望vs实际 │ │ • 调API Server做变更 │ └──────────────────────────────────────────┘ (Informer机制见第063篇详细讲)要点控制器的标准实现就是这三件套——Informer负责第一时间知道变了WorkQueue负责排队、去重、限速Reconcile函数负责真正干活的调谐逻辑。Operator第074篇也是这套模式只不过管的是自定义资源。理解了这套你就能自己写控制器了。本篇小结Controller Manager是K8s的自动驾驶仪里面每个控制器盯一种资源靠Observe→Diff→Act的协调循环不断把实际状态拉向期望状态——这就是自愈和声明式的本质。多个控制器实例通过etcd租约选主同一时刻只有一个Leader在调谐保证高可用。Deployment控制器的拆解展示了标准流程看到Deployment→确保RS→确保Pod数→kubelet起容器→状态回写→循环直到一致。控制器的标准三件套Informer/WorkQueue/Reconcile是编写任何控制器的模板。下篇深入Informer机制——高性能事件驱动的核心。上一篇【第61篇】第61篇etcd——K8s的“记忆中枢“集群的“命根子“就这么会被你搞丢下一篇【第63篇】Informer机制——K8s高性能事件驱动的核心