mcpField
K
kubernetes-operator

kubernetes-operator

github.com/alirezarezvani云与 DevOps28.9k505 次安装2 天前更新
代码仓库

关于 kubernetes-operator

这项技能面向设计 CRD 或维护控制器的团队,用于构建和审查 Kubernetes Operator。它结合三个 Python 检查工具,以及 CRD、协调循环和框架选择指南。

主要功能

  1. 01CRD YAML 验证
  2. 02Go 协调函数检查
  3. 03Operator 能力等级审计
  4. 04CRD 与协调设计指南
  5. 05框架选择指南

适用场景

  1. 01实现前检查 CRD
  2. 02审查控制器协调逻辑
  3. 03评估现有 Operator
  4. 04选择 Operator 框架

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/alirezarezvani/claude-skills --skill kubernetes-operator

安装后在 Claude Code 中输入/kubernetes-operator确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

assets/
crd_template.yaml
reconcile_skeleton.go
references/
crd_design.md
operator_pattern.md
reconcile_loop.md
tooling_landscape.md
scripts/
crd_validator.py
operator_capability_audit.py
reconcile_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 通常存在以下问题:

  1. 将协调视为命令式操作(先做这个,再做那个,接着做那个),而不是声明式操作(以幂等方式使实际状态等于期望状态)
  2. 瞬时故障时不重新排队
  3. 不使用终结器,导致资源成为孤儿
  4. 修改 spec,而不是 status
  5. 不使用 status 子资源(status 更新会触发 spec 协调 → 循环)
  6. 在协调过程中阻塞(长时间 HTTP 调用、锁)
  7. 忘记进行领导者选举 → 多副本部署时出现脑裂

以下 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-runtimeGo生产级、底层控制活跃(sig-api-machinery)
kubebuilderGo标准脚手架、约定明确活跃(Kubernetes SIGs)
operator-sdkGo / Helm / AnsibleOpenShift / 混合范式团队活跃(Red Hat)
metacontroller任意(基于 webhook)多语言团队、不想使用 Go活跃度较低
KOPFPythonPython 团队、异步优先活跃(社区)
java-operator-sdkJavaJVM 团队活跃(Red Hat / Java SIG)

决策规则:

  • 新建 Operator + 使用 Go 的团队 → kubebuilder
  • 新建 Operator + 使用 Python 的团队 → KOPF
  • 新建 Operator + 无法选择语言 → metacontroller
  • 目标平台为 OpenShift → operator-sdk

CRD 设计原则

完整详情请参阅 references/crd_design.md。简要规则:

  1. status 是控制器对实际状态的认知依据。 Spec 表示用户的期望;status 表示控制器观察到的状态。
  2. 使用 status 子资源。 否则,status 更新会重新触发 reconcile(形成循环)。
  3. 使用 Conditions。 Ready、Reconciling、Degraded。每项都包含原因和消息。
  4. 添加 finalizers。 没有 finalizers 时,删除操作可能与控制器发生竞态,并遗留外部资源。
  5. 从第 1 天起为 CRD 进行版本管理。 v1alpha1 → v1beta1 → v1。规划转换 webhook。
  6. 通过 OpenAPI v3 schema 进行验证。 对于应在准入阶段失败的验证,不要依赖控制器来完成。
  7. 为 kubectl get 使用 additionalPrinterColumns。 至少显示 Age、Phase、Ready。
  8. 除非 CRD 管理的是集群范围的资源,否则应将 CRD 设为命名空间级别。

Reconcile 循环原则

完整详情请参阅 references/reconcile_loop.md。简要规则:

  1. 幂等。 对相同状态执行两次 reconcile → 结果相同,副作用为零。
  2. 读取一次,做出决策,然后执行。 不要在 reconcile 期间反复观察实际状态。
  3. 更新 status,而非 spec。 Spec 属于用户。
  4. 返回会触发重新入队的错误。 对于已知的临时情况,使用 ctrl.Result{RequeueAfter: ...}。
  5. 绝不阻塞。 不要使用 time.Sleep。发起耗时较长的 HTTP 调用时必须传入 context。
  6. 使用缓存。 通过控制器的缓存客户端读取;只有在有明确原因时才绕过缓存。
  7. 运行超过 1 个副本时启用 Leader 选举。 否则,启用单副本模式。
  8. 设置 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 设计原则、版本管理、转换 webhook
  • references/reconcile_loop.md — reconcile 模式、错误处理、幂等性
  • references/tooling_landscape.md — 框架比较 + 决策树

斜杠命令

/operator-audit — 对 Operator 仓库运行全部 3 个工具,并生成 Markdown 报告。

资源模板

  • assets/crd_template.yaml — 包含 status 子资源、conditions、finalizer 提示和打印列的 CRD
  • assets/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