Open-Source Wikis

/

Kubernetes

/

Components

/

Controller framework

kubernetes/kubernetes

Controller framework

The library code that lets every controller in this repo (and in the wider ecosystem) follow the same shape: informer, workqueue, sync handler.

Informers and the cache

Informers live in staging/src/k8s.io/client-go/tools/cache/. The flow:

graph LR
    APIs[kube-apiserver] -->|LIST + WATCH| Reflector
    Reflector -->|Add/Update/Delete| DeltaFIFO
    DeltaFIFO --> Indexer[(Local index)]
    Indexer --> Lister[Typed Lister]
    Indexer -->|event| Handlers[Resource event handlers]
  • Reflectorcache.Reflector runs the LIST+WATCH against the API server.
  • DeltaFIFO — preserves event order; coalesces redundant updates.
  • Indexercache.Indexer is a thread-safe map keyed by namespace/name, with secondary indexes (by label, by selector, by IP, …).
  • Typed listercorev1listers.PodLister (and friends) is a thin generated wrapper that returns typed objects from the indexer.
  • Event handlers — controllers register cache.ResourceEventHandlerFuncs to react to events.

A shared informer factory (informers.SharedInformerFactory) is created once per binary. Controllers ask the factory for the informer they need; the factory dedupes so each (group, resource) only does one watch against the apiserver.

Workqueues

staging/src/k8s.io/client-go/util/workqueue provides three queue flavours:

  • Interface — basic FIFO with deduping.
  • DelayingInterface — adds AddAfter(item, delay).
  • RateLimitingInterface — adds AddRateLimited(item) with exponential backoff per item.

Every controller uses a RateLimitingInterface. The default rate limiter is BucketRateLimiter plus ItemExponentialFailureRateLimiter (start at 5ms, cap at 1000s).

OwnerReferences and adoption

Every Pod created by a Deployment carries an OwnerReference pointing to its ReplicaSet. The ReplicaSet has an OwnerReference pointing to the Deployment. The garbage collector traverses these to delete dependents when the parent goes away.

The controller_ref_manager.go helpers turn this into a predictable pattern:

  • Claim — find children that match my selector and either adopt them (set OwnerReference) or release them (remove OwnerReference) if the selector no longer matches.
  • Adopt — only happens if the child has no controlling OwnerRef yet.
  • Release — only happens if I currently own them and I shouldn't anymore.

pkg/controller/controller_ref_manager.go has the canonical BaseControllerRefManager, plus typed wrappers PodControllerRefManager, ReplicaSetControllerRefManager, etc.

Expectations

The "expectations" pattern in pkg/controller/controller_utils.go solves the race "I just created 3 pods, but the informer hasn't seen them yet, so my next sync sees 0 owned pods and creates 3 more".

The flow:

  1. Before creating N children, call expectations.ExpectCreations(key, N).
  2. After the create call returns, do nothing — the informer will eventually see the new objects.
  3. On informer add events, call expectations.CreationObserved(key) to decrement the expectation.
  4. The sync handler skips work while expectations are still outstanding (expectations.SatisfiedExpectations(key)).

The same pattern works for deletions.

Leader election

staging/src/k8s.io/client-go/tools/leaderelection/ implements lease-based leader election. The kube-controller-manager creates a Lease in kube-system and renews it. Only the lease holder runs the controllers; on lease loss, the process exits and the new leader takes over.

Metrics and tracing

  • Metrics: k8s.io/component-base/metrics. The boilerplate metric for every controller is <controller>_reconcile_duration_seconds.
  • Logging: klog with structured key-value pairs. Every controller's Run logs Starting <name> controller / Shutting down <name> controller.
  • Tracing: staging/src/k8s.io/component-base/tracing (OpenTelemetry-backed). Most controllers don't emit spans yet; the apiserver does.

Key source files

File Purpose
staging/src/k8s.io/client-go/tools/cache/shared_informer.go The informer base class
staging/src/k8s.io/client-go/tools/cache/reflector.go LIST+WATCH loop
staging/src/k8s.io/client-go/tools/cache/delta_fifo.go Event ordering and coalescing
staging/src/k8s.io/client-go/util/workqueue/rate_limiting_queue.go The standard rate-limited queue
pkg/controller/controller_utils.go PodControl, expectations, event recorder helpers
pkg/controller/controller_ref_manager.go OwnerRef adopt/release
staging/src/k8s.io/client-go/tools/leaderelection/leaderelection.go Leader election driver

Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.

Controller framework – Kubernetes wiki | Factory