关于 ark-controller-development
面向在 `ark/` 中开发 Ark Kubernetes operator 的技能,涵盖 CRD 与 Helm chart 同步、Go 实现规范,以及从测试到端到端检查的验证步骤。
主要功能
- 01CRD 生成与 Helm chart 同步
- 02Go 实现及依赖使用指引
- 03Lint、构建与测试流程
- 04Controller 和 webhook 测试指引
- 05提交 PR 前的验证清单
适用场景
- 01添加或修改 CRD 字段
- 02解决 CRD 同步错误
- 03验证 Controller 或 webhook 改动
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ mckinsey/ agents-at-scale-ark --skill ark-controller-development安装后在 Claude Code 中输入/ark-controller-development确认已加载。
详细介绍
Ark Controller 开发
在 ark/ 中开发 Ark Kubernetes operator 的指南。
何时使用此技能
- 修改 Go 类型定义(
api/v1alpha1/*_types.go) - 修复 CRD/Helm chart 同步错误
- 添加新的 CRD 字段或资源
CRD 生成流程
api/v1alpha1/*_types.go # Go types with markers
↓
make manifests # Generates CRDs and syncs to Helm chart
↓
config/crd/bases/*.yaml # Source CRDs (auto-generated)
dist/chart/templates/crd/ # Helm chart CRDs (auto-synced)
make manifests 会自动将源 CRD 同步到 Helm chart,同时保留模板化的标头。
修复“CRD 未同步”错误
当 make build 因 CRD 验证错误而失败时:
cd ark
make manifests
make build
关键目录
| 目录 | 用途 |
|---|---|
api/v1alpha1/ | Go 类型定义 |
config/crd/bases/ | 自动生成的源 CRD |
dist/chart/templates/crd/ | Helm chart CRD(自动同步) |
internal/controller/ | 协调逻辑 |
internal/webhook/ | 准入 Webhook |
internal/genai/ | AI/ML 执行逻辑 |
常见任务
修改类型或注释后
Go 类型注释会成为 CRD 字段说明:
cd ark
make manifests
make build
修改任意 Go 代码后
make lint-fix # Format and auto-fix what the linter can fix
make lint # Fail fast on issues CI will reject — MANDATORY
make build # Build and validate
make test # Run unit + envtest suites
打开 PR 前
针对运行中的集群运行 chainsaw e2e 套件——单元测试和 envtest 不会覆盖完整的 apply → reconcile → status 循环。优先使用 确定性的 mock-llm 套件;只有在变更明确涉及该路径时才运行 由 LLM 驱动的测试(可节省成本,并避免真实 LLM 提供商造成的 不稳定问题)。
# Deterministic suite (default)
(cd tests && chainsaw test --selector '!llm')
# LLM suite — only when your change needs it
(cd tests && chainsaw test --selector 'llm')
关于模式和反模式(例如,优先使用 chainsaw assert 而不是 shell grep;优先使用 wait 而不是轮询),请参阅 chainsaw 技能。
make lint 会运行 CI 强制执行的相同 golangci-lint 规则。本地推送前运行它是必须的——PR 检查失败的代价高于 lint 所需的一分钟。
利用现有代码——不要重复造轮子
在编写解析器、结构体、辅助函数、重试循环、URL 构造器或 任何工具函数之前,先检查以下位置是否已有实现:
- Go 标准库。
go.mod中的直接或传递依赖(controller-runtime、apimachinery、你所实现规范对应的 SDK、golang.org/x/...)。
手写代码会逐渐偏离、重复测试,并成为维护负担。委托给库的简短适配器几乎总是优于重新实现。
经验法则:如果你要写的内容与现有规范、文件格式、标头语法或常见基础设施模式相似,就已经有人实现过了。先搜索:go doc <import-path>、ls $(go env GOMODCACHE)/<dep>。
通过别名重新导出库类型(type X = lib.X),而不是定义字段相同的平行结构体。
示例
项目最初手动实现了 WWW-Authenticate 解析器、RFC 9728
结构体、RFC 8414 结构体和 HTTP 获取器——约 150 行代码。go-sdk
已经在 oauthex 中提供了这些功能:
// Bad — 40-line parser, partial struct, duplicated HTTP wrapper.
func parseHeader(h string) (string, bool) { /* ... */ }
type Metadata struct { /* partial mirror of RFC */ }
func fetch(ctx, url) (*Metadata, error) { /* 30 lines */ }
// Good — thin adapter, full spec support, ~10 LOC.
import "github.com/modelcontextprotocol/go-sdk/oauthex"
type Metadata = oauthex.ProtectedResourceMetadata
func Fetch(ctx context.Context, metaURL, resourceURL string, timeout time.Duration) (*Metadata, error) {
return oauthex.GetProtectedResourceMetadata(ctx, metaURL, resourceURL, &http.Client{Timeout: timeout})
}
同样的原则也适用于重试/退避(k8s.io/apimachinery/pkg/util/wait)、
JSON patch(strategicpatch)、条件更新
(meta.SetStatusCondition)、HTTP 客户端、工作队列——无论你要处理什么,都应先检查现有依赖。
避免魔法数字——复用可配置值
不要内联数字时长、重试次数或缓冲区大小。优先级如下:
- 用户可配置的 spec 字段——如果资源已有
spec.timeout、spec.pollInterval、spec.retries,就使用它。一次 operator 配置应控制同一协调过程中的所有相关代码路径。 - 包级 const,并用名称说明该数字的用途。
- 测试局部 const(例如
const testTimeout = 5 * time.Second)—— 测试中绝不内联字面值。
示例
// Bad — parallel constant invented out of thin air.
const discoveryTimeout = 10 * time.Second
client := &http.Client{Timeout: discoveryTimeout}
// Good — plumb the MCPServer's spec.timeout; single source of truth.
func Fetch(ctx, url string, timeout time.Duration) ...
timeout := parseTimeout(mcpServer.Spec.Timeout)
测试——不可省略
每项代码变更都必须附带测试。修改 ark/internal/ 的 PR 如果没有 _test.go,就不完整。适用于控制器分支、Webhook、辅助函数——不只是公共 API。
| 变更 | 位置 | 测试框架 |
|---|---|---|
internal/<pkg>/ 中的辅助函数 / 解析器 | <file>_test.go | 标准库 testing,表驱动 |
| 控制器分支 | internal/controller/<scenario>_test.go | Ginkgo + envtest |
| Webhook 规则 | internal/webhook/v1/<resource>_webhook_test.go | Ginkgo |
| HTTP 逻辑 | 同一包中的 httptest.NewServer | 标准库 testing |
控制器分支必须覆盖:
- 正常路径 → 预期状态和条件。
- 每种失败模式 → 独立且稳定的条件原因(不要匹配字符串)。
- 幂等性 → 再次协调不会发出重复事件或更新
lastTransitionTime。 - 回归保护 → 不影响现有分支。
完成检查清单
在说“完成”之前:
-
make manifests无差异(如果类型有变更) -
make lint通过——遵循 CI 强制执行的相同规则 -
make build通过 -
make test通过——粘贴或引用输出 - Chainsaw 确定性测试套件(
chainsaw test --selector '!llm')通过;仅在变更需要时运行 LLM 套件 - 每个新增函数 / 分支都有对应的
_test.go - 重新生成并提交 Helm chart CRD
- 如果 CRD 有变更,重新生成 OpenAPI / Python SDK / TypeScript SDK
- 重新验证运行中的 Pod——devspace 会同步源代码,但只有重启容器才能加载新的 Go 二进制文件;任何协调路径变更后,都要查看控制器日志