Skip to content

controller-runtime

controller-runtime is a subproject of kubebuilder which provides a lot of useful tools that help develop Kubernetes Operator.

Version: v0.25.1, with client-go v0.37.1, as pinned in go.mod.

Overview

  1. Create a Manager. Internally, Cluster constructs the shared Cache, Client, Scheme, RESTMapper, and uncached APIReader.
  2. Create Reconcilers with explicit dependencies such as Client: mgr.GetClient(); see Reconciler.
  3. Configure each controller with Builder: For chooses the reconciled type, Owns maps child events to owners, and Watches supplies custom event mappings.
  4. Builder.doController constructs a Controller and registers it with Manager.Add. Controllers require leadership by default; those opting out run in Others.
  5. Builder.doWatch constructs Kind sources using Cache, handler, and predicates, then calls Controller.Watch to register them.
  6. Start Manager. It starts HTTP servers, webhooks, caches, non-leader work, warmup work, and leader-gated controllers in the appropriate order.
  7. Kind.Start obtains an informer from Cache and registers the handler. Controller waits for source synchronization before running workers.
  8. Informer events pass predicates, handlers enqueue keys, and Controller workers call Reconcile. Reconcile reads current state through Client and writes desired changes to the API server.

The component pages and diagrams retain construction details, interfaces, usage examples, and call relationships for the pinned version.

For more details, you can check the architecture in book.kubebuilder.io:

List of components:

  1. Manager: Package manager is required to create Controllers and provides shared dependencies such as clients, caches, schemes, etc.
  2. Controller: Package controller provides types and functions for building Controllers. Managed controllers start through Manager.Start; unmanaged constructors require the caller to manage lifecycle.
    1. Event
    2. Builder
    3. Source
    4. Handler
    5. Predicate
  3. Client: Package client contains functionality for interacting with Kubernetes API servers.

    1. cache-backed client: Get/List use the configured cache unless bypassed; writes use the API server. This replaces the older delegatingClient implementation.
  4. Cache

    1. client.Reader: Cache acts as a client to objects stored in the cache.
    2. Informers: Cache loads informers and adds field indices.
  5. Scheme: Wraps apimachinery/Scheme.
  6. Webhook
  7. Envtest

Components

  1. manager
  2. reconciler
  3. log
  4. controller
  5. cluster
    1. client
    2. cache
  6. inject
  7. source
  8. builder
  9. handler

Examples

  1. example-controller
  2. envtest: integration tests with a local API server and etcd; not configured by these examples.

Validation

Run from the repository root:

go test ./contents/kubernetes-operator/...
golangci-lint run

CI runs the Go tests with coverage and golangci-lint when Go source, go.mod/go.sum, lint configuration, or the Go workflow changes. Packages marked [no test files] are compiled but have no dedicated behavioral tests. Regression tests cover informer object ownership/tombstones, ReplicaSet reconciliation, and webhook mutation. Cluster-dependent walkthroughs require a kubeconfig and the described RBAC/CRDs; unit tests do not validate live watch delivery or leader election.

Memo

  1. The default logger uses epoch timestamps unless configured otherwise.
  2. Sources, handlers, and predicates receive their dependencies explicitly. For example, construct a Kind source with source.Kind(cache, object, handler); no dependency injection is required.
  3. Metrics and webhook servers use dedicated options and server interfaces. See Manager and Webhook for the current configuration paths.