跳转到内容

Operator SDK — 写 K8s Operator 的"豪华套餐"版脚手架

是什么

Operator SDK 是 kubebuilder 之上”再加一层”的脚手架——它让你用 Go、Ansible 或 Helm 三种姿势写 Kubernetes Operator,并自带打包、测试、上架到 OperatorHub 的全链路工具。

日常类比:

  • Kubebuilder 像”自己买零件组台式机”——只给你 Go 一种主板
  • Operator SDK 像”成品品牌机三选一”——Go 主板(性能最强)/ Ansible 一体机(运维友好)/ Helm 迷你款(已有 Helm chart 包一层即可)
Terminal window
operator-sdk init --domain example.com --plugins=ansible
operator-sdk create api --group cache --version v1 --kind Memcached

两行命令,得到一个用 Ansible playbook 写 reconcile 的 Operator——零行 Go 代码。

为什么重要

不理解 Operator SDK,下面这些事都没法解释:

  • 为什么 OperatorHub.io 上的 Operator 一键安装就能跑——背后是 SDK 出的 bundle 格式 + OLM(Operator Lifecycle Manager)
  • 为什么团队里运维同学也能写 Operator——Ansible Operator 把 reconcile 翻译成 playbook,门槛骤降
  • 为什么 Red Hat OpenShift 的 Operator 生态那么齐整——OpenShift 自带 OLM,SDK 是其默认上架通道
  • 为什么 Kubebuilder 和 SDK 看起来九成像——因为 SDK v1.0 起 Go 工作流直接 rebase 到 Kubebuilder,共享同一套 controller-runtime 底座

核心要点

Operator SDK 在 Kubebuilder 之上做了 三件加法

  1. 三种 operator 类型选一种

    • Go:底层就是 Kubebuilder,能力上限最高,能爬到 Level 5(Auto Pilot 级)
    • Ansible:用 playbook 描述”目标状态”,SDK 把它包成 reconcile 循环
    • Helm:已有 Helm chart?包一层就成 Operator,连 reconcile 函数都不用写
  2. OLM 集成:除了生成 controller,还能 make bundle 出一份”装 / 升 / 卸”元数据,OLM 会替你管多版本依赖、订阅通道、升级路径——本质上是装 Operator 的 Operator

  3. scorecard 测试:内置一套针对 CRD 行为的合规测试(资源是否带 owner ref、status 是否更新等),跑一行命令打分,比手写 e2e 省事

记住一个对照:Kubebuilder = 写 Operator 本体Operator SDK = 写 + 打包 + 上架 + 测试 全家桶

实践案例

案例 1:Helm Operator 零行 Go 代码

Terminal window
operator-sdk init --plugins=helm --domain example.com
operator-sdk create api \
--group demo --version v1 --kind Nginx \
--helm-chart=bitnami/nginx

跑完之后,集群里多了一种资源 Nginx。用户写:

apiVersion: demo.example.com/v1
kind: Nginx
metadata: { name: my-nginx }
spec:
replicaCount: 3

Operator 会把 spec 翻译成 helm values,调 helm install/upgrade。用户改 replicaCount,它自动重渲染再 upgrade。整个 Operator 你写了 0 行 Go

代价:能力封顶在 Level 1-2,做不了”主备切换""自动备份”这种深度运维。

案例 2:Ansible Operator 把 playbook 当 reconcile

roles/memcached/tasks/main.yml
- name: 确保 deployment 存在
k8s:
definition:
apiVersion: apps/v1
kind: Deployment
metadata: { name: "{{ ansible_operator_meta.name }}" }
spec:
replicas: "{{ size }}"

每次 Memcached CR 变化,SDK 启动 ansible-runner 把这个 role 跑一遍。reconcile 的”对比期望和现状”由 Ansible 的 idempotency(同样的 playbook 跑 N 次结果一样)天然保证。

适合配置型应用——Postgres / RabbitMQ / Redis 这类装上去配几下就能用的。

案例 3:OLM bundle 是怎么打出来的

Terminal window
make bundle VERSION=0.1.0
make bundle-build
make bundle-push

生成的 bundle/ 目录有:

  • manifests/ — CRD + ClusterServiceVersion(CSV,operator 的”元数据简历”)
  • metadata/annotations.yaml — 告诉 OLM 这个 bundle 属于哪个 channel

