Kubernetes Controller 原理与架构详解
1. Controller 的定位与设计目标
在 Kubernetes 中,Controller 是整个控制平面的核心组成部分之一。它负责维护 Kubernetes 集群中各种资源对象的生命周期,使系统实际运行状态不断向用户声明的目标状态靠近。
理解 Kubernetes Controller,需要先理解 Kubernetes 的核心设计思想:
Kubernetes 不是一个“执行命令”的系统,而是一个“持续维持状态”的系统。
传统运维方式属于命令式管理(Imperative Management):
例如:
docker run nginx
这个命令表达的是:
现在启动一个 nginx 容器。
命令执行结束后,系统不会主动关心:
- 容器是否还存在;
- 容器是否异常退出;
- 是否需要增加副本。
而 Kubernetes 使用声明式管理(Declarative Management):
例如:
apiVersion: apps/v1
kind: Deployment
spec:
replicas: 3
它表达的是:
系统应该始终保持 3 个 nginx 副本运行。
那么问题来了:
如果某个 Pod 被删除,谁负责发现?
如果某个节点故障,谁负责补充副本?
如果用户修改镜像版本,谁负责执行滚动更新?
这个角色就是 Controller。
2. Controller 的核心思想:控制循环(Control Loop)
Kubernetes Controller 本质上是一个不断运行的控制循环。
其核心逻辑可以抽象为:
Desired State
|
|
v
Compare Difference
|
|
Current State
|
|
Execute Action
|
|
System Changes
|
|
Observe Again
也就是说 Controller 永远在做一件事情:
观察当前状态,比较目标状态,如果存在差异,就执行调整操作。
这个过程叫:
Reconciliation(调谐)
例如:
用户创建:
replicas: 3
此时 Kubernetes 中:
Desired State:
Pod = 3
Current State:
Pod = 0
Controller 计算差异:
需要创建:
3 - 0 = 3 个 Pod
于是调用 Kubernetes API:
创建 Pod
之后再次观察:
Desired:
3
Current:
3
发现一致:
不执行任何操作。
3. 为什么 Kubernetes 要采用 Controller 模型?
3.1. 提高系统可靠性
如果没有 Controller:
管理员需要:
- 手动检查服务;
- 手动恢复故障;
- 手动扩容。
例如:
一个生产 Deployment:
nginx
replicas=10
某台 Node 故障:
Node1 Down
其中3个Pod消失
没有 Controller:
实际Pod数量:
7
系统无法自动恢复。
有 Controller:
Controller发现:
Desired=10
Current=7
创建3个新的Pod
3.2. 实现自动化运维
Controller 让 Kubernetes 从:
“执行操作”
变成:
“维护目标”。
例如:
数据库 Operator:
用户只需要声明:
kind: MySQLCluster
spec:
replicas:3
version:8.0
Controller 自动:
- 创建数据库实例;
- 配置主从复制;
- 创建存储;
- 故障切换;
- 扩缩容。
这也是 Kubernetes Operator 生态的基础。
4. Kubernetes Controller 整体架构
Kubernetes 中大量 Controller 运行在:
kube-controller-manager
组件中。
整体关系:
用户
|
kubectl
|
v
kube-apiserver
|
|
etcd
|
--------------------------------
| |
Controller Scheduler
|
|
Reconcile Loop
|
|
Kubernetes API
|
|
Pod / Node / Service
需要注意:
Controller 不会直接访问 etcd。
它只能通过:
kube-apiserver
访问 Kubernetes 状态。
原因:
API Server 提供:
- 身份认证;
- 权限控制;
- 数据校验;
- API版本转换;
- Admission Controller。
5. Controller 如何感知资源变化?
这是 Kubernetes Controller 最核心的机制。
很多资料会简单描述:
Controller 监听资源变化。
但是这个“监听”并不是:
Controller不断查询API Server
例如:
错误理解:
Controller:
每秒:
GET Pod列表
GET Pod列表
GET Pod列表
这种方式无法支撑大规模集群。
Kubernetes 使用:
5.1. List-Watch 机制
完整流程:
etcd
|
|
kube-apiserver
|
|
List + Watch API
|
|
Reflector
|
|
Informer Cache
|
|
Controller
6. List-Watch 工作机制
6.1. List阶段
Controller 启动时:
首先需要获取当前资源完整状态。
例如 Deployment Controller:
发送请求:
GET /apis/apps/v1/deployments
API Server 查询 etcd:
返回:
[
deployment-a,
deployment-b,
deployment-c
]
同时返回:
resourceVersion
例如:
resourceVersion=10086
这个版本号表示:
当前资源状态版本。
6.2. Watch阶段
获取初始状态之后:
Controller 不再重复查询。
而是建立 Watch 长连接:
GET /apis/apps/v1/deployments
?watch=true
&resourceVersion=10086
此时:
API Server保持连接。
当资源发生变化:
例如:
用户执行:
kubectl scale deployment nginx --replicas=5
流程:
kubectl
|
API Server
|
etcd
etcd中Deployment对象变化。
API Server通过 Watch 通道通知 Controller:
{
"type":"MODIFIED",
"object":
{
"name":"nginx",
"replicas":5
}
}
所以准确来说:
Controller 监听的是 API Server 提供的 Watch 事件,而不是监听其他组件。
7. Informer 机制
Controller 不直接使用 Watch 数据。
client-go 提供了 Informer。
Informer 是 Kubernetes Controller 高性能运行的关键。
Informer 内部结构:
Informer
|
|
+----------------+
|
Reflector
|
DeltaFIFO
|
Indexer
8. Reflector 的作用
Reflector 是连接 API Server 的组件。
它负责:
- List资源;
- 建立Watch;
- 接收资源变化事件。
流程:
Reflector
|
List
|
获取全部对象
|
Watch
|
接收变化事件
例如:
监听 Pod:
启动:
List Pod
获取:
pod1
pod2
pod3
然后:
Watch Pod
等待变化。
9. DeltaFIFO 的作用
Reflector 收到事件后:
不会直接交给 Controller。
而是进入:
DeltaFIFO
例如:
Pod发生变化:
ADD Pod nginx
UPDATE Pod nginx
DELETE Pod nginx
DeltaFIFO负责:
- 缓存事件;
- 保证顺序;
- 合并重复事件。
为什么需要它?
因为 Kubernetes 中资源变化非常频繁。
例如:
一个 Pod:
短时间:
创建
更新状态
更新IP
更新Node
更新Ready状态
如果每一次变化都立即处理:
Controller压力巨大。
10. Indexer 本地缓存
Informer 维护一个本地缓存:
Indexer。
例如:
API Server:
Pod nginx
Namespace:
default
Node:
node1
缓存:
Indexer:
default/nginx
之后 Controller 查询对象:
直接访问本地缓存。
不用访问 API Server。
这样:
- 降低 API Server压力;
- 提高查询速度;
- 支撑大规模集群。
11. WorkQueue 工作队列
Informer 收到事件后:
不会直接执行 Controller 逻辑。
流程:
Informer
|
Event Handler
|
WorkQueue
|
Worker
|
Reconcile
例如:
Deployment 修改:
事件:
Deployment nginx Updated
加入队列:
default/nginx
Worker:
取出:
default/nginx
执行:
syncDeployment()
12. 为什么需要 WorkQueue?
12.1. 异步解耦
Informer负责:
发现变化。
Controller负责:
处理变化。
两个速度不一样。
12.2. 支持失败重试
例如:
Controller 创建资源失败:
API Server timeout
WorkQueue:
重新加入任务。
12.3. 限制处理速度
假设:
Node故障:
1000个Pod同时变化。
如果立即处理:
可能:
Controller CPU升高
API Server压力增加
WorkQueue可以:
控制消费速度。
13. Reconcile 调谐过程
Reconcile 是 Controller 最核心的逻辑。
它不是:
收到事件
执行固定动作
而是:
收到事件
|
重新读取当前状态
|
计算目标状态
|
比较差异
|
执行修改
例如 Deployment Controller:
用户:
replicas=3
当前:
Pod=2
Reconcile:
发现:
差异=1
执行:
创建1个Pod
如果:
Pod=3
那么:
Desired == Current
什么都不做。
14. 为什么 Controller 不会无限循环?
因为 Controller 必须满足:
14.1. 幂等性(Idempotent)
错误设计:
收到Deployment事件
↓
创建Pod
这样会:
无限创建。
正确设计:
收到事件
↓
查询当前状态
↓
判断是否需要操作
例如:
第一次:
Desired:
3
Current:
2
创建:
1个。
第二次:
Desired:
3
Current:
3
不执行。
15. Kubernetes 常见 Controller
15.1. Deployment Controller
负责:
应用发布管理。
它管理:
Deployment
|
ReplicaSet
|
Pod
主要功能:
- 创建 ReplicaSet;
- 滚动升级;
- 回滚。
15.2. ReplicaSet Controller
负责:
副本数量维持。
例如:
目标:
replicas=5
实际:
Pod=4
创建:
一个 Pod。
15.3. StatefulSet Controller
用于有状态应用。
例如:
MySQL:
mysql-0
mysql-1
mysql-2
保证:
- 稳定网络标识;
- 稳定存储;
- 有序启动。
15.4. DaemonSet Controller
保证:
每个节点运行一个 Pod。
例如:
node-exporter:
node1 exporter
node2 exporter
node3 exporter
15.5. Node Controller
负责:
节点状态管理。
例如:
节点失联:
NodeReady=False
执行:
- 更新状态;
- 触发 Pod 驱逐。
16. Controller 与 Scheduler、Kubelet 的关系
一个 Pod 从创建到运行:
完整流程:
用户创建Deployment
|
|
Deployment Controller
|
|
创建ReplicaSet
|
|
ReplicaSet Controller
|
|
创建Pod
|
|
Scheduler
|
|
选择Node
|
|
Kubelet
|
|
调用container runtime
|
|
运行容器
三者职责:
| 组件 | 核心职责 |
|---|---|
| Controller | 保证资源状态正确 |
| Scheduler | 决定Pod运行位置 |
| Kubelet | 负责节点执行 |
17. Controller 源码结构
如果阅读 Kubernetes 源码:
主要位置:
kubernetes/pkg/controller
client-go:
client-go/tools/cache
client-go/util/workqueue
典型 Controller 结构:
Controller
|
|
+-- Informer
|
|
+-- WorkQueue
|
|
+-- Worker
|
|
+-- Reconcile
核心流程:
for processNextWorkItem(){
key := queue.Get()
syncHandler(key)
queue.Done(key)
}
18. Controller 与 Operator 的关系
Operator 本质:
CRD
+
Custom Controller
例如:
MySQL Operator定义:
kind: MySQLCluster
用户:
spec:
replicas:3
Controller:
自动:
- 创建 StatefulSet;
- 创建 PVC;
- 初始化数据库;
- 配置复制;
- 故障恢复。
这就是 Kubernetes 扩展能力的基础。
19. Controller 在云平台和 AIOps 中的意义
从云平台设计角度,Controller 实际上是一种通用自动化控制框架。
例如云数据库平台:
用户声明:
kind: DatabaseInstance
spec:
cpu:8
memory:32G
replicas:3
Controller 自动:
- 分配资源;
- 创建实例;
- 配置主备;
- 监控状态;
- 故障恢复。
如果结合 AIOps:
可以进一步形成:
Prometheus采集指标
|
|
AI模型预测风险
|
|
Controller执行调整
|
|
系统状态恢复
这也是未来智能运维平台的重要架构模式。
20. 总结
Kubernetes Controller 的本质可以概括为:
Controller 是运行在 Kubernetes 控制平面中的状态调节程序,它通过 client-go Informer 机制利用 API Server 的 List-Watch 能力感知资源变化,将事件放入 WorkQueue,通过 Reconcile Loop 比较资源对象的期望状态和实际状态,并调用 Kubernetes API 修改资源,使整个系统持续保持在用户声明的目标状态。
完整链路:
API Server
|
|
List-Watch
|
|
Informer
|
|
WorkQueue
|
|
Controller Worker
|
|
Reconcile
|
|
Kubernetes API
|
|
资源状态变化
理解 Controller 后,Kubernetes 中绝大多数高级机制——Deployment、Operator、Volcano、Cluster Autoscaler、自动修复系统——都可以归结为同一种设计思想:
观察状态 → 判断差异 → 执行动作 → 回到观察状态。
关联文档
- K8s Operator 完整详解:理解 Operator 如何扩展 Controller 模型。
- K8s Operator 开发全流程:查看自定义 Controller 的工程实现过程。
- K8s 核心接口标准详解:补充 Kubernetes 资源接口与声明式 API 设计。
