Skip to content

// Build K8s operators with Kubebuilder — CRDs, controllers, reconciliation, webhooks, RBAC.

Kubernetes Operator Builder

skill --stat
  • last update

    Jun 2, 2026

  • license

    MITv1.0.0

  • format

    SKILL.md

quickstart.sh
3 steps
  1. 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
  2. Invoke

    // Inside Claude Code, type the skill name as a slash command

    > /kubernetes-operator-builder wire up a GitHub Actions deploy
  3. 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
kubernetes-operator-builder/
references
SKILL.md
readonly
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/README.md
6 sections

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 api layout instead of hand-rolling one.
  • You have a CRD but your Reconcile loop 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

bash
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
go
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 .Status and calling r.Update() silently drops it unless the status subresource is enabled and you use r.Status().Update().
  • Never trigger reconciles on a fixed timer when you can use .Owns() and watches — RequeueAfter is for genuine backoff/polling, not change detection.
  • Make reconcilation idempotent and conflict-tolerant: a 409 Conflict on update is normal; return the error and let the queue retry rather than looping in place.
  • Re-run make manifests after editing RBAC markers, or your deployed ClusterRole won'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/

Reviews

// No reviews yet. Be the first.
Loading review form…

$ ls related/

explore all →