把 bundle 镜像 push 上去,加进一个 catalog index,OperatorHub 立刻能搜到。OLM 在用户集群里负责把它装出来——和应用商店装 App 是同一个心智。

踩过的坑

  1. v1.0 大版本断层:v0.x 和 v1.x 的 Go 项目结构差很多(v1 起接 Kubebuilder 套路)。老教程不能照抄——看到 pkg/apis 目录是 v0.x,看到 api/v1 才是 v1.x。

  2. Helm Operator 假装很强:演示”5 分钟做一个 Operator”看起来美好,真到生产容易撞墙——主从切换、备份恢复、滚动升级 hook 全做不到。把 Helm Operator 当第一版原型就好,复杂场景该转 Go 还得转。

  3. Ansible Operator 心智没切过来:把 reconcile 当成”事件触发的脚本”会出问题——它会被重复触发任意多次,playbook 必须真的幂等。shell: rm -rf /tmp/foo 这种就是地雷。

  4. OLM bundle 元数据极易写错replaces 字段写错版本号,整条升级路径就断;channel 拼错,订阅永远拉不到新版。先用 operator-sdk bundle validate 自检,别直接 push。

  5. scorecard 不等于 e2e:scorecard 只查”CRD 元数据合规、status 字段存在”这类结构性问题,业务正确性它不管。生产前还是要写真实 e2e

  6. owner reference 漏挂:和 Kubebuilder 同款坑——子资源没挂 owner ref,删 CR 时 Deployment / Service 不会被级联回收,集群里堆”幽灵资源”。

  7. finalizer 在 Ansible/Helm 模式里更隐蔽:Go 模式你能直接加 finalizers slice;Ansible/Helm 模式得通过 CR 注解或 hook 触发——文档不显眼,新人常漏。

适用 vs 不适用场景

适用

  • 团队里 Go 同学少,但 Ansible / Helm 经验丰富 → SDK 让运维同学也能产出 Operator
  • 要把 Operator 上架 OperatorHub / OpenShift Operator Catalog → SDK 是官方通道
  • 同一个产品多版本演进 + 升级路径管理 → OLM 是为这个场景生的
  • 想用 scorecard 跑基础合规测试当 CI 门禁

不适用

  • 只在内部集群部署、不打算上架 → Kubebuilder 更轻,少一层抽象
  • 写 admission webhook、不需要 CRD → controller-runtime 直接起 webhook server
  • 极度定制化的 Operator(复杂状态机、自研多副本协议)→ 直接用 Kubebuilder + controller-runtime,SDK 的额外封装反而碍事
  • 不在 K8s 生态 → 完全不适用

学到什么

  1. 抽象层数 vs 灵活度永远是反比——Helm Operator 写得最快、能力最低;Go Operator 写得最慢、上限最高。先按现状选,别贪图”以后可能要”

  2. 打包 / 上架 / 升级也是一等公民——Operator 不是写出来跑通就完,怎么让别人装上、怎么平滑升级才是长期成本所在。OLM 这层是 SDK 区别于 Kubebuilder 的真正价值。

  3. 官方脚手架的”上层封装”策略——Operator SDK 不另起炉灶,而是 v1.0 起把 Go 工作流让位给 Kubebuilder,自己专注”打包 + 测试 + 上架”。好脚手架知道何时不发明轮子

  4. Ansible / Helm Operator 是”用熟悉工具填新格子”的范例——把 K8s reconcile 这个新概念,套进运维同学已经会的 playbook / chart 心智里,让门槛陡降一个量级

延伸阅读

关联

  • kubebuilder —— SDK 的 Go 工作流直接 rebase 到它,共享 controller-runtime
  • kubernetes —— Operator 跑在 K8s 上、扩展 K8s 自身
  • ansible —— Ansible Operator 把 playbook 当 reconcile 循环
  • docker —— bundle 和 operator 本体都是容器镜像
  • terraform —— 同样”声明状态 + 自动收敛”,作用域不同

反向链接

  • ansible —— Ansible — 无 agent 配置管理
  • kubebuilder —— Kubebuilder — 写 K8s Operator 的官方脚手架
  • kubernetes —— Kubernetes — 容器编排平台
  • rook —— Rook — 把 Ceph 装进 K8s 的 CRD 里