Controllers and Informer Pattern

Motivation:

Implementing controllers and leveraging the informer pattern is a common approach for managing Kubernetes resources and responding to changes. This pattern provides a robust and efficient way to handle resource updates, ensuring your application stays in sync with the cluster state.

Key Components:

  • Informers: Provide a mechanism to keep a local cache of Kubernetes resources synchronized with the API server. They listen for changes, update the cache, and trigger event handlers. https://godoc.org/k8s.io/client-go/tools/cache#NewInformer
  • Controllers: Act as the business logic responsible for reacting to changes in the cache. They receive events from informers and execute actions based on specific criteria.
  • Work Queues: Used to process events asynchronously and avoid blocking the informer’s event loop.
  • SharedInformerFactory: Provides a convenient way to create and manage shared informers across multiple controllers. This reduces resource consumption and optimizes communication with the API server.

Examples:

  • Work Queues: This example demonstrates how to write a controller that utilizes work queues to manage resources. It showcases the integration of a work queue with a cache to create a complete controller and how to synchronize it on startup. tree/master/examples/workqueue
  • Custom Resource Definitions (CRD): Provides examples for registering and managing custom resources. The examples include creating, updating, and querying custom resources, as well as developing controllers to handle resource changes. tree/master/examples
  • Leader Election: Demonstrates the use of the leader election package for implementing HA controllers. This example shows how to elect a leader from multiple instances running the controller and ensures that only one instance performs critical operations. tree/master/examples/leader-election
  • Fake Client: This example illustrates how to use a fake client with SharedInformerFactory for testing purposes. It covers creating a fake client, setting up real informers, and injecting events into those informers for simulating various scenarios. tree/master/examples/fake-client

Informers and Interfaces:

Informers in client-go provide a structured way to interact with Kubernetes resources. They offer methods like Informer() for accessing the underlying cache.

  • ControllerRevision Informer:
    • Informer() cache.SharedIndexInformer: Returns the shared informer for ControllerRevision resources.
    • Lister() appsv1.ControllerRevisionLister: Provides a list interface for ControllerRevision resources.
  • Interface: Provides a set of methods to access informers for various resource types.
    • ControllerRevisions() ControllerRevisionInformer: Returns the informer for ControllerRevision resources.
    • Deployments() DeploymentInformer: Returns the informer for Deployment resources.
    • StatefulSets() StatefulSetInformer: Returns the informer for StatefulSet resources.

Example Implementation (ControllerRevisionInformer):

// informers/apps/v1/controllerrevision.go
          package v1
          
          // ControllerRevisions.
          type ControllerRevisionInformer interface {
              Informer() cache.SharedIndexInformer
              Lister() appsv1.ControllerRevisionLister
          }
          
          type controllerRevisionInformer struct {
              factory          internalinterfaces.SharedInformerFactory
              tweakListOptions internalinterfaces.TweakListOptionsFunc
              namespace        string
          }
          
          // NewControllerRevisionInformer constructs a new informer for ControllerRevision type.
          // Always prefer using an informer factory to get a shared informer instead of getting an independent
          // one. This reduces memory footprint and number of connections to the server.
          func NewControllerRevisionInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer {
              return NewFilteredControllerRevisionInformer(client, namespace, resyncPeriod, indexers, nil)
          }
          

Key Considerations:

  • SharedInformerFactory: Using a shared informer factory ensures that multiple controllers share the same cache and connection to the API server.
  • Resync Period: The resync period defines the frequency at which the informer refreshes its cache from the API server.
  • Indexers: Used to optimize queries and ensure efficient retrieval of specific resources.
  • Namespace: The namespace for which the informer should retrieve resources.

Documentation Resources:

Top-Level Directory Explanations

applyconfigurations/ - This directory contains examples and tests for applying Kubernetes configurations using the client-go library.

dynamic/ - This directory contains code for working with dynamic resources in the Kubernetes API.

examples/ - This directory contains example usage of the client-go library.

informers/ - This directory contains code for caching Kubernetes resources using informers.

kubernetes/ - This directory contains the main package for the client-go library, which provides types and functions for interacting with the Kubernetes API.

listers/ - This directory contains interfaces and implementations for listing Kubernetes resources.

metadata/ - This directory contains code related to metadata in Kubernetes.

rest/ - This directory contains code for working with the REST API in the client-go library.

tools/ - This directory contains various tools for working with the client-go library.

util/ - This directory contains utility functions for the client-go library.