Search code examples
kubernetesevents

Why eventTime in kubernetes events (events.k8s.io/v1) is always null?


I'm trying to watch kubernetes events (events.k8s.io) using golang script, and all events have field eventTime filled with null. What is the full explanation of it?

Diving deeper while trying to find it out, I've found only this statement in KEP about graduating this API:

There will be conversion functions that'll allow reading/writing Events as both core.Event and events.Event types. As we don't want to officially extend core.Event type, new fields will be set only if Event would be written through events.Event endpoint (e.g. if Event will be created by core.Event endpoint EventTime won't be set).

https://github.com/kubernetes/enhancements/blob/master/keps/sig-instrumentation/383-new-event-api-ga-graduation/README.md#comparison-between-old-and-new-apis

So will this ever change? If yes, then when? I've run the script in kube versions 1.21-1.25, and in all cases event time was null. I expect to see event time to be not null. Thank You for Your time, guys!

Upd. I've found code in kubernetes with conversion of core.Event to events.Event, and there is mapping of eventTime. So now I should check if event time is filled in core/v1 events.


Solution

    1. When the new event API was created, it was immediately designed so that corev1.Event and events.k8s.io.Event could be converted to each other, so no matter what type of event you requested, you could get them all. Conversion functions are available to convert events from one type to another and vice versa. So when the events.k8s.io API is requested, corev1 events are converted to it and returned as well, with the eventTime field empty. https://github.com/kubernetes/enhancements/blob/master/keps/sig-instrumentation/383-new-event-api-ga-graduation/README.md#backward-compatibility There will be conversion functions that'll allow reading/writing Events as both core.Event and events.Event types. As we don't want to officially extend core.Event type, new fields will be set only if Event would be written through events.Event endpoint (e.g. if Event will be created by core.Event endpoint EventTime won't be set).
    2. Not all events from events.k8s.io.Event that we read have eventTime: null. Specifically, events from the kube-scheduler come with a correct eventTime but with deprecated.* fields (such as deprecatedCount, deprecatedFirstTimestamp, etc.) empty. There are just not many of them.
    3. Events in Kubernetes are created when any component sends them there using the client-go library (https://github.com/kubernetes/client-go).
    4. All Kubernetes components use the EventRecorder interface to send events, and its implementation is hidden in client-go.
    5. Client-go has at least two packages that export this interface: k8s.io/client-go/tools/events (https://github.com/kubernetes/client-go/tree/master/tools/events) and k8s.io/client-go/tools/record (https://github.com/kubernetes/client-go/tree/master/tools/record). The first is responsible for sending events of type events.k8s.io.Event, which we read, and the second for sending corev1.Event events.
    6. In fact, which type of events a particular Kubernetes component will send to the cluster depends on one package import with the EventRecorder interface. The scheduler imports k8s.io/client-go/tools/events, so events of type events.k8s.io.Event with filled new fields and empty deprecated ones come from it to the cluster. Other important components for us, such as kubelet and controller-manager, import k8s.io/client-go/tools/record, so they send corev1.Event events, which are then converted to the new format for us.
    7. This pattern is observed up to and including version 1.27.