Documentation ¶
Overview ¶
Package controllerruntime provides tools to construct Kubernetes-style controllers that manipulate both Kubernetes CRDs and aggregated/built-in Kubernetes APIs.
It defines easy helpers for the common use cases when building CRDs, built on top of customizable layers of abstraction. Common cases should be easy, and uncommon cases should be possible. In general, controller-runtime tries to guide users towards Kubernetes controller best-practices.
Getting Started ¶
The main entrypoint for controller-runtime is this root package, which contains all of the common types needed to get started building controllers:
import ( ctrl "github.com/samuelkuklis/controller-runtime" )
The examples in this package walk through a basic controller setup. The kubebuilder book (https://book.kubebuilder.io) has some more in-depth walkthroughs.
controller-runtime favors structs with sane defaults over constructors, so it's fairly common to see structs being used directly in controller-runtime.
Organization ¶
A brief-ish walkthrough of the layout of this library can be found below. Each package contains more information about how to use it.
Frequently asked questions about using controller-runtime and designing controllers can be found at https://github.com/kubernetes-sigs/controller-runtime/blob/master/FAQ.md.
Managers ¶
Every controller and webhook is ultimately run by a Manager (pkg/manager). A manager is responsible for running controllers and webhooks, and setting up common dependencies (pkg/runtime/inject), like shared caches and clients, as well as managing leader election (pkg/leaderelection). Managers are generally configured to gracefully shut down controllers on pod termination by wiring up a signal handler (pkg/manager/signals).
Controllers ¶
Controllers (pkg/controller) use events (pkg/event) to eventually trigger reconcile requests. They may be constructed manually, but are often constructed with a Builder (pkg/builder), which eases the wiring of event sources (pkg/source), like Kubernetes API object changes, to event handlers (pkg/handler), like "enqueue a reconcile request for the object owner". Predicates (pkg/predicate) can be used to filter which events actually trigger reconciles. There are pre-written utilities for the common cases, and interfaces and helpers for advanced cases.
Reconcilers ¶
Controller logic is implemented in terms of Reconcilers (pkg/reconcile). A Reconciler implements a function which takes a reconcile Request containing the name and namespace of the object to reconcile, reconciles the object, and returns a Response or an error indicating whether to requeue for a second round of processing.
Clients and Caches ¶
Reconcilers use Clients (pkg/client) to access API objects. The default client provided by the manager reads from a local shared cache (pkg/cache) and writes directly to the API server, but clients can be constructed that only talk to the API server, without a cache. The Cache will auto-populate with watched objects, as well as when other structured objects are requested. The default split client does not promise to invalidate the cache during writes (nor does it promise sequential create/get coherence), and code should not assume a get immediately following a create/update will return the updated resource. Caches may also have indexes, which can be created via a FieldIndexer (pkg/client) obtained from the manager. Indexes can used to quickly and easily look up all objects with certain fields set. Reconcilers may retrieve event recorders (pkg/recorder) to emit events using the manager.
Schemes ¶
Clients, Caches, and many other things in Kubernetes use Schemes (pkg/scheme) to associate Go types to Kubernetes API Kinds (Group-Version-Kinds, to be specific).
Webhooks ¶
Similarly, webhooks (pkg/webhook/admission) may be implemented directly, but are often constructed using a builder (pkg/webhook/admission/builder). They are run via a server (pkg/webhook) which is managed by a Manager.
Logging and Metrics ¶
Logging (pkg/log) in controller-runtime is done via structured logs, using a log set of interfaces called logr (https://pkg.go.dev/github.com/go-logr/logr). While controller-runtime provides easy setup for using Zap (https://go.uber.org/zap, pkg/log/zap), you can provide any implementation of logr as the base logger for controller-runtime.
Metrics (pkg/metrics) provided by controller-runtime are registered into a controller-runtime-specific Prometheus metrics registry. The manager can serve these by an HTTP endpoint, and additional metrics may be registered to this Registry as normal.
Testing ¶
You can easily build integration and unit tests for your controllers and webhooks using the test Environment (pkg/envtest). This will automatically stand up a copy of etcd and kube-apiserver, and provide the correct options to connect to the API server. It's designed to work well with the Ginkgo testing framework, but should work with any testing setup.
Example ¶
This example creates a simple application Controller that is configured for ReplicaSets and Pods.
* Create a new application for ReplicaSets that manages Pods owned by the ReplicaSet and calls into ReplicaSetReconciler.
* Start the application. TODO(pwittrock): Update this example when we have better dependency injection support.
package main import ( "context" "fmt" "os" ctrl "github.com/samuelkuklis/controller-runtime" "github.com/samuelkuklis/controller-runtime/pkg/client" appsv1 "k8s.io/api/apps/v1" corev1 "k8s.io/api/core/v1" // since we invoke tests with -ginkgo.junit-report we need to import ginkgo. _ "github.com/onsi/ginkgo/v2" ) func main() { var log = ctrl.Log.WithName("builder-examples") manager, err := ctrl.NewManager(ctrl.GetConfigOrDie(), ctrl.Options{}) if err != nil { log.Error(err, "could not create manager") os.Exit(1) } err = ctrl. NewControllerManagedBy(manager). // Create the Controller For(&appsv1.ReplicaSet{}). // ReplicaSet is the Application API Owns(&corev1.Pod{}). // ReplicaSet owns Pods created by it Complete(&ReplicaSetReconciler{Client: manager.GetClient()}) if err != nil { log.Error(err, "could not create controller") os.Exit(1) } if err := manager.Start(ctrl.SetupSignalHandler()); err != nil { log.Error(err, "could not start manager") os.Exit(1) } } // ReplicaSetReconciler is a simple Controller example implementation. type ReplicaSetReconciler struct { client.Client } // Implement the business logic: // This function will be called when there is a change to a ReplicaSet or a Pod with an OwnerReference // to a ReplicaSet. // // * Read the ReplicaSet // * Read the Pods // * Set a Label on the ReplicaSet with the Pod count. func (a *ReplicaSetReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) { rs := &appsv1.ReplicaSet{} err := a.Get(ctx, req.NamespacedName, rs) if err != nil { return ctrl.Result{}, err } pods := &corev1.PodList{} err = a.List(ctx, pods, client.InNamespace(req.Namespace), client.MatchingLabels(rs.Spec.Template.Labels)) if err != nil { return ctrl.Result{}, err } rs.Labels["pod-count"] = fmt.Sprintf("%v", len(pods.Items)) err = a.Update(context.TODO(), rs) if err != nil { return ctrl.Result{}, err } return ctrl.Result{}, nil }
Output:
Example (UpdateLeaderElectionDurations) ¶
This example creates a simple application Controller that is configured for ReplicaSets and Pods. This application controller will be running leader election with the provided configuration in the manager options. If leader election configuration is not provided, controller runs leader election with default values. Default values taken from: https://github.com/kubernetes/component-base/blob/master/config/v1alpha1/defaults.go * defaultLeaseDuration = 15 * time.Second * defaultRenewDeadline = 10 * time.Second * defaultRetryPeriod = 2 * time.Second
* Create a new application for ReplicaSets that manages Pods owned by the ReplicaSet and calls into ReplicaSetReconciler.
* Start the application. TODO(pwittrock): Update this example when we have better dependency injection support.
package main import ( "context" "fmt" "os" "time" ctrl "github.com/samuelkuklis/controller-runtime" "github.com/samuelkuklis/controller-runtime/pkg/client" appsv1 "k8s.io/api/apps/v1" corev1 "k8s.io/api/core/v1" // since we invoke tests with -ginkgo.junit-report we need to import ginkgo. _ "github.com/onsi/ginkgo/v2" ) func main() { var log = ctrl.Log.WithName("builder-examples") leaseDuration := 100 * time.Second renewDeadline := 80 * time.Second retryPeriod := 20 * time.Second manager, err := ctrl.NewManager( ctrl.GetConfigOrDie(), ctrl.Options{ LeaseDuration: &leaseDuration, RenewDeadline: &renewDeadline, RetryPeriod: &retryPeriod, }) if err != nil { log.Error(err, "could not create manager") os.Exit(1) } err = ctrl. NewControllerManagedBy(manager). // Create the Controller For(&appsv1.ReplicaSet{}). // ReplicaSet is the Application API Owns(&corev1.Pod{}). // ReplicaSet owns Pods created by it Complete(&ReplicaSetReconciler{Client: manager.GetClient()}) if err != nil { log.Error(err, "could not create controller") os.Exit(1) } if err := manager.Start(ctrl.SetupSignalHandler()); err != nil { log.Error(err, "could not start manager") os.Exit(1) } } // ReplicaSetReconciler is a simple Controller example implementation. type ReplicaSetReconciler struct { client.Client } // Implement the business logic: // This function will be called when there is a change to a ReplicaSet or a Pod with an OwnerReference // to a ReplicaSet. // // * Read the ReplicaSet // * Read the Pods // * Set a Label on the ReplicaSet with the Pod count. func (a *ReplicaSetReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) { rs := &appsv1.ReplicaSet{} err := a.Get(ctx, req.NamespacedName, rs) if err != nil { return ctrl.Result{}, err } pods := &corev1.PodList{} err = a.List(ctx, pods, client.InNamespace(req.Namespace), client.MatchingLabels(rs.Spec.Template.Labels)) if err != nil { return ctrl.Result{}, err } rs.Labels["pod-count"] = fmt.Sprintf("%v", len(pods.Items)) err = a.Update(context.TODO(), rs) if err != nil { return ctrl.Result{}, err } return ctrl.Result{}, nil }
Output:
Index ¶
Examples ¶
Constants ¶
This section is empty.
Variables ¶
var ( // RegisterFlags registers flag variables to the given FlagSet if not already registered. // It uses the default command line FlagSet, if none is provided. Currently, it only registers the kubeconfig flag. RegisterFlags = config.RegisterFlags // GetConfigOrDie creates a *rest.Config for talking to a Kubernetes apiserver. // If --kubeconfig is set, will use the kubeconfig file at that location. Otherwise will assume running // in cluster and use the cluster provided kubeconfig. // // Will log an error and exit if there is an error creating the rest.Config. GetConfigOrDie = config.GetConfigOrDie // GetConfig creates a *rest.Config for talking to a Kubernetes apiserver. // If --kubeconfig is set, will use the kubeconfig file at that location. Otherwise will assume running // in cluster and use the cluster provided kubeconfig. // // Config precedence // // * --kubeconfig flag pointing at a file // // * KUBECONFIG environment variable pointing at a file // // * In-cluster config if running in cluster // // * $HOME/.kube/config if exists. GetConfig = config.GetConfig // ConfigFile returns the cfg.File function for deferred config file loading, // this is passed into Options{}.From() to populate the Options fields for // the manager. ConfigFile = cfg.File // NewControllerManagedBy returns a new controller builder that will be started by the provided Manager. NewControllerManagedBy = builder.ControllerManagedBy // NewWebhookManagedBy returns a new webhook builder that will be started by the provided Manager. NewWebhookManagedBy = builder.WebhookManagedBy // NewManager returns a new Manager for creating Controllers. NewManager = manager.New // CreateOrUpdate creates or updates the given object obj in the Kubernetes // cluster. The object's desired state should be reconciled with the existing // state using the passed in ReconcileFn. obj must be a struct pointer so that // obj can be updated with the content returned by the Server. // // It returns the executed operation and an error. CreateOrUpdate = controllerutil.CreateOrUpdate // SetControllerReference sets owner as a Controller OwnerReference on owned. // This is used for garbage collection of the owned object and for // reconciling the owner object on changes to owned (with a Watch + EnqueueRequestForOwner). // Since only one OwnerReference can be a controller, it returns an error if // there is another OwnerReference with Controller flag set. SetControllerReference = controllerutil.SetControllerReference // SetupSignalHandler registered for SIGTERM and SIGINT. A stop channel is returned // which is closed on one of these signals. If a second signal is caught, the program // is terminated with exit code 1. SetupSignalHandler = signals.SetupSignalHandler // Log is the base logger used by controller-runtime. It delegates // to another logr.Logger. You *must* call SetLogger to // get any actual logging. Log = log.Log // LoggerFrom returns a logger with predefined values from a context.Context. // The logger, when used with controllers, can be expected to contain basic information about the object // that's being reconciled like: // - `reconciler group` and `reconciler kind` coming from the For(...) object passed in when building a controller. // - `name` and `namespace` injected from the reconciliation request. // // This is meant to be used with the context supplied in a struct that satisfies the Reconciler interface. LoggerFrom = log.FromContext // LoggerInto takes a context and sets the logger as one of its keys. // // This is meant to be used in reconcilers to enrich the logger within a context with additional values. LoggerInto = log.IntoContext // SetLogger sets a concrete logging implementation for all deferred Loggers. SetLogger = log.SetLogger )
Functions ¶
This section is empty.
Types ¶
type Builder ¶
Builder builds an Application ControllerManagedBy (e.g. Operator) and returns a manager.Manager to start it.
type GroupResource ¶
type GroupResource = schema.GroupResource
GroupResource specifies a Group and a Resource, but does not force a version. This is useful for identifying concepts during lookup stages without having partially valid types.
type GroupVersion ¶
type GroupVersion = schema.GroupVersion
GroupVersion contains the "group" and the "version", which uniquely identifies the API.
type Manager ¶
Manager initializes shared dependencies such as Caches and Clients, and provides them to Runnables. A Manager is required to create Controllers.
type ObjectMeta ¶
type ObjectMeta = metav1.ObjectMeta
ObjectMeta is metadata that all persisted resources must have, which includes all objects users must create.
type Request ¶
Request contains the information necessary to reconcile a Kubernetes object. This includes the information to uniquely identify the object - its Name and Namespace. It does NOT contain information about any specific Event or the object contents itself.
type SchemeBuilder ¶
SchemeBuilder builds a new Scheme for mapping go types to Kubernetes GroupVersionKinds.
Directories ¶
Path | Synopsis |
---|---|
examples
|
|
configfile/custom/v1alpha1
Package v1alpha1 provides the CustomControllerManagerConfiguration used for demoing componentconfig +kubebuilder:object:generate=true
|
Package v1alpha1 provides the CustomControllerManagerConfiguration used for demoing componentconfig +kubebuilder:object:generate=true |
crd/pkg
+kubebuilder:object:generate=true +groupName=chaosapps.metamagical.io
|
+kubebuilder:object:generate=true +groupName=chaosapps.metamagical.io |
Package pkg provides libraries for building Controllers.
|
Package pkg provides libraries for building Controllers. |
builder
Package builder wraps other controller-runtime libraries and exposes simple patterns for building common Controllers.
|
Package builder wraps other controller-runtime libraries and exposes simple patterns for building common Controllers. |
cache
Package cache provides object caches that act as caching client.Reader instances and help drive Kubernetes-object-based event handlers.
|
Package cache provides object caches that act as caching client.Reader instances and help drive Kubernetes-object-based event handlers. |
certwatcher
Package certwatcher is a helper for reloading Certificates from disk to be used with tls servers.
|
Package certwatcher is a helper for reloading Certificates from disk to be used with tls servers. |
client
Package client contains functionality for interacting with Kubernetes API servers.
|
Package client contains functionality for interacting with Kubernetes API servers. |
client/apiutil
Package apiutil contains utilities for working with raw Kubernetes API machinery, such as creating RESTMappers and raw REST clients, and extracting the GVK of an object.
|
Package apiutil contains utilities for working with raw Kubernetes API machinery, such as creating RESTMappers and raw REST clients, and extracting the GVK of an object. |
client/config
Package config contains libraries for initializing REST configs for talking to the Kubernetes API
|
Package config contains libraries for initializing REST configs for talking to the Kubernetes API |
client/fake
Package fake provides a fake client for testing.
|
Package fake provides a fake client for testing. |
config
Package config contains functionality for interacting with ComponentConfig files
|
Package config contains functionality for interacting with ComponentConfig files |
config/v1alpha1
Package v1alpha1 provides the ControllerManagerConfiguration used for configuring ctrl.Manager +kubebuilder:object:generate=true
|
Package v1alpha1 provides the ControllerManagerConfiguration used for configuring ctrl.Manager +kubebuilder:object:generate=true |
controller
Package controller provides types and functions for building Controllers.
|
Package controller provides types and functions for building Controllers. |
controller/controllertest
Package controllertest contains fake informers for testing controllers When in doubt, it's almost always better to test against a real API server using envtest.Environment.
|
Package controllertest contains fake informers for testing controllers When in doubt, it's almost always better to test against a real API server using envtest.Environment. |
controller/controllerutil
Package controllerutil contains utility functions for working with and implementing Controllers.
|
Package controllerutil contains utility functions for working with and implementing Controllers. |
conversion
Package conversion provides interface definitions that an API Type needs to implement for it to be supported by the generic conversion webhook handler defined under pkg/webhook/conversion.
|
Package conversion provides interface definitions that an API Type needs to implement for it to be supported by the generic conversion webhook handler defined under pkg/webhook/conversion. |
envtest
Package envtest provides libraries for integration testing by starting a local control plane
|
Package envtest provides libraries for integration testing by starting a local control plane |
event
Package event contains the definitions for the Event types produced by source.Sources and transformed into reconcile.Requests by handler.EventHandler.
|
Package event contains the definitions for the Event types produced by source.Sources and transformed into reconcile.Requests by handler.EventHandler. |
handler
Package handler defines EventHandlers that enqueue reconcile.Requests in response to Create, Update, Deletion Events observed from Watching Kubernetes APIs.
|
Package handler defines EventHandlers that enqueue reconcile.Requests in response to Create, Update, Deletion Events observed from Watching Kubernetes APIs. |
healthz
Package healthz contains helpers from supporting liveness and readiness endpoints.
|
Package healthz contains helpers from supporting liveness and readiness endpoints. |
internal/flock
Package flock is copied from k8s.io/kubernetes/pkg/util/flock to avoid importing k8s.io/kubernetes as a dependency.
|
Package flock is copied from k8s.io/kubernetes/pkg/util/flock to avoid importing k8s.io/kubernetes as a dependency. |
leaderelection
Package leaderelection contains a constructor for a leader election resource lock.
|
Package leaderelection contains a constructor for a leader election resource lock. |
leaderelection/fake
Package fake mocks a resource lock for testing purposes.
|
Package fake mocks a resource lock for testing purposes. |
log
Package log contains utilities for fetching a new logger when one is not already available.
|
Package log contains utilities for fetching a new logger when one is not already available. |
log/zap
Package zap contains helpers for setting up a new logr.Logger instance using the Zap logging framework.
|
Package zap contains helpers for setting up a new logr.Logger instance using the Zap logging framework. |
manager
Package manager is required to create Controllers and provides shared dependencies such as clients, caches, schemes, etc.
|
Package manager is required to create Controllers and provides shared dependencies such as clients, caches, schemes, etc. |
manager/signals
Package signals contains libraries for handling signals to gracefully shutdown the manager in combination with Kubernetes pod graceful termination policy.
|
Package signals contains libraries for handling signals to gracefully shutdown the manager in combination with Kubernetes pod graceful termination policy. |
metrics
Package metrics contains controller related metrics utilities
|
Package metrics contains controller related metrics utilities |
patterns/application
Package application documents patterns for building Controllers to manage specific applications.
|
Package application documents patterns for building Controllers to manage specific applications. |
patterns/operator
Package operator serves to redirect users to the application package.
|
Package operator serves to redirect users to the application package. |
predicate
Package predicate defines Predicates used by Controllers to filter Events before they are provided to EventHandlers.
|
Package predicate defines Predicates used by Controllers to filter Events before they are provided to EventHandlers. |
ratelimiter
Package ratelimiter defines rate limiters used by Controllers to limit how frequently requests may be queued.
|
Package ratelimiter defines rate limiters used by Controllers to limit how frequently requests may be queued. |
reconcile
Package reconcile defines the Reconciler interface to implement Kubernetes APIs.
|
Package reconcile defines the Reconciler interface to implement Kubernetes APIs. |
recorder
Package recorder defines interfaces for working with Kubernetes event recorders.
|
Package recorder defines interfaces for working with Kubernetes event recorders. |
runtime
Package runtime contains not-quite-internal mechanisms for controller-runtime, plus some deprecated exports of functionality moved elsewhere.
|
Package runtime contains not-quite-internal mechanisms for controller-runtime, plus some deprecated exports of functionality moved elsewhere. |
runtime/inject
Package inject defines interfaces and functions for propagating dependencies from a ControllerManager to the components registered with it.
|
Package inject defines interfaces and functions for propagating dependencies from a ControllerManager to the components registered with it. |
scheme
Package scheme contains utilities for gradually building Schemes, which contain information associating Go types with Kubernetes groups, versions, and kinds.
|
Package scheme contains utilities for gradually building Schemes, which contain information associating Go types with Kubernetes groups, versions, and kinds. |
source
Package source provides event streams to hook up to Controllers with Controller.Watch.
|
Package source provides event streams to hook up to Controllers with Controller.Watch. |
webhook
Package webhook provides methods to build and bootstrap a webhook server.
|
Package webhook provides methods to build and bootstrap a webhook server. |
webhook/admission
Package admission provides implementation for admission webhook and methods to implement admission webhook handlers.
|
Package admission provides implementation for admission webhook and methods to implement admission webhook handlers. |
webhook/admission/admissiontest
Package admissiontest contains fake webhooks for validating admission webhooks
|
Package admissiontest contains fake webhooks for validating admission webhooks |
webhook/authentication
Package authentication provides implementation for authentication webhook and methods to implement authentication webhook handlers.
|
Package authentication provides implementation for authentication webhook and methods to implement authentication webhook handlers. |
webhook/conversion
Package conversion provides implementation for CRD conversion webhook that implements handler for version conversion requests for types that are convertible.
|
Package conversion provides implementation for CRD conversion webhook that implements handler for version conversion requests for types that are convertible. |