controller package - sigs.k8s.io/controller-runtime/pkg/controller - Go Packages (original) (raw)
Package controller provides types and functions for building Controllers. Controllers implement Kubernetes APIs.
Creation ¶
To create a new Controller, first create a manager.Manager and pass it to the controller.New function. The Controller MUST be started by calling Manager.Start.
This section is empty.
ReconcileIDFromContext gets the reconcileID from the current context.
This section is empty.
Controller implements a Kubernetes API. A Controller manages a work queue fed reconcile.Requests from source.Sources. Work is performed through the reconcile.Reconciler for each enqueued item. Work typically is reads and writes Kubernetes objects to make the system state match the state specified in the object Spec.
This example starts a new Controller named "pod-controller" to Watch Pods and call a no-op Reconciler.
package main
import ( "context" "os"
corev1 "k8s.io/api/core/v1"
"sigs.k8s.io/controller-runtime/pkg/controller"
"sigs.k8s.io/controller-runtime/pkg/handler"
logf "sigs.k8s.io/controller-runtime/pkg/log"
"sigs.k8s.io/controller-runtime/pkg/manager"
"sigs.k8s.io/controller-runtime/pkg/manager/signals"
"sigs.k8s.io/controller-runtime/pkg/reconcile"
"sigs.k8s.io/controller-runtime/pkg/source"
)
var ( mgr manager.Manager
log = logf.Log.WithName("controller-examples")
)
func main() { // mgr is a manager.Manager
// Create a new Controller that will call the provided Reconciler function in response
// to events.
c, err := controller.New("pod-controller", mgr, controller.Options{
Reconciler: reconcile.Func(func(context.Context, reconcile.Request) (reconcile.Result, error) {
// Your business logic to implement the API by creating, updating, deleting objects goes here.
return reconcile.Result{}, nil
}),
})
if err != nil {
log.Error(err, "unable to create pod-controller")
os.Exit(1)
}
// Watch for Pod create / update / delete events and call Reconcile
err = c.Watch(source.Kind(mgr.GetCache(), &corev1.Pod{}, &handler.TypedEnqueueRequestForObject[*corev1.Pod]{}))
if err != nil {
log.Error(err, "unable to watch pods")
os.Exit(1)
}
// Start the Controller through the manager.
if err := mgr.Start(signals.SetupSignalHandler()); err != nil {
log.Error(err, "unable to continue running manager")
os.Exit(1)
}
}
Output:
This example starts a new Controller named "pod-controller" to Watch Pods with the unstructured object and call a no-op Reconciler.
package main
import ( "context" "os"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime/schema"
"sigs.k8s.io/controller-runtime/pkg/controller"
"sigs.k8s.io/controller-runtime/pkg/handler"
logf "sigs.k8s.io/controller-runtime/pkg/log"
"sigs.k8s.io/controller-runtime/pkg/manager"
"sigs.k8s.io/controller-runtime/pkg/manager/signals"
"sigs.k8s.io/controller-runtime/pkg/reconcile"
"sigs.k8s.io/controller-runtime/pkg/source"
)
var ( mgr manager.Manager
log = logf.Log.WithName("controller-examples")
)
func main() { // mgr is a manager.Manager
// Create a new Controller that will call the provided Reconciler function in response
// to events.
c, err := controller.New("pod-controller", mgr, controller.Options{
Reconciler: reconcile.Func(func(context.Context, reconcile.Request) (reconcile.Result, error) {
// Your business logic to implement the API by creating, updating, deleting objects goes here.
return reconcile.Result{}, nil
}),
})
if err != nil {
log.Error(err, "unable to create pod-controller")
os.Exit(1)
}
u := &unstructured.Unstructured{}
u.SetGroupVersionKind(schema.GroupVersionKind{
Kind: "Pod",
Group: "",
Version: "v1",
})
// Watch for Pod create / update / delete events and call Reconcile
err = c.Watch(source.Kind(mgr.GetCache(), u, &handler.TypedEnqueueRequestForObject[*unstructured.Unstructured]{}))
if err != nil {
log.Error(err, "unable to watch pods")
os.Exit(1)
}
// Start the Controller through the manager.
if err := mgr.Start(signals.SetupSignalHandler()); err != nil {
log.Error(err, "unable to continue running manager")
os.Exit(1)
}
}
Output:
New returns a new Controller registered with the Manager. The Manager will ensure that shared Caches have been synced before the Controller is Started.
The name must be unique as it is used to identify the controller in metrics and logs.
This example creates a new Controller named "pod-controller" with a no-op reconcile function. The manager.Manager will be used to Start the Controller, and will provide it a shared Cache and Client.
package main
import ( "context" "os"
"sigs.k8s.io/controller-runtime/pkg/controller"
logf "sigs.k8s.io/controller-runtime/pkg/log"
"sigs.k8s.io/controller-runtime/pkg/manager"
"sigs.k8s.io/controller-runtime/pkg/reconcile"
)
var ( mgr manager.Manager
log = logf.Log.WithName("controller-examples")
)
func main() { _, err := controller.New("pod-controller", mgr, controller.Options{ Reconciler: reconcile.Func(func(context.Context, reconcile.Request) (reconcile.Result, error) { // Your business logic to implement the API by creating, updating, deleting objects goes here. return reconcile.Result{}, nil }), }) if err != nil { log.Error(err, "unable to create pod-controller") os.Exit(1) } }
Output:
NewUnmanaged returns a new controller without adding it to the manager. The caller is responsible for starting the returned controller.
The name must be unique as it is used to identify the controller in metrics and logs.
This example creates a new controller named "pod-controller" to watch Pods and call a no-op reconciler. The controller is not added to the provided manager, and must thus be started and stopped by the caller.
package main
import ( "context" "os"
corev1 "k8s.io/api/core/v1"
"sigs.k8s.io/controller-runtime/pkg/controller"
"sigs.k8s.io/controller-runtime/pkg/handler"
logf "sigs.k8s.io/controller-runtime/pkg/log"
"sigs.k8s.io/controller-runtime/pkg/manager"
"sigs.k8s.io/controller-runtime/pkg/reconcile"
"sigs.k8s.io/controller-runtime/pkg/source"
)
var ( mgr manager.Manager
log = logf.Log.WithName("controller-examples")
)
func main() { // mgr is a manager.Manager
// Configure creates a new controller but does not add it to the supplied
// manager.
c, err := controller.NewUnmanaged("pod-controller", mgr, controller.Options{
Reconciler: reconcile.Func(func(context.Context, reconcile.Request) (reconcile.Result, error) {
return reconcile.Result{}, nil
}),
})
if err != nil {
log.Error(err, "unable to create pod-controller")
os.Exit(1)
}
if err := c.Watch(source.Kind(mgr.GetCache(), &corev1.Pod{}, &handler.TypedEnqueueRequestForObject[*corev1.Pod]{})); err != nil {
log.Error(err, "unable to watch pods")
os.Exit(1)
}
ctx, cancel := context.WithCancel(context.Background())
// Start our controller in a goroutine so that we do not block.
go func() {
// Block until our controller manager is elected leader. We presume our
// entire process will terminate if we lose leadership, so we don't need
// to handle that.
<-mgr.Elected()
// Start our controller. This will block until the context is
// closed, or the controller returns an error.
if err := c.Start(ctx); err != nil {
log.Error(err, "cannot run experiment controller")
}
}()
// Stop our controller.
cancel()
}
Output:
Options are the arguments for creating a new Controller.
TypedController implements an API.
NewTyped returns a new typed controller registered with the Manager,
The name must be unique as it is used to identify the controller in metrics and logs.
NewTypedUnmanaged returns a new typed controller without adding it to the manager.
The name must be unique as it is used to identify the controller in metrics and logs.
TypedOptions are the arguments for creating a new Controller.