operator 是封装 controller 模式的可复用 go 程序包,核心区别在于 reconcile 输入为自定义 crd 类型(如 mydatabase),需先注册 crd、显式添加类型到 scheme,并正确处理子资源生命周期与权限。

Operator 是什么,和普通 Controller 有啥区别
它不是新概念,而是把 Controller 模式封装成可复用、可发布的 Go 程序包。核心差异在 Reconcile 函数的输入:普通 Controller 处理 corev1.Pod 这类内置资源;Operator 的 Reconcile 输入是你自己定义的 CRD 类型,比如 MyDatabase。Kubernetes 不知道这个类型长什么样,所以你得先用 kubectl apply -f crd.yaml 注册它,再让 Operator 监听这个类型。
- CRD 必须先部署成功,否则 Operator 启动时会报错:
no matches for kind "MyDatabase" in version "database.example.com/v1" - Operator 的 Scheme 必须显式注册你的 CRD 类型,漏掉
mydatabase.AddToScheme(scheme)就会 panic - 不要用
client.Get()直接查 CR 实例而不先检查 Namespace 是否存在——CR 可能跨 namespace,但默认 client scope 是 namespaced
用 controller-runtime 快速启动一个 Operator
controller-runtime 是当前主流选择,它把 client-go 底层细节封装掉了,重点暴露 Builder 和 Reconciler。初始化项目不用从零写 main.go,推荐用 operator-sdk init(v1.28+)或直接 go mod init + 手动引入依赖。
- 必须调用
mgr.AddMetricsExtraHandler才能在/metrics暴露指标,否则 Prometheus 抓不到 -
ctrl.NewControllerManagedBy(mgr).For(&MyDatabase{}).Owns(&appsv1.Deployment{})这句决定 Operator 能“拥有”哪些子资源——漏掉Owns,Deployment 删除后就不会触发 Reconcile - 日志别用
fmt.Println,统一走log.FromContext(ctx),否则在 kubectl logs 里看不到结构化字段
Reconcile 函数里怎么安全地创建/更新子资源
不能假设子资源一定不存在,也不能每次 Reconcile 都删了重建。正确做法是:先 Get,存在就 Update(带 ResourceVersion),不存在才 Create。controller-runtime 提供了 Patch 和 Controllerutil.SetControllerReference 来简化。
小型企业入门套件(The Small Business Starter Kit)提供了一个商业宣传网站的完整演示,他适合中小型企业。使用他创建的网站支持自定义模板,具有先进的功能,包括:内容和数据管理的SQL和XML数据源整合。该源码包含C#和VB两个版本,只有前台部分源码,微软官方截止到51aspx发布源码时还没有提供后台代码。小型企业网站入门套件的关键页面包括:产品分类显示新闻发布显示商户认证
- 更新 Deployment 时,如果只改
spec.replicas却没保留spec.template.spec.containers[0].image,会导致字段被清空——因为 client-go 默认用 Strategic Merge Patch,但你的 struct tag 没配patchStrategy就会降级成 JSON Merge,覆盖整块 - 不要用
DeepEqual判断是否需要更新,开销大且易错;改用controllerutil.ContainsFinalizer或比对关键字段(如obj.Spec.Version) - Finalizer 必须在 CR 创建时加,在删除逻辑里清理,否则 CR 卡在
Terminating状态不消失
本地调试 Operator 为什么总是连不上集群
常见原因是 kubeconfig 权限或上下文配置不对。Operator 启动时默认读 $HOME/.kube/config,但如果你用 kubectx 切过 context,而 current-context 指向 minikube 或 kind,却忘了启动对应集群,就会卡在 failed to get Kubernetes server version。
立即学习“go语言免费学习笔记(深入)”;
- 用
kubectl config view --minify确认当前 context 的cluster和user名字是否真实存在 - 在非 default namespace 部署 Operator 时,RBAC 的
ServiceAccount必须绑定到对应 namespace,否则watch MyDatabase会 403 - 本地跑
make run时,如果 Operator 要访问其他 namespace 的 Secret,ClusterRole 必须明确允许get secreton<em>/</em>,不能只写default/*
CRD 的 validation schema 写错一个字段,整个 CR 就无法创建,但错误信息藏在 kubectl explain mydatabase 或 apiserver 日志里,不容易发现。真要调,先看 kubectl get crd mydatabases.database.example.com -o yaml 里的 spec.validation.openAPIV3Schema 是否合法。









