operator 是用 go 编写的自定义控制器,监听 customresource 并协调原生资源;不用 yaml 因其无法自动响应状态变化,仅适用于有复杂生命周期的状态化应用。

Operator 是什么,为什么不用直接写 YAML
Operator 不是 Kubernetes 原生资源,而是你用 Go 编写的、运行在集群里的“自定义控制器”。它监听你定义的 CustomResource(比如 MyDatabase),然后调用 client-go 创建/更新/删除 Deployment、Service、Secret 等原生资源。直接写 YAML 无法响应状态变化——比如数据库崩溃后自动拉起新实例、扩容时自动初始化副本,这些逻辑必须由 Operator 主动协调。
真正需要 Operator 的场景很明确:你的应用有状态、有生命周期管理逻辑、且不能靠 StatefulSet 默认行为覆盖。别为了“高大上”写 Operator,多数无状态服务用 Helm + Kustomize 更轻量。
用 controller-runtime 快速启动一个 Operator
别从 client-go 零写——controller-runtime 封装了 Informer、Reconcile 循环、Leader 选举等重复逻辑,是当前事实标准。用 operator-sdk init 或 kubebuilder init 生成骨架后,核心就是实现 Reconcile 方法:
使用 uber-go/dig 在 Golang 中实现依赖注入——基于反射容器,提供 Provide/Invoke、dig.In/dig.Out 参数与结果对象,支持命名依赖等
func (r *MyDatabaseReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
var db MyDatabase
if err := r.Get(ctx, req.NamespacedName, &db); err != nil {
return ctrl.Result{}, client.IgnoreNotFound(err)
}
// 检查是否要创建 Pod
var pod corev1.Pod
if err := r.Get(ctx, types.NamespacedName{Namespace: db.Namespace, Name: db.Name}, &pod); err != nil {
if apierrors.IsNotFound(err) {
// 创建 Pod 的逻辑
pod := NewPodForDB(&db)
if err := r.Create(ctx, &pod); err != nil {
return ctrl.Result{}, err
}
}
return ctrl.Result{}, err
}
return ctrl.Result{}, nil
}
-
Reconcile不是事件回调,而是“最终一致性循环”:每次被触发就检查当前状态 vs 期望状态,然后做最小必要操作 - 不要在
Reconcile里 sleep 或阻塞,超时默认 15 秒,卡住会导致队列积压 - 所有 client 操作(
Get/Create/Update)都必须带ctx,否则 Leader 切换时可能残留 goroutine
如何让 Operator 看到自定义资源(CRD)
CRD 必须先安装进集群,Operator 才能通过 scheme.AddToScheme 注册类型并监听。常见错误是只在本地 make install 却忘了部署到目标集群:
- 运行
make install生成 CRD YAML 并kubectl apply -f config/crd/bases/,不是仅go run就完事 - 确保
main.go中注册了你的 Scheme:mydatabasev1.AddToScheme(mgr.GetScheme()),漏掉这句Get会返回no kind "MyDatabase" is registered - CRD 的
spec.version和 Go struct 的GroupVersionKind必须严格匹配,大小写、复数形式(如mydatabases)都不能错
调试 Operator 时最常卡在哪
Operator 启动后没反应?90% 是权限或 RBAC 问题。它需要明确声明能操作哪些资源:
- 检查
config/rbac/role.yaml是否包含对MyDatabase的get/list/watch,以及对Pods/Services的create/update/delete - 用
kubectl auth can-i --list -n myns验证 Operator ServiceAccount 权限 - 日志里出现
failed to list *v1.MyDatabase: the server could not find the requested resource→ CRD 没装;出现Forbidden: User "system:serviceaccount:myns:my-operator" cannot list resource "mydatabases"→ RBAC 缺权限 - 本地调试用
make run ENABLE_WEBHOOKS=false绕过证书问题,但上线前必须启用 webhook 做准入校验
Operator 的复杂性不在 Go 语法,而在你得同时理解 Kubernetes 的对象模型、事件驱动机制、以及你自己的业务状态机怎么映射过去。一个没想清楚的终态定义(比如“备份完成”究竟以哪个字段为标志),比十个 nil panic 更难 debug。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!










