Events should be raised in certain circumstances only
Be aware that it is not recommended to emit Events for all operations. If authors raise too many events, it brings bad UX experiences for those consuming the solutions on the cluster, and they may find it difficult to filter an actionable event from the cluster. For more information, please take a look at the Kubernetes APIs convention .
Anatomy of an Event:
Eventf(regarding, related runtime.Object, eventtype, reason, action, message string, args ...interface{})
regarding is the object this event is about.
related is an optional secondary object related to this event (use nil if not applicable).
eventtype is this event type, and is either Normal or Warning . (More info )
reason is the reason the controller generates this event. It should be short and unique with UpperCamelCase format. The value could appear in switch statements by automation. (More info )
action is the action that was taken/failed regarding the object.
message is a human-readable description with optional format arguments.
Example Usage
Following is an example of a code implementation that raises an Event.
// The following implementation will raise an event
r.Recorder.Eventf(cr, nil, corev1.EventTypeWarning, "Deleting", "DeleteCR",
"Custom Resource %s is being deleted from the namespace %s",
cr.Name, cr.Namespace)
Following are the steps with examples to help you raise events in your controller’s reconciliations.
Events are published from a Controller using an EventRecorder type CorrelatorOptions struct,
which can be created for a Controller by calling GetEventRecorder(name string) on a Manager. See that we change the implementation scaffolded in cmd/main.go:
if err := (&controller.MyKindReconciler{
Client: mgr.GetClient(),
Scheme: mgr.GetScheme(),
// Note that we added the following line:
Recorder: mgr.GetEventRecorder("mykind-controller"),
}).SetupWithManager(mgr); err != nil {
setupLog.Error(err, "unable to create controller", "controller", "MyKind")
os.Exit(1)
}
To raise an event, you must have access to events.EventRecorder in the Controller. Therefore, first update the controller implementation:
import (
...
"k8s.io/client-go/tools/events"
...
)
// MyKindReconciler reconciles a MyKind object
type MyKindReconciler struct {
client.Client
Scheme *runtime.Scheme
// See that we added the following code to allow us to pass the events.EventRecorder
Recorder events.EventRecorder
}
Events are published from a Controller using an [EventRecorder]type CorrelatorOptions struct,
which can be created for a Controller by calling GetEventRecorder(name string) on a Manager. See that we change the implementation scaffolded in cmd/main.go:
if err := (&controller.MyKindReconciler{
Client: mgr.GetClient(),
Scheme: mgr.GetScheme(),
// Note that we added the following line:
Recorder: mgr.GetEventRecorder("mykind-controller"),
}).SetupWithManager(mgr); err != nil {
setupLog.Error(err, "unable to create controller", "controller", "MyKind")
os.Exit(1)
}
You must also grant the RBAC rules permissions to allow your project to create Events. Therefore, ensure that you add the RBAC into your controller:
...
// +kubebuilder:rbac:groups=events.k8s.io,resources=events,verbs=create;patch
...
func (r *MyKindReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
And then, run $ make manifests to update the rules under config/rbac/role.yaml.