From f95ec84322876d2e4461eb5d43b983bd1bde36ac Mon Sep 17 00:00:00 2001 From: "W. Trevor King" Date: Thu, 23 Jul 2020 14:08:36 -0700 Subject: [PATCH 1/3] Event: Document TTL and best-effort-ness Generally try to waive away folks who see a particular event stream and feel tempted to extrapolate and build tooling that expects the same underlying resource transition chain to continue to produce a similar event stream as the underlying components evolve and are updated. New controllers should not be constrained to be backwards-compatible with previous versions with regard to Event emission. This is distinct from the Event type itself, which has the usual Kubernetes-API compatibility commitments for versioned types. The EventTTL default has been 1h since 7e258b85bd (Reduce TTL for events in etcd from 48hrs to 1hr, 2015-03-11, #5315), and remains so today: $ git --no-pager log -1 --format='%h %s' origin/master 8e5c02255cc Merge pull request #90942 from ii/ii-create-pod%2Bpodstatus-resource-lifecycle-test $ git --no-pager grep EventTTL: 8e5c02255cc cmd/kube-apiserver/app/options/options.go 8e5c02255cc:cmd/kube-apiserver/app/options/options.go: EventTTL: 1 * time.Hour, In this space [1,2]: To avoid filling up master's disk, a retention policy is enforced: events are removed one hour after the last occurrence. To provide longer history and aggregation capabilities, a third party solution should be installed to capture events. ... Note: It is not guaranteed that all events happening in a cluster will be exported to Stackdriver. One possible scenario when events will not be exported is when event exporter is not running (e.g. during restart or upgrade). In most cases it's fine to use events for purposes like setting up metrics and alerts, but you should be aware of the potential inaccuracy. ... To prevent disturbing your workloads, event exporter does not have resources set and is in the best effort QOS class, which means that it will be the first to be killed in the case of resource starvation. Although that's talking more about export from etcd -> external storage, and not about cluster components submitting events to etcd. [1]: https://kubernetes.io/docs/tasks/debug-application-cluster/events-stackdriver/ [2]: https://github.com/kubernetes/website/pull/4155/files#diff-d8eb69c5436aa38b396d4f3ed75e4792R10 --- pkg/apis/core/types.go | 7 ++++++- staging/src/k8s.io/api/core/v1/types.go | 7 ++++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/pkg/apis/core/types.go b/pkg/apis/core/types.go index 0c6baa98332..eaea31151c3 100644 --- a/pkg/apis/core/types.go +++ b/pkg/apis/core/types.go @@ -4602,7 +4602,12 @@ const ( // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object -// Event is a report of an event somewhere in the cluster. +// Event is a report of an event somewhere in the cluster. Events +// have a limited retention time and triggers and messages may evolve +// with time. Event consumers should not rely on the timing of an event +// with a given Reason reflecting a consistent underlying trigger, or the +// continued existence of events with that Reason. Events should be +// treated as informative, best-effort, supplemental data. // TODO: Decide whether to store these separately or with the object they apply to. type Event struct { metav1.TypeMeta diff --git a/staging/src/k8s.io/api/core/v1/types.go b/staging/src/k8s.io/api/core/v1/types.go index bd67349d957..11650677c34 100644 --- a/staging/src/k8s.io/api/core/v1/types.go +++ b/staging/src/k8s.io/api/core/v1/types.go @@ -5315,7 +5315,12 @@ const ( // +genclient // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object -// Event is a report of an event somewhere in the cluster. +// Event is a report of an event somewhere in the cluster. Events +// have a limited retention time and triggers and messages may evolve +// with time. Event consumers should not rely on the timing of an event +// with a given Reason reflecting a consistent underlying trigger, or the +// continued existence of events with that Reason. Events should be +// treated as informative, best-effort, supplemental data. type Event struct { metav1.TypeMeta `json:",inline"` // Standard object's metadata. From 4af2f7d37f43cf86e676903b06cb721a9f1a60e9 Mon Sep 17 00:00:00 2001 From: David Eads Date: Tue, 27 Oct 2020 14:06:15 -0400 Subject: [PATCH 2/3] add godoc for events to events.k8s.io --- staging/src/k8s.io/api/events/v1/types.go | 5 +++++ staging/src/k8s.io/api/events/v1beta1/types.go | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/staging/src/k8s.io/api/events/v1/types.go b/staging/src/k8s.io/api/events/v1/types.go index f11c2799803..4bf715872ab 100644 --- a/staging/src/k8s.io/api/events/v1/types.go +++ b/staging/src/k8s.io/api/events/v1/types.go @@ -25,6 +25,11 @@ import ( // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object // Event is a report of an event somewhere in the cluster. It generally denotes some state change in the system. +// Events have a limited retention time and triggers and messages may evolve +// with time. Event consumers should not rely on the timing of an event +// with a given Reason reflecting a consistent underlying trigger, or the +// continued existence of events with that Reason. Events should be +// treated as informative, best-effort, supplemental data. type Event struct { metav1.TypeMeta `json:",inline"` diff --git a/staging/src/k8s.io/api/events/v1beta1/types.go b/staging/src/k8s.io/api/events/v1beta1/types.go index dce4e21dfd0..796e56ea7da 100644 --- a/staging/src/k8s.io/api/events/v1beta1/types.go +++ b/staging/src/k8s.io/api/events/v1beta1/types.go @@ -27,6 +27,11 @@ import ( // +k8s:prerelease-lifecycle-gen:deprecated=1.22 // Event is a report of an event somewhere in the cluster. It generally denotes some state change in the system. +// Events have a limited retention time and triggers and messages may evolve +// with time. Event consumers should not rely on the timing of an event +// with a given Reason reflecting a consistent underlying trigger, or the +// continued existence of events with that Reason. Events should be +// treated as informative, best-effort, supplemental data. type Event struct { metav1.TypeMeta `json:",inline"` From 5edd3763ce1caa4b60f91a14b3742a7730c9ca6a Mon Sep 17 00:00:00 2001 From: David Eads Date: Tue, 27 Oct 2020 14:23:20 -0400 Subject: [PATCH 3/3] generated --- api/openapi-spec/swagger.json | 6 +++--- staging/src/k8s.io/api/core/v1/generated.proto | 7 ++++++- .../src/k8s.io/api/core/v1/types_swagger_doc_generated.go | 2 +- staging/src/k8s.io/api/events/v1/generated.proto | 5 +++++ .../k8s.io/api/events/v1/types_swagger_doc_generated.go | 2 +- staging/src/k8s.io/api/events/v1beta1/generated.proto | 5 +++++ .../api/events/v1beta1/types_swagger_doc_generated.go | 2 +- 7 files changed, 22 insertions(+), 7 deletions(-) diff --git a/api/openapi-spec/swagger.json b/api/openapi-spec/swagger.json index c78c7543c77..cbd54edc56e 100644 --- a/api/openapi-spec/swagger.json +++ b/api/openapi-spec/swagger.json @@ -6574,7 +6574,7 @@ "type": "object" }, "io.k8s.api.core.v1.Event": { - "description": "Event is a report of an event somewhere in the cluster.", + "description": "Event is a report of an event somewhere in the cluster. Events have a limited retention time and triggers and messages may evolve with time. Event consumers should not rely on the timing of an event with a given Reason reflecting a consistent underlying trigger, or the continued existence of events with that Reason. Events should be treated as informative, best-effort, supplemental data.", "properties": { "action": { "description": "What action was taken/failed regarding to the Regarding object.", @@ -11028,7 +11028,7 @@ ] }, "io.k8s.api.events.v1.Event": { - "description": "Event is a report of an event somewhere in the cluster. It generally denotes some state change in the system.", + "description": "Event is a report of an event somewhere in the cluster. It generally denotes some state change in the system. Events have a limited retention time and triggers and messages may evolve with time. Event consumers should not rely on the timing of an event with a given Reason reflecting a consistent underlying trigger, or the continued existence of events with that Reason. Events should be treated as informative, best-effort, supplemental data.", "properties": { "action": { "description": "action is what action was taken/failed regarding to the regarding object. It is machine-readable. This field cannot be empty for new Events and it can have at most 128 characters.", @@ -11167,7 +11167,7 @@ "type": "object" }, "io.k8s.api.events.v1beta1.Event": { - "description": "Event is a report of an event somewhere in the cluster. It generally denotes some state change in the system.", + "description": "Event is a report of an event somewhere in the cluster. It generally denotes some state change in the system. Events have a limited retention time and triggers and messages may evolve with time. Event consumers should not rely on the timing of an event with a given Reason reflecting a consistent underlying trigger, or the continued existence of events with that Reason. Events should be treated as informative, best-effort, supplemental data.", "properties": { "action": { "description": "action is what action was taken/failed regarding to the regarding object. It is machine-readable. This field can have at most 128 characters.", diff --git a/staging/src/k8s.io/api/core/v1/generated.proto b/staging/src/k8s.io/api/core/v1/generated.proto index 8e19c949cff..e0fe772a93f 100644 --- a/staging/src/k8s.io/api/core/v1/generated.proto +++ b/staging/src/k8s.io/api/core/v1/generated.proto @@ -1403,7 +1403,12 @@ message EphemeralVolumeSource { optional bool readOnly = 2; } -// Event is a report of an event somewhere in the cluster. +// Event is a report of an event somewhere in the cluster. Events +// have a limited retention time and triggers and messages may evolve +// with time. Event consumers should not rely on the timing of an event +// with a given Reason reflecting a consistent underlying trigger, or the +// continued existence of events with that Reason. Events should be +// treated as informative, best-effort, supplemental data. message Event { // Standard object's metadata. // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata diff --git a/staging/src/k8s.io/api/core/v1/types_swagger_doc_generated.go b/staging/src/k8s.io/api/core/v1/types_swagger_doc_generated.go index a71dc118f24..edf08705e23 100644 --- a/staging/src/k8s.io/api/core/v1/types_swagger_doc_generated.go +++ b/staging/src/k8s.io/api/core/v1/types_swagger_doc_generated.go @@ -637,7 +637,7 @@ func (EphemeralVolumeSource) SwaggerDoc() map[string]string { } var map_Event = map[string]string{ - "": "Event is a report of an event somewhere in the cluster.", + "": "Event is a report of an event somewhere in the cluster. Events have a limited retention time and triggers and messages may evolve with time. Event consumers should not rely on the timing of an event with a given Reason reflecting a consistent underlying trigger, or the continued existence of events with that Reason. Events should be treated as informative, best-effort, supplemental data.", "metadata": "Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata", "involvedObject": "The object that this event is about.", "reason": "This should be a short, machine understandable string that gives the reason for the transition into the object's current status.", diff --git a/staging/src/k8s.io/api/events/v1/generated.proto b/staging/src/k8s.io/api/events/v1/generated.proto index c9404c90aad..690c99e4c5a 100644 --- a/staging/src/k8s.io/api/events/v1/generated.proto +++ b/staging/src/k8s.io/api/events/v1/generated.proto @@ -30,6 +30,11 @@ import "k8s.io/apimachinery/pkg/runtime/schema/generated.proto"; option go_package = "v1"; // Event is a report of an event somewhere in the cluster. It generally denotes some state change in the system. +// Events have a limited retention time and triggers and messages may evolve +// with time. Event consumers should not rely on the timing of an event +// with a given Reason reflecting a consistent underlying trigger, or the +// continued existence of events with that Reason. Events should be +// treated as informative, best-effort, supplemental data. message Event { optional k8s.io.apimachinery.pkg.apis.meta.v1.ObjectMeta metadata = 1; diff --git a/staging/src/k8s.io/api/events/v1/types_swagger_doc_generated.go b/staging/src/k8s.io/api/events/v1/types_swagger_doc_generated.go index 67105272a8d..7255727bb49 100644 --- a/staging/src/k8s.io/api/events/v1/types_swagger_doc_generated.go +++ b/staging/src/k8s.io/api/events/v1/types_swagger_doc_generated.go @@ -28,7 +28,7 @@ package v1 // AUTO-GENERATED FUNCTIONS START HERE. DO NOT EDIT. var map_Event = map[string]string{ - "": "Event is a report of an event somewhere in the cluster. It generally denotes some state change in the system.", + "": "Event is a report of an event somewhere in the cluster. It generally denotes some state change in the system. Events have a limited retention time and triggers and messages may evolve with time. Event consumers should not rely on the timing of an event with a given Reason reflecting a consistent underlying trigger, or the continued existence of events with that Reason. Events should be treated as informative, best-effort, supplemental data.", "eventTime": "eventTime is the time when this Event was first observed. It is required.", "series": "series is data about the Event series this event represents or nil if it's a singleton Event.", "reportingController": "reportingController is the name of the controller that emitted this Event, e.g. `kubernetes.io/kubelet`. This field cannot be empty for new Events.", diff --git a/staging/src/k8s.io/api/events/v1beta1/generated.proto b/staging/src/k8s.io/api/events/v1beta1/generated.proto index 465b8f3c469..90b57d8d08a 100644 --- a/staging/src/k8s.io/api/events/v1beta1/generated.proto +++ b/staging/src/k8s.io/api/events/v1beta1/generated.proto @@ -30,6 +30,11 @@ import "k8s.io/apimachinery/pkg/runtime/schema/generated.proto"; option go_package = "v1beta1"; // Event is a report of an event somewhere in the cluster. It generally denotes some state change in the system. +// Events have a limited retention time and triggers and messages may evolve +// with time. Event consumers should not rely on the timing of an event +// with a given Reason reflecting a consistent underlying trigger, or the +// continued existence of events with that Reason. Events should be +// treated as informative, best-effort, supplemental data. message Event { optional k8s.io.apimachinery.pkg.apis.meta.v1.ObjectMeta metadata = 1; diff --git a/staging/src/k8s.io/api/events/v1beta1/types_swagger_doc_generated.go b/staging/src/k8s.io/api/events/v1beta1/types_swagger_doc_generated.go index 8c987f89963..7f8e162cdd4 100644 --- a/staging/src/k8s.io/api/events/v1beta1/types_swagger_doc_generated.go +++ b/staging/src/k8s.io/api/events/v1beta1/types_swagger_doc_generated.go @@ -28,7 +28,7 @@ package v1beta1 // AUTO-GENERATED FUNCTIONS START HERE. DO NOT EDIT. var map_Event = map[string]string{ - "": "Event is a report of an event somewhere in the cluster. It generally denotes some state change in the system.", + "": "Event is a report of an event somewhere in the cluster. It generally denotes some state change in the system. Events have a limited retention time and triggers and messages may evolve with time. Event consumers should not rely on the timing of an event with a given Reason reflecting a consistent underlying trigger, or the continued existence of events with that Reason. Events should be treated as informative, best-effort, supplemental data.", "eventTime": "eventTime is the time when this Event was first observed. It is required.", "series": "series is data about the Event series this event represents or nil if it's a singleton Event.", "reportingController": "reportingController is the name of the controller that emitted this Event, e.g. `kubernetes.io/kubelet`. This field cannot be empty for new Events.",