Kubernetes 控制器与operator的联系
Kubernetes 控制器与 Operator 的联系
一、核心关系概述
Operator = 自定义资源(CRD) + 自定义控制器
Operator 是特殊化的、应用特定的控制器,构建在 Kubernetes 控制器模式之上,用于管理复杂的、有状态的应用程序。
二、架构对比
基础控制器模式
API Server (期望状态) → 控制器 → 实际状态
(声明式API) (执行动作)
Operator 扩展了此模式
API Server (自定义资源) → Operator控制器 → 应用管理
(应用特定知识) (复杂运维逻辑)
三、演进关系图解
graph TB
A[Kubernetes 控制器模式] --> B[基础控制器]
A --> C[扩展机制]
B --> D[Deployment控制器]
B --> E[StatefulSet控制器]
B --> F[其他内置控制器]
C --> G[CRD: 自定义资源定义]
C --> H[API扩展]
G --> I[自定义控制器]
H --> I
I --> J[Operator模式]
J --> K[应用专业知识编码]
J --> L[自动化运维逻辑]
D --> M[管理无状态应用]
E --> N[管理有状态应用]
J --> O[管理复杂应用全生命周期]
四、详细对比表
| 维度 | Kubernetes 控制器 | Operator |
|---|---|---|
| 本质 | 内置的自动化控制循环 | 自定义控制器的特定实现 |
| 管理对象 | Pod、Service、Deployment 等原生资源 | 自定义资源(如 MySQLCluster、RedisCluster) |
| 知识范围 | 通用的 Kubernetes 资源管理 | 应用特定的运维知识 |
| 复杂度 | 相对简单,处理通用逻辑 | 复杂,包含应用全生命周期管理 |
| 开发方 | Kubernetes 核心团队 | 应用开发者/厂商/社区 |
| 部署方式 | 随 kube-controller-manager 运行 | 独立部署在集群中 |
| 目标 | 确保 Kubernetes 资源状态一致 | 确保应用状态与业务期望一致 |
五、技术继承关系
1. 共享的核心机制
// 两者都使用的控制器模式
type Controller interface {
// 1. 监听资源变化
Watch(resourceType) error
// 2. 调谐循环
Reconcile(ctx context.Context, req Request) (Result, error)
// 3. 事件处理
HandleEvent(event Event) error
}
2. 相同的底层组件
# Operator 复用控制器框架
dependencies:
- client-go # Kubernetes 客户端库
- controller-runtime # 控制器运行时框架
- informer # 资源监听机制
- workqueue # 事件队列处理
- leader-election # 领导者选举
六、从控制器到 Operator 的演进
阶段 1:基础控制器
// 管理简单的副本数
func (r *ReplicaSetReconciler) Reconcile() {
// 检查当前 Pod 数量
currentPods := getPods()
// 与期望副本数比较
if len(currentPods) < desiredReplicas {
// 创建新的 Pod
createPod()
}
}
阶段 2:有状态控制器
// StatefulSet 控制器:添加了顺序和持久化
func (r *StatefulSetReconciler) Reconcile() {
// 有序创建 Pod
for i := 0; i < desiredReplicas; i++ {
if !podExists(i) {
// 按顺序创建,绑定持久卷
createPodWithPV(i)
break
}
}
}
阶段 3:Operator(应用专家)
// MySQL Operator:包含应用专业知识
func (r *MySQLOperator) Reconcile() {
// 1. 检查集群状态
if !clusterHealthy() {
healCluster()
}
// 2. 管理备份
if timeForBackup() {
performBackup()
}
// 3. 处理升级
if newVersionAvailable() {
rollingUpgrade()
}
// 4. 监控和告警
checkMetricsAndAlert()
// 5. 配置管理
syncConfiguration()
}
七、实际示例对比
场景:部署一个 Web 应用
使用原生控制器
# 1. 创建 Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
name: webapp
spec:
replicas: 3
template:
spec:
containers:
- name: web
image: nginx:1.19
# 2. 创建 Service
apiVersion: v1
kind: Service
metadata:
name: webapp-service
spec:
selector:
app: webapp
ports:
- port: 80
# 3. 手动执行备份、监控、升级等运维操作
使用 Operator(如 ArgoCD Operator)
# 1. 定义 GitOps 应用
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: webapp
spec:
source:
repoURL: 'https://github.com/example/webapp.git'
targetRevision: HEAD
path: k8s/
destination:
server: 'https://kubernetes.default.svc'
namespace: default
syncPolicy:
automated:
prune: true
selfHeal: true
# 2. Operator 自动处理:
# - 从 Git 同步配置
# - 自动部署
# - 健康检查
# - 回滚管理
# - 通知和告警
八、Operator 如何扩展控制器能力
1. 添加应用特定语义
# 原生资源:不知道"数据库"是什么
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: mysql
spec:
# 只是管理 Pod 副本
# 自定义资源:理解数据库概念
apiVersion: mysql.example.com/v1
kind: MySQLCluster
metadata:
name: production-db
spec:
replicas: 3
storageSize: 100Gi
backup:
schedule: "0 2 * * *"
retentionDays: 30
version: "8.0.28"
2. 封装运维逻辑
// Operator 封装复杂操作
func (r *DatabaseOperator) handleFailover() {
// 1. 检测主节点故障
if primaryFailed() {
// 2. 选举新的主节点
newPrimary := electNewPrimary()
// 3. 重新配置副本
reconfigureReplicas(newPrimary)
// 4. 更新 DNS/服务发现
updateServiceDiscovery(newPrimary)
// 5. 发送通知
sendAlert("Failover completed")
// 6. 记录事件
recordEvent("Failover", newPrimary)
}
}
九、技术栈继承关系
Kubernetes 控制器技术栈
kube-controller-manager
├── deployment-controller
├── replicaset-controller
├── statefulset-controller
├── daemonset-controller
└── job-controller
Operator 技术栈(构建于控制器之上)
Operator Framework
├── Operator SDK
├── controller-runtime
├── client-go
├── apimachinery
└── Custom Controller
├── Custom Resource Definition
├── Reconciliation Loop
├── Finalizers
├── Owner References
└── Status Subresource
十、设计模式演变
模式 1:原生控制器模式
// 管理 Kubernetes 原生对象
type NativeController struct {
Client kubernetes.Interface
Informer cache.SharedIndexInformer
Workqueue workqueue.RateLimitingInterface
}
func (c *NativeController) Run(stopCh <-chan struct{}) {
// 监听 Kubernetes 资源
}
模式 2:Operator 模式
// 管理自定义资源
type Operator struct {
// 继承控制器基础设施
controller.NativeController
// 添加 Operator 特定功能
CustomClient client.Client // 自定义资源客户端
EventRecorder record.EventRecorder // 事件记录
Metrics *operatorMetrics // 业务指标
// 应用专业知识
AppConfig *AppConfiguration // 应用配置
BackupManager BackupManager // 备份管理器
UpgradeManager UpgradeManager // 升级管理器
}
十一、实际案例:从控制器到 Operator
案例:管理 Elasticsearch 集群
方案 1:使用原生控制器(复杂)
# 需要手动编写和管理多个资源
kubectl apply -f elasticsearch-statefulset.yaml
kubectl apply -f elasticsearch-service.yaml
kubectl apply -f elasticsearch-configmap.yaml
kubectl apply -f elasticsearch-pv.yaml
# 手动处理:
# - 节点发现
# - 滚动升级
# - 备份恢复
# - 监控配置
# - 证书管理
方案 2:使用 Elasticsearch Operator(简单)
# 一个资源定义全部需求
apiVersion: elasticsearch.k8s.elastic.co/v1
kind: Elasticsearch
metadata:
name: quickstart
spec:
version: 8.11.0
nodeSets:
- name: default
count: 3
config:
node.store.allow_mmap: false
# Operator 自动处理:
# 1. 创建 StatefulSet、Service、ConfigMap
# 2. 配置节点间 TLS 加密
# 3. 设置集群健康检查
# 4. 管理滚动升级
# 5. 提供监控端点
# 6. 处理节点故障恢复
十二、选择指南
何时使用原生控制器?
- ✅ 管理无状态应用
- ✅ 标准部署模式
- ✅ 简单的扩缩容需求
- ✅ 不需要应用特定知识
何时使用 Operator?
- ✅ 管理有状态复杂应用(数据库、消息队列)
- ✅ 需要自动化运维操作(备份、升级、恢复)
- ✅ 应用有特定的配置需求
- ✅ 需要封装领域专业知识
- ✅ 实现 GitOps 或高级部署策略
十三、总结
Operator 是 Kubernetes 控制器模式的自然演进和专业化扩展:
- 继承关系:Operator 完全基于控制器模式构建
- 专业化:Operator 添加了应用特定领域的知识
- 扩展性:通过 CRD 扩展 Kubernetes API
- 自动化:将复杂的运维操作编码为自动化逻辑
- 声明式演进:从"如何部署"到"期望的应用状态"
关键理解:
- 所有 Operator 都是控制器
- 但不是所有控制器都是 Operator
- Operator = 通用控制器模式 + 应用专业知识 + CRD 扩展
- Operator 使 Kubernetes 从"容器编排平台"升级为"应用管理平台"
这种演进使得 Kubernetes 能够管理越来越复杂的应用,将运维专家的知识沉淀为可重复使用的自动化代码。
浙公网安备 33010602011771号