last update
Jun 2, 2026
license
MITv1.0.0
format
SKILL.md
- Install
// Downloads SKILL.md into ~/.claude/skills/kubernetes-operator-builder/
$ curl -fsSL --create-dirs -o ~/.claude/skills/kubernetes-operator-builder/SKILL.md https://claudeskil.com/skills/kubernetes-operator-builder/SKILL.md - Invoke
// Inside Claude Code, type the skill name as a slash command
> /kubernetes-operator-builder wire up a GitHub Actions deploy - Or copy this from the README
// extracted bash block
$ curl -fsSL --create-dirs -o ~/.claude/skills/kubernetes-operator-builder/SKILL.md https://claudeskil.com/skills/kubernetes-operator-builder/SKILL.md kubebuilder init --domain example.com --repo example.com/widget-operator kubebuilder create api --group apps --version v1alpha1 --kind Widget
- name:
- Kubernetes Operator Builder
- slug:
- kubernetes-operator-builder
- version:
- v1.0.0
- license:
- MIT
- author:
- @chiragthummar16
- categories:
- tags:
- #kubernetes#operator#kubebuilder#go#crd
- description:
Build K8s operators with Kubebuilder — CRDs, controllers, reconciliation, webhooks, RBAC.
README.md
Kubernetes Operator Builder
Scaffolds and fills in production-grade Kubernetes operators using Kubebuilder and the controller-runtime library. It handles the parts that are easy to get subtly wrong — reconciliation idempotency, status vs. spec separation, finalizer cleanup, and webhook wiring — so you end up with a controller that behaves correctly under retries and resyncs. Aimed at Go developers extending Kubernetes with custom resources, whether you're packaging an internal platform abstraction or shipping an operator to OperatorHub.
When to use it
- You're starting a new operator and want a correct
kubebuilder init+kubebuilder create apilayout instead of hand-rolling one. - You have a CRD but your
Reconcileloop fights itself — fixing the same object every resync, or losing status on conflict. - You need to add a mutating or validating webhook (defaulting, immutability checks) and keep the cert wiring sane.
- You're adding a finalizer to clean up external resources (cloud LBs, DB users) before the CR is deleted.
How it works
It drives the standard toolchain: kubebuilder init --domain, kubebuilder create api --group --version --kind, and make manifests generate (which runs controller-gen to emit CRD YAML, deepcopy functions, and RBAC role rules from // +kubebuilder:rbac markers). Types are annotated with // +kubebuilder:validation: and // +kubebuilder:subresource:status markers. The controller is built around ctrl.NewControllerManagedBy(mgr).For(...).Owns(...), with reconciler logic returning ctrl.Result{Requeue/RequeueAfter} and using client.IgnoreNotFound, controllerutil.SetControllerReference, and r.Status().Update() for the status subresource. Finalizers use controllerutil.AddFinalizer/RemoveFinalizer. Tests run under envtest (a real apiserver + etcd, no kubelet) with Ginkgo/Gomega.
Example
curl -fsSL --create-dirs -o ~/.claude/skills/kubernetes-operator-builder/SKILL.md https://claudeskil.com/skills/kubernetes-operator-builder/SKILL.md
kubebuilder init --domain example.com --repo example.com/widget-operator
kubebuilder create api --group apps --version v1alpha1 --kind Widget
func (r *WidgetReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
var w appsv1alpha1.Widget
if err := r.Get(ctx, req.NamespacedName, &w); err != nil {
return ctrl.Result{}, client.IgnoreNotFound(err)
}
// reconcile owned Deployment, then:
w.Status.Ready = true
return ctrl.Result{}, r.Status().Update(ctx, &w)
}
Tips & gotchas
- Always update spec and status through separate calls: mutating
.Statusand callingr.Update()silently drops it unless thestatussubresource is enabled and you user.Status().Update(). - Never trigger reconciles on a fixed timer when you can use
.Owns()and watches —RequeueAfteris for genuine backoff/polling, not change detection. - Make reconcilation idempotent and conflict-tolerant: a
409 Conflicton update is normal; return the error and let the queue retry rather than looping in place. - Re-run
make manifestsafter editing RBAC markers, or your deployedClusterRolewon't match what the controller actually does.
FAQ
Kubebuilder or Operator SDK? Operator SDK's Go path wraps Kubebuilder, so the controller-runtime patterns here apply to both. This skill targets the Kubebuilder CLI and layout directly.
Do I need a real cluster to test? No. envtest spins up a standalone apiserver and etcd, enough to test CRD validation, reconcilation, and status — but it has no scheduler or kubelet, so Pods never actually run.
Multiple CRDs in one operator? Yes — run kubebuilder create api per kind; each gets its own reconciler registered on the shared manager.
$ cat reviews/