关于 kubernetes-operator
这项技能面向设计 CRD 或维护控制器的团队,用于构建和审查 Kubernetes Operator。它结合三个 Python 检查工具,以及 CRD、协调循环和框架选择指南。
主要功能
- 01CRD YAML 验证
- 02Go 协调函数检查
- 03Operator 能力等级审计
- 04CRD 与协调设计指南
- 05框架选择指南
适用场景
- 01实现前检查 CRD
- 02审查控制器协调逻辑
- 03评估现有 Operator
- 04选择 Operator 框架
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ alirezarezvani/ claude-skills --skill kubernetes-operator安装后在 Claude Code 中输入/kubernetes-operator确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
assets/crd_template.yamlreconcile_skeleton.goreferences/crd_design.mdoperator_pattern.mdreconcile_loop.mdtooling_landscape.mdscripts/crd_validator.pyoperator_capability_audit.pyreconcile_lint.py详细介绍
Kubernetes Operator
构建能够正确协调的 Operator。大多数 Operator 故障并非 Kubernetes 的问题,而是协调循环的问题:缺少终结器、阻塞调用、瞬时错误时不重新排队、状态漂移、RBAC 授权过度。此技能可在问题进入集群前,以确定性方式发现这些问题。
适用场景
- 构建新的 Kubernetes Operator(用于 CRD 的控制器)
- 检查现有 Operator 是否存在能力级别方面的缺口
- 审计 CRD 规范中的状态、条件和终结器是否正确
- 选择框架(controller-runtime / kubebuilder / operator-sdk / metacontroller / KOPF)
- 设计自定义资源的 API
- 加固 RBAC、领导者选举或 Webhook 验证
不适用场景
- 普通 Helm chart 打包 → 使用
helm-chart-builder - 标准 kubectl 操作 / 蓝绿部署 → 使用
senior-devops - 通用 k8s 安全状况 → 使用
cloud-security - “我想运行一个工作负载”——这应该使用 Deployment / Job,而不是 Operator
核心原则:Operator 是协调循环,而不是脚本
observe(actual) → desired = read(spec) → diff(actual, desired) → act → update(status)
↓
requeue / done
出现故障的 Operator 通常存在以下问题:
- 将协调视为命令式操作(先做这个,再做那个,接着做那个),而不是声明式操作(以幂等方式使实际状态等于期望状态)
- 瞬时故障时不重新排队
- 不使用终结器,导致资源成为孤儿
- 修改 spec,而不是 status
- 不使用 status 子资源(status 更新会触发 spec 协调 → 循环)
- 在协调过程中阻塞(长时间 HTTP 调用、锁)
- 忘记进行领导者选举 → 多副本部署时出现脑裂
以下 3 个工具可发现上述问题。
快速开始
SKILL=engineering/kubernetes-operator/skills/kubernetes-operator
# Validate a CRD design
python "$SKILL/scripts/crd_validator.py" --crd config/crd/myapp.yaml
# Lint a Go reconcile function
python "$SKILL/scripts/reconcile_lint.py" --controller controllers/myapp_controller.go
# Score against OperatorHub Capability Levels (1-5)
python "$SKILL/scripts/operator_capability_audit.py" --operator-dir .
3 个 Python 工具
全部仅依赖标准库。使用 --help 运行。
crd_validator.py
根据 Operator 模式最佳实践验证 CRD YAML。
python scripts/crd_validator.py --crd config/crd/myapp.yaml
python scripts/crd_validator.py --crd config/crd/ --format json
检查项:
- 设置了
spec.versions[*].subresources.status(status 子资源) spec.scope为Namespaced(而非Cluster),除非有明确的理由- 定义了 Singular 和 listKind
spec.versions[*].schema.openAPIV3Schema包含类型定义(顶层没有x-kubernetes-preserve-unknown-fields: true)- 某个版本标记为
served: true且storage: true - schema 中包含 Conditions 数组(允许使用
metav1.Conditions) - 打印列包含
Age和Status/Phase
reconcile_lint.py
检查 Go 控制器的协调函数是否存在反模式。
python scripts/reconcile_lint.py --controller controllers/myapp_controller.go
检查项(基于正则表达式的启发式规则):
- 返回值为
(ctrl.Result, error)形式 - 错误会触发非零重新排队(
return ctrl.Result{Requeue: true}, err) - 标记对 spec 对象调用
client.Update()的情况(控制器应只更新 status) - 标记在协调过程中调用
time.Sleep的情况(应使用RequeueAfter) - 标记未提供上下文取消的 HTTP 调用
- 添加终结器后缺少
defer - CRD 中存在条件时,没有调用
IsConditionTrue/SetCondition - 协调函数超过 80 行(应提取子程序)
operator_capability_audit.py
根据 OperatorHub 的 5 个能力级别评估 Operator。
python scripts/operator_capability_audit.py --operator-dir .
级别:
- L1 — 基本安装: 已定义 CRD,控制器可部署该资源
- L2 — 无缝升级: PDB、转换 Webhook、版本偏差策略
- L3 — 完整生命周期: 备份、恢复、故障恢复
- L4 — 深度洞察: 指标端点、Prometheus 规则、告警
- L5 — 自动驾驶: 自动扩缩容、自动调优、异常检测
报告当前级别,并提供提升一个级别的具体后续步骤。
工具生态
根据语言和复杂度选择框架。请参阅 references/tooling_landscape.md。
| 框架 | 语言 | 最适合 | 维护情况 |
|---|---|---|---|
| controller-runtime | Go | 生产级、底层控制 | 活跃(sig-api-machinery) |
| kubebuilder | Go | 标准脚手架、约定明确 | 活跃(Kubernetes SIGs) |
| operator-sdk | Go / Helm / Ansible | OpenShift / 混合范式团队 | 活跃(Red Hat) |
| metacontroller | 任意(基于 webhook) | 多语言团队、不想使用 Go | 活跃度较低 |
| KOPF | Python | Python 团队、异步优先 | 活跃(社区) |
| java-operator-sdk | Java | JVM 团队 | 活跃(Red Hat / Java SIG) |
决策规则:
- 新建 Operator + 使用 Go 的团队 → kubebuilder
- 新建 Operator + 使用 Python 的团队 → KOPF
- 新建 Operator + 无法选择语言 → metacontroller
- 目标平台为 OpenShift → operator-sdk
CRD 设计原则
完整详情请参阅 references/crd_design.md。简要规则:
- status 是控制器对实际状态的认知依据。 Spec 表示用户的期望;status 表示控制器观察到的状态。
- 使用 status 子资源。 否则,status 更新会重新触发 reconcile(形成循环)。
- 使用 Conditions。
Ready、Reconciling、Degraded。每项都包含原因和消息。 - 添加 finalizers。 没有 finalizers 时,删除操作可能与控制器发生竞态,并遗留外部资源。
- 从第 1 天起为 CRD 进行版本管理。
v1alpha1→v1beta1→v1。规划转换 webhook。 - 通过 OpenAPI v3 schema 进行验证。 对于应在准入阶段失败的验证,不要依赖控制器来完成。
- 为
kubectl get使用additionalPrinterColumns。 至少显示Age、Phase、Ready。 - 除非 CRD 管理的是集群范围的资源,否则应将 CRD 设为命名空间级别。
Reconcile 循环原则
完整详情请参阅 references/reconcile_loop.md。简要规则:
- 幂等。 对相同状态执行两次 reconcile → 结果相同,副作用为零。
- 读取一次,做出决策,然后执行。 不要在 reconcile 期间反复观察实际状态。
- 更新 status,而非 spec。 Spec 属于用户。
- 返回会触发重新入队的错误。 对于已知的临时情况,使用
ctrl.Result{RequeueAfter: ...}。 - 绝不阻塞。 不要使用
time.Sleep。发起耗时较长的 HTTP 调用时必须传入 context。 - 使用缓存。 通过控制器的缓存客户端读取;只有在有明确原因时才绕过缓存。
- 运行超过 1 个副本时启用 Leader 选举。 否则,启用单副本模式。
- 设置 OwnerReferences。 级联删除是 Operator 模式自带的优势。
工作流
工作流 1:搭建新的 Operator(Go + kubebuilder)
1. Pick a Group/Version/Kind: e.g., apps.example.com/v1alpha1, kind=MyApp
2. kubebuilder init --domain example.com --repo github.com/org/myapp-operator
3. kubebuilder create api --group apps --version v1alpha1 --kind MyApp
4. Run crd_validator.py on config/crd/bases/apps.example.com_myapps.yaml
→ Fix every WARN before writing controller code
5. Implement the reconcile function (Karpathy principle 2: simplest correct version first)
6. Run reconcile_lint.py on controllers/myapp_controller.go
7. Run operator_capability_audit.py --operator-dir . — confirm L1
8. Test in a kind cluster: kubectl apply -f config/samples/
9. Add status conditions; aim for L2 in the same PR
工作流 2:审查现有 Operator
1. Run operator_capability_audit.py --operator-dir <path>
2. Run crd_validator.py --crd config/crd/
3. Run reconcile_lint.py --controller controllers/
4. Triage findings:
- FAIL → block release; fix before next deploy
- WARN → file an issue; fix in next 30 days
5. Document current capability level in README; commit
6. Plan one capability level advancement per quarter
工作流 3:选择框架
1. Identify primary language constraint (team skill)
2. Identify deployment target (vanilla k8s vs OpenShift)
3. Identify operator complexity (single CRD vs multi-CRD vs cluster-wide)
4. Cross-reference with references/tooling_landscape.md
5. Build a 1-week proof-of-concept before committing
参考资料
references/operator_pattern.md— Operator 是什么,以及何时使用、何时选择替代方案references/crd_design.md— CRD 设计原则、版本管理、转换 webhookreferences/reconcile_loop.md— reconcile 模式、错误处理、幂等性references/tooling_landscape.md— 框架比较 + 决策树
斜杠命令
/operator-audit — 对 Operator 仓库运行全部 3 个工具,并生成 Markdown 报告。
资源模板
assets/crd_template.yaml— 包含 status 子资源、conditions、finalizer 提示和打印列的 CRDassets/reconcile_skeleton.go— Go 控制器 reconcile 函数,包含幂等性、conditions、finalizers 和重新入队模式
反模式
- 在 reconcile 中使用
time.Sleep(30 * time.Second)— 阻塞其他 reconcile。请使用RequeueAfter。 - 使用
r.Client.Update(ctx, obj)设置状态 — 请改用r.Status().Update(ctx, obj)。 - 未启用 Leader Election + 2 个或更多副本 — 脑裂。
- 没有 finalizer — 删除时外部资源会成为孤立资源。
- CRD 没有 status 子资源 — 状态更新会触发 spec reconcile(导致无限循环)。
- Reconcile 函数超过 200 行 — 按条件提取
reconcileXxx子例程。 - 在 spec 根节点设置
x-kubernetes-preserve-unknown-fields: true— 这会使验证失效。 - 命令式 reconcile — “如果正在创建,则执行 A;如果正在更新,则执行 B;如果正在删除,则执行 C”。这种做法不对。Reconcile = 使实际状态与期望状态一致,不管我们是如何到达当前状态的。
可验证的成功标准
使用此技能的团队应达到以下目标:
- 100% 的新 CRD 在合并前通过
crd_validator.py - 所有 reconcile 函数通过
reconcile_lint.py严格模式检查 - Operator 在公开发布前达到 OperatorHub Capability Level 3(Full Lifecycle)
- 修复 reconcile Bug 的平均耗时:<1 天(生产环境中没有无限循环)
评论
支持 Markdown