From ee596a88d944440c71c1773c78019cd341ed605b Mon Sep 17 00:00:00 2001 From: Lee Verberne Date: Sun, 24 Jul 2022 16:06:41 +0200 Subject: [PATCH 1/3] Mark EphemeralContainers feature gate as GA --- pkg/features/kube_features.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pkg/features/kube_features.go b/pkg/features/kube_features.go index c2a4709c3aa..5d10c98577e 100644 --- a/pkg/features/kube_features.go +++ b/pkg/features/kube_features.go @@ -285,6 +285,7 @@ const ( // owner: @verb // alpha: v1.16 // beta: v1.23 + // GA: v1.25 // // Allows running an ephemeral container in pod namespaces to troubleshoot a running pod. EphemeralContainers featuregate.Feature = "EphemeralContainers" @@ -883,7 +884,7 @@ var defaultKubernetesFeatureGates = map[featuregate.Feature]featuregate.FeatureS EndpointSliceTerminatingCondition: {Default: true, PreRelease: featuregate.Beta}, - EphemeralContainers: {Default: true, PreRelease: featuregate.Beta}, + EphemeralContainers: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.27 ExecProbeTimeout: {Default: true, PreRelease: featuregate.GA}, // lock to default and remove after v1.22 based on KEP #1972 update From bc3c5ae26943aca33399b054fba5d14661f8ac52 Mon Sep 17 00:00:00 2001 From: Lee Verberne Date: Sun, 24 Jul 2022 16:41:47 +0200 Subject: [PATCH 2/3] Remove EphemeralContainers beta disclaimer --- api/openapi-spec/swagger.json | 6 +++--- api/openapi-spec/v3/api__v1_openapi.json | 6 +++--- api/openapi-spec/v3/apis__apps__v1_openapi.json | 4 ++-- api/openapi-spec/v3/apis__batch__v1_openapi.json | 4 ++-- pkg/apis/core/types.go | 4 ---- pkg/generated/openapi/zz_generated.openapi.go | 6 +++--- staging/src/k8s.io/api/core/v1/generated.proto | 4 ---- staging/src/k8s.io/api/core/v1/types.go | 4 ---- .../src/k8s.io/api/core/v1/types_swagger_doc_generated.go | 6 +++--- 9 files changed, 16 insertions(+), 28 deletions(-) diff --git a/api/openapi-spec/swagger.json b/api/openapi-spec/swagger.json index b5e0608c64a..d0ca8b7509c 100644 --- a/api/openapi-spec/swagger.json +++ b/api/openapi-spec/swagger.json @@ -5402,7 +5402,7 @@ "type": "object" }, "io.k8s.api.core.v1.EphemeralContainer": { - "description": "An EphemeralContainer is a temporary container that you may add to an existing Pod for user-initiated activities such as debugging. Ephemeral containers have no resource or scheduling guarantees, and they will not be restarted when they exit or when a Pod is removed or restarted. The kubelet may evict a Pod if an ephemeral container causes the Pod to exceed its resource allocation.\n\nTo add an ephemeral container, use the ephemeralcontainers subresource of an existing Pod. Ephemeral containers may not be removed or restarted.\n\nThis is a beta feature available on clusters that haven't disabled the EphemeralContainers feature gate.", + "description": "An EphemeralContainer is a temporary container that you may add to an existing Pod for user-initiated activities such as debugging. Ephemeral containers have no resource or scheduling guarantees, and they will not be restarted when they exit or when a Pod is removed or restarted. The kubelet may evict a Pod if an ephemeral container causes the Pod to exceed its resource allocation.\n\nTo add an ephemeral container, use the ephemeralcontainers subresource of an existing Pod. Ephemeral containers may not be removed or restarted.", "properties": { "args": { "description": "Arguments to the entrypoint. The image's CMD is used if this is not provided. Variable references $(VAR_NAME) are expanded using the container's environment. If a variable cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. \"$$(VAR_NAME)\" will produce the string literal \"$(VAR_NAME)\". Escaped references will never be expanded, regardless of whether the variable exists or not. Cannot be updated. More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell", @@ -7795,7 +7795,7 @@ "type": "boolean" }, "ephemeralContainers": { - "description": "List of ephemeral containers run in this pod. Ephemeral containers may be run in an existing pod to perform user-initiated actions such as debugging. This list cannot be specified when creating a pod, and it cannot be modified by updating the pod spec. In order to add an ephemeral container to an existing pod, use the pod's ephemeralcontainers subresource. This field is beta-level and available on clusters that haven't disabled the EphemeralContainers feature gate.", + "description": "List of ephemeral containers run in this pod. Ephemeral containers may be run in an existing pod to perform user-initiated actions such as debugging. This list cannot be specified when creating a pod, and it cannot be modified by updating the pod spec. In order to add an ephemeral container to an existing pod, use the pod's ephemeralcontainers subresource.", "items": { "$ref": "#/definitions/io.k8s.api.core.v1.EphemeralContainer" }, @@ -7986,7 +7986,7 @@ "type": "array" }, "ephemeralContainerStatuses": { - "description": "Status for any ephemeral containers that have run in this pod. This field is beta-level and available on clusters that haven't disabled the EphemeralContainers feature gate.", + "description": "Status for any ephemeral containers that have run in this pod.", "items": { "$ref": "#/definitions/io.k8s.api.core.v1.ContainerStatus" }, diff --git a/api/openapi-spec/v3/api__v1_openapi.json b/api/openapi-spec/v3/api__v1_openapi.json index f2b8cd2e860..f9545c126f6 100644 --- a/api/openapi-spec/v3/api__v1_openapi.json +++ b/api/openapi-spec/v3/api__v1_openapi.json @@ -1840,7 +1840,7 @@ "type": "object" }, "io.k8s.api.core.v1.EphemeralContainer": { - "description": "An EphemeralContainer is a temporary container that you may add to an existing Pod for user-initiated activities such as debugging. Ephemeral containers have no resource or scheduling guarantees, and they will not be restarted when they exit or when a Pod is removed or restarted. The kubelet may evict a Pod if an ephemeral container causes the Pod to exceed its resource allocation.\n\nTo add an ephemeral container, use the ephemeralcontainers subresource of an existing Pod. Ephemeral containers may not be removed or restarted.\n\nThis is a beta feature available on clusters that haven't disabled the EphemeralContainers feature gate.", + "description": "An EphemeralContainer is a temporary container that you may add to an existing Pod for user-initiated activities such as debugging. Ephemeral containers have no resource or scheduling guarantees, and they will not be restarted when they exit or when a Pod is removed or restarted. The kubelet may evict a Pod if an ephemeral container causes the Pod to exceed its resource allocation.\n\nTo add an ephemeral container, use the ephemeralcontainers subresource of an existing Pod. Ephemeral containers may not be removed or restarted.", "properties": { "args": { "description": "Arguments to the entrypoint. The image's CMD is used if this is not provided. Variable references $(VAR_NAME) are expanded using the container's environment. If a variable cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. \"$$(VAR_NAME)\" will produce the string literal \"$(VAR_NAME)\". Escaped references will never be expanded, regardless of whether the variable exists or not. Cannot be updated. More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell", @@ -4993,7 +4993,7 @@ "type": "boolean" }, "ephemeralContainers": { - "description": "List of ephemeral containers run in this pod. Ephemeral containers may be run in an existing pod to perform user-initiated actions such as debugging. This list cannot be specified when creating a pod, and it cannot be modified by updating the pod spec. In order to add an ephemeral container to an existing pod, use the pod's ephemeralcontainers subresource. This field is beta-level and available on clusters that haven't disabled the EphemeralContainers feature gate.", + "description": "List of ephemeral containers run in this pod. Ephemeral containers may be run in an existing pod to perform user-initiated actions such as debugging. This list cannot be specified when creating a pod, and it cannot be modified by updating the pod spec. In order to add an ephemeral container to an existing pod, use the pod's ephemeralcontainers subresource.", "items": { "allOf": [ { @@ -5248,7 +5248,7 @@ "type": "array" }, "ephemeralContainerStatuses": { - "description": "Status for any ephemeral containers that have run in this pod. This field is beta-level and available on clusters that haven't disabled the EphemeralContainers feature gate.", + "description": "Status for any ephemeral containers that have run in this pod.", "items": { "allOf": [ { diff --git a/api/openapi-spec/v3/apis__apps__v1_openapi.json b/api/openapi-spec/v3/apis__apps__v1_openapi.json index 400a9982ca5..a77c478bc13 100644 --- a/api/openapi-spec/v3/apis__apps__v1_openapi.json +++ b/api/openapi-spec/v3/apis__apps__v1_openapi.json @@ -2047,7 +2047,7 @@ "type": "object" }, "io.k8s.api.core.v1.EphemeralContainer": { - "description": "An EphemeralContainer is a temporary container that you may add to an existing Pod for user-initiated activities such as debugging. Ephemeral containers have no resource or scheduling guarantees, and they will not be restarted when they exit or when a Pod is removed or restarted. The kubelet may evict a Pod if an ephemeral container causes the Pod to exceed its resource allocation.\n\nTo add an ephemeral container, use the ephemeralcontainers subresource of an existing Pod. Ephemeral containers may not be removed or restarted.\n\nThis is a beta feature available on clusters that haven't disabled the EphemeralContainers feature gate.", + "description": "An EphemeralContainer is a temporary container that you may add to an existing Pod for user-initiated activities such as debugging. Ephemeral containers have no resource or scheduling guarantees, and they will not be restarted when they exit or when a Pod is removed or restarted. The kubelet may evict a Pod if an ephemeral container causes the Pod to exceed its resource allocation.\n\nTo add an ephemeral container, use the ephemeralcontainers subresource of an existing Pod. Ephemeral containers may not be removed or restarted.", "properties": { "args": { "description": "Arguments to the entrypoint. The image's CMD is used if this is not provided. Variable references $(VAR_NAME) are expanded using the container's environment. If a variable cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. \"$$(VAR_NAME)\" will produce the string literal \"$(VAR_NAME)\". Escaped references will never be expanded, regardless of whether the variable exists or not. Cannot be updated. More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell", @@ -3416,7 +3416,7 @@ "type": "boolean" }, "ephemeralContainers": { - "description": "List of ephemeral containers run in this pod. Ephemeral containers may be run in an existing pod to perform user-initiated actions such as debugging. This list cannot be specified when creating a pod, and it cannot be modified by updating the pod spec. In order to add an ephemeral container to an existing pod, use the pod's ephemeralcontainers subresource. This field is beta-level and available on clusters that haven't disabled the EphemeralContainers feature gate.", + "description": "List of ephemeral containers run in this pod. Ephemeral containers may be run in an existing pod to perform user-initiated actions such as debugging. This list cannot be specified when creating a pod, and it cannot be modified by updating the pod spec. In order to add an ephemeral container to an existing pod, use the pod's ephemeralcontainers subresource.", "items": { "allOf": [ { diff --git a/api/openapi-spec/v3/apis__batch__v1_openapi.json b/api/openapi-spec/v3/apis__batch__v1_openapi.json index d4fd0a34b59..6d1afe2c820 100644 --- a/api/openapi-spec/v3/apis__batch__v1_openapi.json +++ b/api/openapi-spec/v3/apis__batch__v1_openapi.json @@ -1243,7 +1243,7 @@ "type": "object" }, "io.k8s.api.core.v1.EphemeralContainer": { - "description": "An EphemeralContainer is a temporary container that you may add to an existing Pod for user-initiated activities such as debugging. Ephemeral containers have no resource or scheduling guarantees, and they will not be restarted when they exit or when a Pod is removed or restarted. The kubelet may evict a Pod if an ephemeral container causes the Pod to exceed its resource allocation.\n\nTo add an ephemeral container, use the ephemeralcontainers subresource of an existing Pod. Ephemeral containers may not be removed or restarted.\n\nThis is a beta feature available on clusters that haven't disabled the EphemeralContainers feature gate.", + "description": "An EphemeralContainer is a temporary container that you may add to an existing Pod for user-initiated activities such as debugging. Ephemeral containers have no resource or scheduling guarantees, and they will not be restarted when they exit or when a Pod is removed or restarted. The kubelet may evict a Pod if an ephemeral container causes the Pod to exceed its resource allocation.\n\nTo add an ephemeral container, use the ephemeralcontainers subresource of an existing Pod. Ephemeral containers may not be removed or restarted.", "properties": { "args": { "description": "Arguments to the entrypoint. The image's CMD is used if this is not provided. Variable references $(VAR_NAME) are expanded using the container's environment. If a variable cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. \"$$(VAR_NAME)\" will produce the string literal \"$(VAR_NAME)\". Escaped references will never be expanded, regardless of whether the variable exists or not. Cannot be updated. More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell", @@ -2495,7 +2495,7 @@ "type": "boolean" }, "ephemeralContainers": { - "description": "List of ephemeral containers run in this pod. Ephemeral containers may be run in an existing pod to perform user-initiated actions such as debugging. This list cannot be specified when creating a pod, and it cannot be modified by updating the pod spec. In order to add an ephemeral container to an existing pod, use the pod's ephemeralcontainers subresource. This field is beta-level and available on clusters that haven't disabled the EphemeralContainers feature gate.", + "description": "List of ephemeral containers run in this pod. Ephemeral containers may be run in an existing pod to perform user-initiated actions such as debugging. This list cannot be specified when creating a pod, and it cannot be modified by updating the pod spec. In order to add an ephemeral container to an existing pod, use the pod's ephemeralcontainers subresource.", "items": { "allOf": [ { diff --git a/pkg/apis/core/types.go b/pkg/apis/core/types.go index 3e33e319013..edd91877ba2 100644 --- a/pkg/apis/core/types.go +++ b/pkg/apis/core/types.go @@ -2829,7 +2829,6 @@ type PodSpec struct { // pod to perform user-initiated actions such as debugging. This list cannot be specified when // creating a pod, and it cannot be modified by updating the pod spec. In order to add an // ephemeral container to an existing pod, use the pod's ephemeralcontainers subresource. - // This field is beta-level and available on clusters that haven't disabled the EphemeralContainers feature gate. // +optional EphemeralContainers []EphemeralContainer // +optional @@ -3325,8 +3324,6 @@ var _ = Container(EphemeralContainerCommon{}) // // To add an ephemeral container, use the ephemeralcontainers subresource of an existing // Pod. Ephemeral containers may not be removed or restarted. -// -// This is a beta feature available on clusters that haven't disabled the EphemeralContainers feature gate. type EphemeralContainer struct { // Ephemeral containers have all of the fields of Container, plus additional fields // specific to ephemeral containers. Fields in common with Container are in the @@ -3389,7 +3386,6 @@ type PodStatus struct { ContainerStatuses []ContainerStatus // Status for any ephemeral containers that have run in this pod. - // This field is beta-level and available on clusters that haven't disabled the EphemeralContainers feature gate. // +optional EphemeralContainerStatuses []ContainerStatus } diff --git a/pkg/generated/openapi/zz_generated.openapi.go b/pkg/generated/openapi/zz_generated.openapi.go index ac6f925eb7e..8c68fbcbd26 100644 --- a/pkg/generated/openapi/zz_generated.openapi.go +++ b/pkg/generated/openapi/zz_generated.openapi.go @@ -16758,7 +16758,7 @@ func schema_k8sio_api_core_v1_EphemeralContainer(ref common.ReferenceCallback) c return common.OpenAPIDefinition{ Schema: spec.Schema{ SchemaProps: spec.SchemaProps{ - Description: "An EphemeralContainer is a temporary container that you may add to an existing Pod for user-initiated activities such as debugging. Ephemeral containers have no resource or scheduling guarantees, and they will not be restarted when they exit or when a Pod is removed or restarted. The kubelet may evict a Pod if an ephemeral container causes the Pod to exceed its resource allocation.\n\nTo add an ephemeral container, use the ephemeralcontainers subresource of an existing Pod. Ephemeral containers may not be removed or restarted.\n\nThis is a beta feature available on clusters that haven't disabled the EphemeralContainers feature gate.", + Description: "An EphemeralContainer is a temporary container that you may add to an existing Pod for user-initiated activities such as debugging. Ephemeral containers have no resource or scheduling guarantees, and they will not be restarted when they exit or when a Pod is removed or restarted. The kubelet may evict a Pod if an ephemeral container causes the Pod to exceed its resource allocation.\n\nTo add an ephemeral container, use the ephemeralcontainers subresource of an existing Pod. Ephemeral containers may not be removed or restarted.", Type: []string{"object"}, Properties: map[string]spec.Schema{ "name": { @@ -21868,7 +21868,7 @@ func schema_k8sio_api_core_v1_PodSpec(ref common.ReferenceCallback) common.OpenA }, }, SchemaProps: spec.SchemaProps{ - Description: "List of ephemeral containers run in this pod. Ephemeral containers may be run in an existing pod to perform user-initiated actions such as debugging. This list cannot be specified when creating a pod, and it cannot be modified by updating the pod spec. In order to add an ephemeral container to an existing pod, use the pod's ephemeralcontainers subresource. This field is beta-level and available on clusters that haven't disabled the EphemeralContainers feature gate.", + Description: "List of ephemeral containers run in this pod. Ephemeral containers may be run in an existing pod to perform user-initiated actions such as debugging. This list cannot be specified when creating a pod, and it cannot be modified by updating the pod spec. In order to add an ephemeral container to an existing pod, use the pod's ephemeralcontainers subresource.", Type: []string{"array"}, Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ @@ -22321,7 +22321,7 @@ func schema_k8sio_api_core_v1_PodStatus(ref common.ReferenceCallback) common.Ope }, "ephemeralContainerStatuses": { SchemaProps: spec.SchemaProps{ - Description: "Status for any ephemeral containers that have run in this pod. This field is beta-level and available on clusters that haven't disabled the EphemeralContainers feature gate.", + Description: "Status for any ephemeral containers that have run in this pod.", Type: []string{"array"}, Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ diff --git a/staging/src/k8s.io/api/core/v1/generated.proto b/staging/src/k8s.io/api/core/v1/generated.proto index 544055108f4..9c5b0483c11 100644 --- a/staging/src/k8s.io/api/core/v1/generated.proto +++ b/staging/src/k8s.io/api/core/v1/generated.proto @@ -1201,8 +1201,6 @@ message EnvVarSource { // // To add an ephemeral container, use the ephemeralcontainers subresource of an existing // Pod. Ephemeral containers may not be removed or restarted. -// -// This is a beta feature available on clusters that haven't disabled the EphemeralContainers feature gate. message EphemeralContainer { // Ephemeral containers have all of the fields of Container, plus additional fields // specific to ephemeral containers. Fields in common with Container are in the @@ -3483,7 +3481,6 @@ message PodSpec { // pod to perform user-initiated actions such as debugging. This list cannot be specified when // creating a pod, and it cannot be modified by updating the pod spec. In order to add an // ephemeral container to an existing pod, use the pod's ephemeralcontainers subresource. - // This field is beta-level and available on clusters that haven't disabled the EphemeralContainers feature gate. // +optional // +patchMergeKey=name // +patchStrategy=merge @@ -3822,7 +3819,6 @@ message PodStatus { optional string qosClass = 9; // Status for any ephemeral containers that have run in this pod. - // This field is beta-level and available on clusters that haven't disabled the EphemeralContainers feature gate. // +optional repeated ContainerStatus ephemeralContainerStatuses = 13; } diff --git a/staging/src/k8s.io/api/core/v1/types.go b/staging/src/k8s.io/api/core/v1/types.go index b4b58a17d4a..568d92e4ada 100644 --- a/staging/src/k8s.io/api/core/v1/types.go +++ b/staging/src/k8s.io/api/core/v1/types.go @@ -3090,7 +3090,6 @@ type PodSpec struct { // pod to perform user-initiated actions such as debugging. This list cannot be specified when // creating a pod, and it cannot be modified by updating the pod spec. In order to add an // ephemeral container to an existing pod, use the pod's ephemeralcontainers subresource. - // This field is beta-level and available on clusters that haven't disabled the EphemeralContainers feature gate. // +optional // +patchMergeKey=name // +patchStrategy=merge @@ -3803,8 +3802,6 @@ var _ = Container(EphemeralContainerCommon{}) // // To add an ephemeral container, use the ephemeralcontainers subresource of an existing // Pod. Ephemeral containers may not be removed or restarted. -// -// This is a beta feature available on clusters that haven't disabled the EphemeralContainers feature gate. type EphemeralContainer struct { // Ephemeral containers have all of the fields of Container, plus additional fields // specific to ephemeral containers. Fields in common with Container are in the @@ -3906,7 +3903,6 @@ type PodStatus struct { // +optional QOSClass PodQOSClass `json:"qosClass,omitempty" protobuf:"bytes,9,rep,name=qosClass"` // Status for any ephemeral containers that have run in this pod. - // This field is beta-level and available on clusters that haven't disabled the EphemeralContainers feature gate. // +optional EphemeralContainerStatuses []ContainerStatus `json:"ephemeralContainerStatuses,omitempty" protobuf:"bytes,13,rep,name=ephemeralContainerStatuses"` } 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 bc9e2e039f0..76cb659b8fc 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 @@ -580,7 +580,7 @@ func (EnvVarSource) SwaggerDoc() map[string]string { } var map_EphemeralContainer = map[string]string{ - "": "An EphemeralContainer is a temporary container that you may add to an existing Pod for user-initiated activities such as debugging. Ephemeral containers have no resource or scheduling guarantees, and they will not be restarted when they exit or when a Pod is removed or restarted. The kubelet may evict a Pod if an ephemeral container causes the Pod to exceed its resource allocation.\n\nTo add an ephemeral container, use the ephemeralcontainers subresource of an existing Pod. Ephemeral containers may not be removed or restarted.\n\nThis is a beta feature available on clusters that haven't disabled the EphemeralContainers feature gate.", + "": "An EphemeralContainer is a temporary container that you may add to an existing Pod for user-initiated activities such as debugging. Ephemeral containers have no resource or scheduling guarantees, and they will not be restarted when they exit or when a Pod is removed or restarted. The kubelet may evict a Pod if an ephemeral container causes the Pod to exceed its resource allocation.\n\nTo add an ephemeral container, use the ephemeralcontainers subresource of an existing Pod. Ephemeral containers may not be removed or restarted.", "targetContainerName": "If set, the name of the container from PodSpec that this ephemeral container targets. The ephemeral container will be run in the namespaces (IPC, PID, etc) of this container. If not set then the ephemeral container uses the namespaces configured in the Pod spec.\n\nThe container runtime must implement support for this feature. If the runtime does not support namespace targeting then the result of setting this field is undefined.", } @@ -1638,7 +1638,7 @@ var map_PodSpec = map[string]string{ "volumes": "List of volumes that can be mounted by containers belonging to the pod. More info: https://kubernetes.io/docs/concepts/storage/volumes", "initContainers": "List of initialization containers belonging to the pod. Init containers are executed in order prior to containers being started. If any init container fails, the pod is considered to have failed and is handled according to its restartPolicy. The name for an init container or normal container must be unique among all containers. Init containers may not have Lifecycle actions, Readiness probes, Liveness probes, or Startup probes. The resourceRequirements of an init container are taken into account during scheduling by finding the highest request/limit for each resource type, and then using the max of of that value or the sum of the normal containers. Limits are applied to init containers in a similar fashion. Init containers cannot currently be added or removed. Cannot be updated. More info: https://kubernetes.io/docs/concepts/workloads/pods/init-containers/", "containers": "List of containers belonging to the pod. Containers cannot currently be added or removed. There must be at least one container in a Pod. Cannot be updated.", - "ephemeralContainers": "List of ephemeral containers run in this pod. Ephemeral containers may be run in an existing pod to perform user-initiated actions such as debugging. This list cannot be specified when creating a pod, and it cannot be modified by updating the pod spec. In order to add an ephemeral container to an existing pod, use the pod's ephemeralcontainers subresource. This field is beta-level and available on clusters that haven't disabled the EphemeralContainers feature gate.", + "ephemeralContainers": "List of ephemeral containers run in this pod. Ephemeral containers may be run in an existing pod to perform user-initiated actions such as debugging. This list cannot be specified when creating a pod, and it cannot be modified by updating the pod spec. In order to add an ephemeral container to an existing pod, use the pod's ephemeralcontainers subresource.", "restartPolicy": "Restart policy for all containers within the pod. One of Always, OnFailure, Never. Default to Always. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#restart-policy", "terminationGracePeriodSeconds": "Optional duration in seconds the pod needs to terminate gracefully. May be decreased in delete request. Value must be non-negative integer. The value zero indicates stop immediately via the kill signal (no opportunity to shut down). If this value is nil, the default grace period will be used instead. The grace period is the duration in seconds after the processes running in the pod are sent a termination signal and the time when the processes are forcibly halted with a kill signal. Set this value longer than the expected cleanup time for your process. Defaults to 30 seconds.", "activeDeadlineSeconds": "Optional duration in seconds the pod may be active on the node relative to StartTime before the system will actively try to mark it failed and kill associated containers. Value must be a positive integer.", @@ -1691,7 +1691,7 @@ var map_PodStatus = map[string]string{ "initContainerStatuses": "The list has one entry per init container in the manifest. The most recent successful init container will have ready = true, the most recently started container will have startTime set. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#pod-and-container-status", "containerStatuses": "The list has one entry per container in the manifest. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#pod-and-container-status", "qosClass": "The Quality of Service (QOS) classification assigned to the pod based on resource requirements See PodQOSClass type for available QOS classes More info: https://git.k8s.io/community/contributors/design-proposals/node/resource-qos.md", - "ephemeralContainerStatuses": "Status for any ephemeral containers that have run in this pod. This field is beta-level and available on clusters that haven't disabled the EphemeralContainers feature gate.", + "ephemeralContainerStatuses": "Status for any ephemeral containers that have run in this pod.", } func (PodStatus) SwaggerDoc() map[string]string { From d238e67ba600c57eef998fc5b8f98f70a267952b Mon Sep 17 00:00:00 2001 From: Lee Verberne Date: Sun, 24 Jul 2022 16:36:42 +0200 Subject: [PATCH 3/3] Remove EphemeralContainers feature-gate checks --- pkg/api/pod/util.go | 17 +-- pkg/api/pod/util_test.go | 128 +----------------- pkg/api/v1/pod/util.go | 8 +- pkg/api/v1/pod/util_test.go | 44 +----- pkg/apis/apps/validation/validation_test.go | 4 - pkg/apis/core/pods/helpers.go | 12 +- pkg/apis/core/pods/helpers_test.go | 5 - pkg/apis/core/validation/validation_test.go | 3 - pkg/kubelet/container/helpers_test.go | 4 - pkg/kubelet/container/ref.go | 16 +-- pkg/kubelet/kubelet_pods.go | 30 ++-- .../kuberuntime/kuberuntime_container.go | 4 +- .../kuberuntime_container_linux_test.go | 1 - .../kuberuntime/kuberuntime_container_test.go | 15 -- .../kuberuntime/kuberuntime_manager.go | 18 +-- .../kuberuntime/kuberuntime_manager_test.go | 7 - pkg/kubelet/pod/pod_manager.go | 6 - pkg/kubelet/server/server.go | 2 +- pkg/registry/core/pod/storage/storage.go | 10 -- pkg/registry/core/pod/strategy_test.go | 4 - pkg/registry/core/rest/storage_core.go | 6 +- pkg/volume/util/util_test.go | 4 - test/e2e/common/node/ephemeral_containers.go | 7 - test/e2e/framework/util.go | 10 +- test/e2e/framework/volume/fixtures.go | 6 - .../admissionwebhook/admission_test.go | 2 +- test/integration/pods/pods_test.go | 68 ---------- 27 files changed, 51 insertions(+), 390 deletions(-) diff --git a/pkg/api/pod/util.go b/pkg/api/pod/util.go index 3f485aad1ee..bf14aceed93 100644 --- a/pkg/api/pod/util.go +++ b/pkg/api/pod/util.go @@ -46,11 +46,7 @@ const AllContainers ContainerType = (InitContainers | Containers | EphemeralCont // AllFeatureEnabledContainers returns a ContainerType mask which includes all container // types except for the ones guarded by feature gate. func AllFeatureEnabledContainers() ContainerType { - containerType := AllContainers - if !utilfeature.DefaultFeatureGate.Enabled(features.EphemeralContainers) { - containerType &= ^EphemeralContainers - } - return containerType + return AllContainers } // ContainerVisitor is called with each container spec, and returns true @@ -529,10 +525,6 @@ func dropDisabledFields( } } - if !utilfeature.DefaultFeatureGate.Enabled(features.EphemeralContainers) && !ephemeralContainersInUse(oldPodSpec) { - podSpec.EphemeralContainers = nil - } - if !utilfeature.DefaultFeatureGate.Enabled(features.ProbeTerminationGracePeriod) && !probeGracePeriodInUse(oldPodSpec) { // Set pod-level terminationGracePeriodSeconds to nil if the feature is disabled and it is not used VisitContainers(podSpec, AllContainers, func(c *api.Container, containerType ContainerType) bool { @@ -654,13 +646,6 @@ func nodeTaintsPolicyInUse(podSpec *api.PodSpec) bool { return false } -func ephemeralContainersInUse(podSpec *api.PodSpec) bool { - if podSpec == nil { - return false - } - return len(podSpec.EphemeralContainers) > 0 -} - // procMountInUse returns true if the pod spec is non-nil and has a SecurityContext's ProcMount field set to a non-default value func procMountInUse(podSpec *api.PodSpec) bool { if podSpec == nil { diff --git a/pkg/api/pod/util_test.go b/pkg/api/pod/util_test.go index 4e95e70a0e5..130d7c79286 100644 --- a/pkg/api/pod/util_test.go +++ b/pkg/api/pod/util_test.go @@ -39,11 +39,10 @@ import ( func TestVisitContainers(t *testing.T) { setAllFeatureEnabledContainersDuringTest := ContainerType(0) testCases := []struct { - desc string - spec *api.PodSpec - wantContainers []string - mask ContainerType - ephemeralContainersEnabled bool + desc string + spec *api.PodSpec + wantContainers []string + mask ContainerType }{ { desc: "empty podspec", @@ -127,25 +126,6 @@ func TestVisitContainers(t *testing.T) { wantContainers: []string{"i1", "i2", "c1", "c2", "e1", "e2"}, mask: AllContainers, }, - { - desc: "all feature enabled container types with ephemeral containers disabled", - spec: &api.PodSpec{ - Containers: []api.Container{ - {Name: "c1"}, - {Name: "c2"}, - }, - InitContainers: []api.Container{ - {Name: "i1"}, - {Name: "i2"}, - }, - EphemeralContainers: []api.EphemeralContainer{ - {EphemeralContainerCommon: api.EphemeralContainerCommon{Name: "e1"}}, - {EphemeralContainerCommon: api.EphemeralContainerCommon{Name: "e2"}}, - }, - }, - wantContainers: []string{"i1", "i2", "c1", "c2"}, - mask: setAllFeatureEnabledContainersDuringTest, - }, { desc: "all feature enabled container types with ephemeral containers enabled", spec: &api.PodSpec{ @@ -162,9 +142,8 @@ func TestVisitContainers(t *testing.T) { {EphemeralContainerCommon: api.EphemeralContainerCommon{Name: "e2"}}, }, }, - wantContainers: []string{"i1", "i2", "c1", "c2", "e1", "e2"}, - mask: setAllFeatureEnabledContainersDuringTest, - ephemeralContainersEnabled: true, + wantContainers: []string{"i1", "i2", "c1", "c2", "e1", "e2"}, + mask: setAllFeatureEnabledContainersDuringTest, }, { desc: "dropping fields", @@ -189,8 +168,6 @@ func TestVisitContainers(t *testing.T) { for _, tc := range testCases { t.Run(tc.desc, func(t *testing.T) { - defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.EphemeralContainers, tc.ephemeralContainersEnabled)() - if tc.mask == setAllFeatureEnabledContainersDuringTest { tc.mask = AllFeatureEnabledContainers() } @@ -226,8 +203,6 @@ func TestVisitContainers(t *testing.T) { } func TestPodSecrets(t *testing.T) { - defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.EphemeralContainers, true)() - // Stub containing all possible secret references in a pod. // The names of the referenced secrets match struct paths detected by reflection. pod := &api.Pod{ @@ -425,8 +400,6 @@ func collectResourcePaths(t *testing.T, resourcename string, path *field.Path, n } func TestPodConfigmaps(t *testing.T) { - defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.EphemeralContainers, true)() - // Stub containing all possible ConfigMap references in a pod. // The names of the referenced ConfigMaps match struct paths detected by reflection. pod := &api.Pod{ @@ -1023,95 +996,6 @@ func TestDropProbeGracePeriod(t *testing.T) { } } -func TestDropEphemeralContainers(t *testing.T) { - podWithEphemeralContainers := func() *api.Pod { - return &api.Pod{ - Spec: api.PodSpec{ - RestartPolicy: api.RestartPolicyNever, - EphemeralContainers: []api.EphemeralContainer{{EphemeralContainerCommon: api.EphemeralContainerCommon{Name: "container1", Image: "testimage"}}}, - }, - } - } - podWithoutEphemeralContainers := func() *api.Pod { - return &api.Pod{ - Spec: api.PodSpec{ - RestartPolicy: api.RestartPolicyNever, - }, - } - } - - podInfo := []struct { - description string - hasEphemeralContainers bool - pod func() *api.Pod - }{ - { - description: "has ephemeral containers", - hasEphemeralContainers: true, - pod: podWithEphemeralContainers, - }, - { - description: "does not have ephemeral containers", - hasEphemeralContainers: false, - pod: podWithoutEphemeralContainers, - }, - { - description: "is nil", - hasEphemeralContainers: false, - pod: func() *api.Pod { return nil }, - }, - } - - for _, enabled := range []bool{true, false} { - for _, oldPodInfo := range podInfo { - for _, newPodInfo := range podInfo { - oldPodHasEphemeralContainers, oldPod := oldPodInfo.hasEphemeralContainers, oldPodInfo.pod() - newPodHasEphemeralContainers, newPod := newPodInfo.hasEphemeralContainers, newPodInfo.pod() - if newPod == nil { - continue - } - - t.Run(fmt.Sprintf("feature enabled=%v, old pod %v, new pod %v", enabled, oldPodInfo.description, newPodInfo.description), func(t *testing.T) { - defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.EphemeralContainers, enabled)() - - var oldPodSpec *api.PodSpec - if oldPod != nil { - oldPodSpec = &oldPod.Spec - } - dropDisabledFields(&newPod.Spec, nil, oldPodSpec, nil) - - // old pod should never be changed - if !reflect.DeepEqual(oldPod, oldPodInfo.pod()) { - t.Errorf("old pod changed: %v", cmp.Diff(oldPod, oldPodInfo.pod())) - } - - switch { - case enabled || oldPodHasEphemeralContainers: - // new pod should not be changed if the feature is enabled, or if the old pod had subpaths - if !reflect.DeepEqual(newPod, newPodInfo.pod()) { - t.Errorf("new pod changed: %v", cmp.Diff(newPod, newPodInfo.pod())) - } - case newPodHasEphemeralContainers: - // new pod should be changed - if reflect.DeepEqual(newPod, newPodInfo.pod()) { - t.Errorf("new pod was not changed") - } - // new pod should not have subpaths - if !reflect.DeepEqual(newPod, podWithoutEphemeralContainers()) { - t.Errorf("new pod had subpaths: %v", cmp.Diff(newPod, podWithoutEphemeralContainers())) - } - default: - // new pod should not need to be changed - if !reflect.DeepEqual(newPod, newPodInfo.pod()) { - t.Errorf("new pod changed: %v", cmp.Diff(newPod, newPodInfo.pod())) - } - } - }) - } - } - } -} - func TestValidatePodDeletionCostOption(t *testing.T) { testCases := []struct { name string diff --git a/pkg/api/v1/pod/util.go b/pkg/api/v1/pod/util.go index 8bfc21a67f4..8cefc94641e 100644 --- a/pkg/api/v1/pod/util.go +++ b/pkg/api/v1/pod/util.go @@ -23,8 +23,6 @@ import ( v1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/util/intstr" - utilfeature "k8s.io/apiserver/pkg/util/feature" - "k8s.io/kubernetes/pkg/features" ) // FindPort locates the container port for the given pod and portName. If the @@ -68,11 +66,7 @@ const AllContainers ContainerType = (InitContainers | Containers | EphemeralCont // AllFeatureEnabledContainers returns a ContainerType mask which includes all container // types except for the ones guarded by feature gate. func AllFeatureEnabledContainers() ContainerType { - containerType := AllContainers - if !utilfeature.DefaultFeatureGate.Enabled(features.EphemeralContainers) { - containerType &= ^EphemeralContainers - } - return containerType + return AllContainers } // ContainerVisitor is called with each container spec, and returns true diff --git a/pkg/api/v1/pod/util_test.go b/pkg/api/v1/pod/util_test.go index b8e4f4e6d76..20b32206f20 100644 --- a/pkg/api/v1/pod/util_test.go +++ b/pkg/api/v1/pod/util_test.go @@ -29,9 +29,6 @@ import ( "k8s.io/apimachinery/pkg/util/intstr" "k8s.io/apimachinery/pkg/util/sets" "k8s.io/apimachinery/pkg/util/validation/field" - utilfeature "k8s.io/apiserver/pkg/util/feature" - featuregatetesting "k8s.io/component-base/featuregate/testing" - "k8s.io/kubernetes/pkg/features" ) func TestFindPort(t *testing.T) { @@ -205,11 +202,10 @@ func TestFindPort(t *testing.T) { func TestVisitContainers(t *testing.T) { setAllFeatureEnabledContainersDuringTest := ContainerType(0) testCases := []struct { - desc string - spec *v1.PodSpec - wantContainers []string - mask ContainerType - ephemeralContainersEnabled bool + desc string + spec *v1.PodSpec + wantContainers []string + mask ContainerType }{ { desc: "empty podspec", @@ -294,26 +290,7 @@ func TestVisitContainers(t *testing.T) { mask: AllContainers, }, { - desc: "all feature enabled container types with ephemeral containers disabled", - spec: &v1.PodSpec{ - Containers: []v1.Container{ - {Name: "c1"}, - {Name: "c2"}, - }, - InitContainers: []v1.Container{ - {Name: "i1"}, - {Name: "i2"}, - }, - EphemeralContainers: []v1.EphemeralContainer{ - {EphemeralContainerCommon: v1.EphemeralContainerCommon{Name: "e1"}}, - {EphemeralContainerCommon: v1.EphemeralContainerCommon{Name: "e2"}}, - }, - }, - wantContainers: []string{"i1", "i2", "c1", "c2"}, - mask: setAllFeatureEnabledContainersDuringTest, - }, - { - desc: "all feature enabled container types with ephemeral containers enabled", + desc: "all feature enabled container types", spec: &v1.PodSpec{ Containers: []v1.Container{ {Name: "c1"}, @@ -328,9 +305,8 @@ func TestVisitContainers(t *testing.T) { {EphemeralContainerCommon: v1.EphemeralContainerCommon{Name: "e2"}}, }, }, - wantContainers: []string{"i1", "i2", "c1", "c2", "e1", "e2"}, - mask: setAllFeatureEnabledContainersDuringTest, - ephemeralContainersEnabled: true, + wantContainers: []string{"i1", "i2", "c1", "c2", "e1", "e2"}, + mask: setAllFeatureEnabledContainersDuringTest, }, { desc: "dropping fields", @@ -355,8 +331,6 @@ func TestVisitContainers(t *testing.T) { for _, tc := range testCases { t.Run(tc.desc, func(t *testing.T) { - defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.EphemeralContainers, tc.ephemeralContainersEnabled)() - if tc.mask == setAllFeatureEnabledContainersDuringTest { tc.mask = AllFeatureEnabledContainers() } @@ -392,8 +366,6 @@ func TestVisitContainers(t *testing.T) { } func TestPodSecrets(t *testing.T) { - defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.EphemeralContainers, true)() - // Stub containing all possible secret references in a pod. // The names of the referenced secrets match struct paths detected by reflection. pod := &v1.Pod{ @@ -591,8 +563,6 @@ func collectResourcePaths(t *testing.T, resourcename string, path *field.Path, n } func TestPodConfigmaps(t *testing.T) { - defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.EphemeralContainers, true)() - // Stub containing all possible ConfigMap references in a pod. // The names of the referenced ConfigMaps match struct paths detected by reflection. pod := &v1.Pod{ diff --git a/pkg/apis/apps/validation/validation_test.go b/pkg/apis/apps/validation/validation_test.go index 6d34ea5a532..99147f00e9f 100644 --- a/pkg/apis/apps/validation/validation_test.go +++ b/pkg/apis/apps/validation/validation_test.go @@ -2396,8 +2396,6 @@ func TestValidateDaemonSetUpdate(t *testing.T) { } func TestValidateDaemonSet(t *testing.T) { - defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.EphemeralContainers, true)() - validSelector := map[string]string{"a": "b"} validPodTemplate := api.PodTemplate{ Template: api.PodTemplateSpec{ @@ -2660,8 +2658,6 @@ func validDeployment() *apps.Deployment { } func TestValidateDeployment(t *testing.T) { - defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.EphemeralContainers, true)() - successCases := []*apps.Deployment{ validDeployment(), } diff --git a/pkg/apis/core/pods/helpers.go b/pkg/apis/core/pods/helpers.go index e05a313a1f1..71810c5005c 100644 --- a/pkg/apis/core/pods/helpers.go +++ b/pkg/apis/core/pods/helpers.go @@ -20,9 +20,7 @@ import ( "fmt" "k8s.io/apimachinery/pkg/util/validation/field" - utilfeature "k8s.io/apiserver/pkg/util/feature" api "k8s.io/kubernetes/pkg/apis/core" - "k8s.io/kubernetes/pkg/features" "k8s.io/kubernetes/pkg/fieldpath" ) @@ -47,12 +45,10 @@ func VisitContainersWithPath(podSpec *api.PodSpec, specPath *field.Path, visitor return false } } - if utilfeature.DefaultFeatureGate.Enabled(features.EphemeralContainers) { - fldPath = specPath.Child("ephemeralContainers") - for i := range podSpec.EphemeralContainers { - if !visitor((*api.Container)(&podSpec.EphemeralContainers[i].EphemeralContainerCommon), fldPath.Index(i)) { - return false - } + fldPath = specPath.Child("ephemeralContainers") + for i := range podSpec.EphemeralContainers { + if !visitor((*api.Container)(&podSpec.EphemeralContainers[i].EphemeralContainerCommon), fldPath.Index(i)) { + return false } } return true diff --git a/pkg/apis/core/pods/helpers_test.go b/pkg/apis/core/pods/helpers_test.go index 1a357301b93..5552a55a720 100644 --- a/pkg/apis/core/pods/helpers_test.go +++ b/pkg/apis/core/pods/helpers_test.go @@ -21,15 +21,10 @@ import ( "testing" "k8s.io/apimachinery/pkg/util/validation/field" - utilfeature "k8s.io/apiserver/pkg/util/feature" - featuregatetesting "k8s.io/component-base/featuregate/testing" api "k8s.io/kubernetes/pkg/apis/core" - "k8s.io/kubernetes/pkg/features" ) func TestVisitContainersWithPath(t *testing.T) { - defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.EphemeralContainers, true)() - testCases := []struct { description string path *field.Path diff --git a/pkg/apis/core/validation/validation_test.go b/pkg/apis/core/validation/validation_test.go index ff7bc068445..0feda38c954 100644 --- a/pkg/apis/core/validation/validation_test.go +++ b/pkg/apis/core/validation/validation_test.go @@ -11485,8 +11485,6 @@ func makeValidService() core.Service { } func TestValidatePodEphemeralContainersUpdate(t *testing.T) { - defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.EphemeralContainers, true)() - makePod := func(ephemeralContainers []core.EphemeralContainer) *core.Pod { return &core.Pod{ ObjectMeta: metav1.ObjectMeta{ @@ -20312,7 +20310,6 @@ func TestValidateWindowsHostProcessPod(t *testing.T) { for _, testCase := range testCases { t.Run(testCase.name, func(t *testing.T) { defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.WindowsHostProcessContainers, testCase.featureEnabled)() - defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.EphemeralContainers, true)() opts := PodValidationOptions{AllowWindowsHostProcessField: testCase.featureEnabled} diff --git a/pkg/kubelet/container/helpers_test.go b/pkg/kubelet/container/helpers_test.go index 9e894b2072f..fcd5b6fb6ea 100644 --- a/pkg/kubelet/container/helpers_test.go +++ b/pkg/kubelet/container/helpers_test.go @@ -26,9 +26,6 @@ import ( v1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - utilfeature "k8s.io/apiserver/pkg/util/feature" - featuregatetesting "k8s.io/component-base/featuregate/testing" - "k8s.io/kubernetes/pkg/features" ) func TestEnvVarsToMap(t *testing.T) { @@ -326,7 +323,6 @@ func TestExpandVolumeMountsWithSubpath(t *testing.T) { } func TestGetContainerSpec(t *testing.T) { - defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.EphemeralContainers, true)() for _, tc := range []struct { name string havePod *v1.Pod diff --git a/pkg/kubelet/container/ref.go b/pkg/kubelet/container/ref.go index e4f860378a1..3d84a963e59 100644 --- a/pkg/kubelet/container/ref.go +++ b/pkg/kubelet/container/ref.go @@ -20,10 +20,8 @@ import ( "fmt" v1 "k8s.io/api/core/v1" - utilfeature "k8s.io/apiserver/pkg/util/feature" ref "k8s.io/client-go/tools/reference" "k8s.io/kubernetes/pkg/api/legacyscheme" - "k8s.io/kubernetes/pkg/features" ) // ImplicitContainerPrefix is a container name prefix that will indicate that container was started implicitly (like the pod infra container). @@ -67,15 +65,13 @@ func fieldPath(pod *v1.Pod, container *v1.Container) (string, error) { return fmt.Sprintf("spec.initContainers{%s}", here.Name), nil } } - if utilfeature.DefaultFeatureGate.Enabled(features.EphemeralContainers) { - for i := range pod.Spec.EphemeralContainers { - here := &pod.Spec.EphemeralContainers[i] - if here.Name == container.Name { - if here.Name == "" { - return fmt.Sprintf("spec.ephemeralContainers[%d]", i), nil - } - return fmt.Sprintf("spec.ephemeralContainers{%s}", here.Name), nil + for i := range pod.Spec.EphemeralContainers { + here := &pod.Spec.EphemeralContainers[i] + if here.Name == container.Name { + if here.Name == "" { + return fmt.Sprintf("spec.ephemeralContainers[%d]", i), nil } + return fmt.Sprintf("spec.ephemeralContainers{%s}", here.Name), nil } } return "", fmt.Errorf("container %q not found in pod %s/%s", container.Name, pod.Namespace, pod.Name) diff --git a/pkg/kubelet/kubelet_pods.go b/pkg/kubelet/kubelet_pods.go index a69558261e8..3ca002f458e 100644 --- a/pkg/kubelet/kubelet_pods.go +++ b/pkg/kubelet/kubelet_pods.go @@ -1221,7 +1221,7 @@ func (kl *Kubelet) validateContainerLogStatus(podName string, podStatus *v1.PodS if !found { cStatus, found = podutil.GetContainerStatus(podStatus.InitContainerStatuses, containerName) } - if !found && utilfeature.DefaultFeatureGate.Enabled(features.EphemeralContainers) { + if !found { cStatus, found = podutil.GetContainerStatus(podStatus.EphemeralContainerStatuses, containerName) } if !found { @@ -1602,23 +1602,21 @@ func (kl *Kubelet) convertStatusToAPIStatus(pod *v1.Pod, podStatus *kubecontaine len(pod.Spec.InitContainers) > 0, true, ) - if utilfeature.DefaultFeatureGate.Enabled(features.EphemeralContainers) { - var ecSpecs []v1.Container - for i := range pod.Spec.EphemeralContainers { - ecSpecs = append(ecSpecs, v1.Container(pod.Spec.EphemeralContainers[i].EphemeralContainerCommon)) - } - - // #80875: By now we've iterated podStatus 3 times. We could refactor this to make a single - // pass through podStatus.ContainerStatuses - apiPodStatus.EphemeralContainerStatuses = kl.convertToAPIContainerStatuses( - pod, podStatus, - oldPodStatus.EphemeralContainerStatuses, - ecSpecs, - len(pod.Spec.InitContainers) > 0, - false, - ) + var ecSpecs []v1.Container + for i := range pod.Spec.EphemeralContainers { + ecSpecs = append(ecSpecs, v1.Container(pod.Spec.EphemeralContainers[i].EphemeralContainerCommon)) } + // #80875: By now we've iterated podStatus 3 times. We could refactor this to make a single + // pass through podStatus.ContainerStatuses + apiPodStatus.EphemeralContainerStatuses = kl.convertToAPIContainerStatuses( + pod, podStatus, + oldPodStatus.EphemeralContainerStatuses, + ecSpecs, + len(pod.Spec.InitContainers) > 0, + false, + ) + return &apiPodStatus } diff --git a/pkg/kubelet/kuberuntime/kuberuntime_container.go b/pkg/kubelet/kuberuntime/kuberuntime_container.go index 1ea7723f813..eaa85c39f13 100644 --- a/pkg/kubelet/kuberuntime/kuberuntime_container.go +++ b/pkg/kubelet/kuberuntime/kuberuntime_container.go @@ -46,9 +46,7 @@ import ( kubetypes "k8s.io/apimachinery/pkg/types" utilruntime "k8s.io/apimachinery/pkg/util/runtime" "k8s.io/apimachinery/pkg/util/sets" - utilfeature "k8s.io/apiserver/pkg/util/feature" runtimeapi "k8s.io/cri-api/pkg/apis/runtime/v1" - "k8s.io/kubernetes/pkg/features" kubecontainer "k8s.io/kubernetes/pkg/kubelet/container" "k8s.io/kubernetes/pkg/kubelet/cri/remote" "k8s.io/kubernetes/pkg/kubelet/events" @@ -120,7 +118,7 @@ func ephemeralContainerStartSpec(ec *v1.EphemeralContainer) *startSpec { // usually isn't a problem since ephemeral containers aren't allowed at pod creation time. // This always returns nil when the EphemeralContainers feature is disabled. func (s *startSpec) getTargetID(podStatus *kubecontainer.PodStatus) (*kubecontainer.ContainerID, error) { - if s.ephemeralContainer == nil || s.ephemeralContainer.TargetContainerName == "" || !utilfeature.DefaultFeatureGate.Enabled(features.EphemeralContainers) { + if s.ephemeralContainer == nil || s.ephemeralContainer.TargetContainerName == "" { return nil, nil } diff --git a/pkg/kubelet/kuberuntime/kuberuntime_container_linux_test.go b/pkg/kubelet/kuberuntime/kuberuntime_container_linux_test.go index 29d0bbfc9b4..307a40d0188 100644 --- a/pkg/kubelet/kuberuntime/kuberuntime_container_linux_test.go +++ b/pkg/kubelet/kuberuntime/kuberuntime_container_linux_test.go @@ -520,7 +520,6 @@ func TestGetHugepageLimitsFromResources(t *testing.T) { } func TestGenerateLinuxContainerConfigNamespaces(t *testing.T) { - defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.EphemeralContainers, true)() _, _, m, err := createTestRuntimeManager() if err != nil { t.Fatalf("error creating test RuntimeManager: %v", err) diff --git a/pkg/kubelet/kuberuntime/kuberuntime_container_test.go b/pkg/kubelet/kuberuntime/kuberuntime_container_test.go index 91d73097611..115b0a6f676 100644 --- a/pkg/kubelet/kuberuntime/kuberuntime_container_test.go +++ b/pkg/kubelet/kuberuntime/kuberuntime_container_test.go @@ -17,7 +17,6 @@ limitations under the License. package kuberuntime import ( - "fmt" "io/ioutil" "os" "path/filepath" @@ -32,10 +31,7 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" v1 "k8s.io/api/core/v1" - utilfeature "k8s.io/apiserver/pkg/util/feature" - featuregatetesting "k8s.io/component-base/featuregate/testing" runtimeapi "k8s.io/cri-api/pkg/apis/runtime/v1" - "k8s.io/kubernetes/pkg/features" kubecontainer "k8s.io/kubernetes/pkg/kubelet/container" containertest "k8s.io/kubernetes/pkg/kubelet/container/testing" "k8s.io/kubernetes/pkg/kubelet/lifecycle" @@ -405,23 +401,12 @@ func TestStartSpec(t *testing.T) { }, } { t.Run(tc.name, func(t *testing.T) { - defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.EphemeralContainers, true)() if got, err := tc.spec.getTargetID(podStatus); err != nil { t.Fatalf("%v: getTargetID got unexpected error: %v", t.Name(), err) } else if diff := cmp.Diff(tc.want, got); diff != "" { t.Errorf("%v: getTargetID got unexpected result. diff:\n%v", t.Name(), diff) } }) - - // Test with feature disabled in self-contained section which can be removed when feature flag is removed. - t.Run(fmt.Sprintf("%s (disabled)", tc.name), func(t *testing.T) { - defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.EphemeralContainers, false)() - if got, err := tc.spec.getTargetID(podStatus); err != nil { - t.Fatalf("%v: getTargetID got unexpected error: %v", t.Name(), err) - } else if got != nil { - t.Errorf("%v: getTargetID got: %v, wanted nil", t.Name(), got) - } - }) } } diff --git a/pkg/kubelet/kuberuntime/kuberuntime_manager.go b/pkg/kubelet/kuberuntime/kuberuntime_manager.go index 6b2761a38e1..dedb35042a3 100644 --- a/pkg/kubelet/kuberuntime/kuberuntime_manager.go +++ b/pkg/kubelet/kuberuntime/kuberuntime_manager.go @@ -578,14 +578,12 @@ func (m *kubeGenericRuntimeManager) computePodActions(pod *v1.Pod, podStatus *ku } // Ephemeral containers may be started even if initialization is not yet complete. - if utilfeature.DefaultFeatureGate.Enabled(features.EphemeralContainers) { - for i := range pod.Spec.EphemeralContainers { - c := (*v1.Container)(&pod.Spec.EphemeralContainers[i].EphemeralContainerCommon) + for i := range pod.Spec.EphemeralContainers { + c := (*v1.Container)(&pod.Spec.EphemeralContainers[i].EphemeralContainerCommon) - // Ephemeral Containers are never restarted - if podStatus.FindContainerStatusByName(c.Name) == nil { - changes.EphemeralContainersToStart = append(changes.EphemeralContainersToStart, i) - } + // Ephemeral Containers are never restarted + if podStatus.FindContainerStatusByName(c.Name) == nil { + changes.EphemeralContainersToStart = append(changes.EphemeralContainersToStart, i) } } @@ -914,10 +912,8 @@ func (m *kubeGenericRuntimeManager) SyncPod(pod *v1.Pod, podStatus *kubecontaine // These are started "prior" to init containers to allow running ephemeral containers even when there // are errors starting an init container. In practice init containers will start first since ephemeral // containers cannot be specified on pod creation. - if utilfeature.DefaultFeatureGate.Enabled(features.EphemeralContainers) { - for _, idx := range podContainerChanges.EphemeralContainersToStart { - start("ephemeral container", metrics.EphemeralContainer, ephemeralContainerStartSpec(&pod.Spec.EphemeralContainers[idx])) - } + for _, idx := range podContainerChanges.EphemeralContainersToStart { + start("ephemeral container", metrics.EphemeralContainer, ephemeralContainerStartSpec(&pod.Spec.EphemeralContainers[idx])) } // Step 6: start the init container. diff --git a/pkg/kubelet/kuberuntime/kuberuntime_manager_test.go b/pkg/kubelet/kuberuntime/kuberuntime_manager_test.go index 8bec90c8f84..8e2daef2810 100644 --- a/pkg/kubelet/kuberuntime/kuberuntime_manager_test.go +++ b/pkg/kubelet/kuberuntime/kuberuntime_manager_test.go @@ -35,14 +35,11 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/util/sets" - utilfeature "k8s.io/apiserver/pkg/util/feature" "k8s.io/client-go/util/flowcontrol" - featuregatetesting "k8s.io/component-base/featuregate/testing" runtimeapi "k8s.io/cri-api/pkg/apis/runtime/v1" apitest "k8s.io/cri-api/pkg/apis/testing" podutil "k8s.io/kubernetes/pkg/api/v1/pod" "k8s.io/kubernetes/pkg/credentialprovider" - "k8s.io/kubernetes/pkg/features" kubecontainer "k8s.io/kubernetes/pkg/kubelet/container" containertest "k8s.io/kubernetes/pkg/kubelet/container/testing" proberesults "k8s.io/kubernetes/pkg/kubelet/prober/results" @@ -490,9 +487,6 @@ func TestGetPods(t *testing.T) { } func TestKillPod(t *testing.T) { - // Tests that KillPod also kills Ephemeral Containers - defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.EphemeralContainers, true)() - fakeRuntime, _, m, err := createTestRuntimeManager() assert.NoError(t, err) @@ -1372,7 +1366,6 @@ func makeBasePodAndStatusWithInitContainers() (*v1.Pod, *kubecontainer.PodStatus } func TestComputePodActionsWithInitAndEphemeralContainers(t *testing.T) { - defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.EphemeralContainers, true)() // Make sure existing test cases pass with feature enabled TestComputePodActions(t) TestComputePodActionsWithInitContainers(t) diff --git a/pkg/kubelet/pod/pod_manager.go b/pkg/kubelet/pod/pod_manager.go index ce342ac7209..2eeb4788af8 100644 --- a/pkg/kubelet/pod/pod_manager.go +++ b/pkg/kubelet/pod/pod_manager.go @@ -22,8 +22,6 @@ import ( v1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/types" - utilfeature "k8s.io/apiserver/pkg/util/feature" - "k8s.io/kubernetes/pkg/features" "k8s.io/kubernetes/pkg/kubelet/configmap" kubecontainer "k8s.io/kubernetes/pkg/kubelet/container" "k8s.io/kubernetes/pkg/kubelet/metrics" @@ -162,10 +160,6 @@ func (pm *basicManager) UpdatePod(pod *v1.Pod) { // updateMetrics updates the metrics surfaced by the pod manager. // oldPod or newPod may be nil to signify creation or deletion. func updateMetrics(oldPod, newPod *v1.Pod) { - if !utilfeature.DefaultFeatureGate.Enabled(features.EphemeralContainers) { - return - } - var numEC int if oldPod != nil { numEC -= len(oldPod.Spec.EphemeralContainers) diff --git a/pkg/kubelet/server/server.go b/pkg/kubelet/server/server.go index 4c31bb6a4ac..95e9f287222 100644 --- a/pkg/kubelet/server/server.go +++ b/pkg/kubelet/server/server.go @@ -916,7 +916,7 @@ func (s *Server) checkpoint(request *restful.Request, response *restful.Response } } } - if !found && utilfeature.DefaultFeatureGate.Enabled(features.EphemeralContainers) { + if !found { for _, container := range pod.Spec.EphemeralContainers { if container.Name == containerName { found = true diff --git a/pkg/registry/core/pod/storage/storage.go b/pkg/registry/core/pod/storage/storage.go index c426b8727ed..27af1f4d9ed 100644 --- a/pkg/registry/core/pod/storage/storage.go +++ b/pkg/registry/core/pod/storage/storage.go @@ -33,12 +33,10 @@ import ( "k8s.io/apiserver/pkg/storage" storeerr "k8s.io/apiserver/pkg/storage/errors" "k8s.io/apiserver/pkg/util/dryrun" - utilfeature "k8s.io/apiserver/pkg/util/feature" policyclient "k8s.io/client-go/kubernetes/typed/policy/v1" podutil "k8s.io/kubernetes/pkg/api/pod" api "k8s.io/kubernetes/pkg/apis/core" "k8s.io/kubernetes/pkg/apis/core/validation" - "k8s.io/kubernetes/pkg/features" "k8s.io/kubernetes/pkg/kubelet/client" "k8s.io/kubernetes/pkg/printers" printersinternal "k8s.io/kubernetes/pkg/printers/internalversion" @@ -330,10 +328,6 @@ var _ = rest.Patcher(&EphemeralContainersREST{}) // Get retrieves the object from the storage. It is required to support Patch. func (r *EphemeralContainersREST) Get(ctx context.Context, name string, options *metav1.GetOptions) (runtime.Object, error) { - if !utilfeature.DefaultFeatureGate.Enabled(features.EphemeralContainers) { - return nil, errors.NewBadRequest("feature EphemeralContainers disabled") - } - return r.store.Get(ctx, name, options) } @@ -350,10 +344,6 @@ func (r *EphemeralContainersREST) Destroy() { // Update alters the EphemeralContainers field in PodSpec func (r *EphemeralContainersREST) Update(ctx context.Context, name string, objInfo rest.UpdatedObjectInfo, createValidation rest.ValidateObjectFunc, updateValidation rest.ValidateObjectUpdateFunc, forceAllowCreate bool, options *metav1.UpdateOptions) (runtime.Object, bool, error) { - if !utilfeature.DefaultFeatureGate.Enabled(features.EphemeralContainers) { - return nil, false, errors.NewBadRequest("feature EphemeralContainers disabled") - } - // We are explicitly setting forceAllowCreate to false in the call to the underlying storage because // subresources should never allow create on update. return r.store.Update(ctx, name, objInfo, createValidation, updateValidation, false, options) diff --git a/pkg/registry/core/pod/strategy_test.go b/pkg/registry/core/pod/strategy_test.go index 742578e734a..7e6022e7598 100644 --- a/pkg/registry/core/pod/strategy_test.go +++ b/pkg/registry/core/pod/strategy_test.go @@ -35,12 +35,9 @@ import ( "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/types" genericapirequest "k8s.io/apiserver/pkg/endpoints/request" - utilfeature "k8s.io/apiserver/pkg/util/feature" "k8s.io/client-go/tools/cache" - featuregatetesting "k8s.io/component-base/featuregate/testing" apitesting "k8s.io/kubernetes/pkg/api/testing" api "k8s.io/kubernetes/pkg/apis/core" - "k8s.io/kubernetes/pkg/features" "k8s.io/kubernetes/pkg/kubelet/client" utilpointer "k8s.io/utils/pointer" @@ -355,7 +352,6 @@ func (g mockPodGetter) Get(context.Context, string, *metav1.GetOptions) (runtime } func TestCheckLogLocation(t *testing.T) { - defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.EphemeralContainers, true)() ctx := genericapirequest.NewDefaultContext() fakePodName := "test" tcs := []struct { diff --git a/pkg/registry/core/rest/storage_core.go b/pkg/registry/core/rest/storage_core.go index c9f8e039136..206e87e8909 100644 --- a/pkg/registry/core/rest/storage_core.go +++ b/pkg/registry/core/rest/storage_core.go @@ -36,13 +36,11 @@ import ( genericapiserver "k8s.io/apiserver/pkg/server" serverstorage "k8s.io/apiserver/pkg/server/storage" "k8s.io/apiserver/pkg/storage/etcd3" - utilfeature "k8s.io/apiserver/pkg/util/feature" policyclient "k8s.io/client-go/kubernetes/typed/policy/v1" restclient "k8s.io/client-go/rest" "k8s.io/kubernetes/pkg/api/legacyscheme" api "k8s.io/kubernetes/pkg/apis/core" "k8s.io/kubernetes/pkg/cluster/ports" - "k8s.io/kubernetes/pkg/features" kubeletclient "k8s.io/kubernetes/pkg/kubelet/client" "k8s.io/kubernetes/pkg/registry/core/componentstatus" configmapstore "k8s.io/kubernetes/pkg/registry/core/configmap/storage" @@ -291,9 +289,7 @@ func (c LegacyRESTStorageProvider) NewLegacyRESTStorage(apiResourceConfigSource if podStorage.Eviction != nil { storage[resource+"/eviction"] = podStorage.Eviction } - if utilfeature.DefaultFeatureGate.Enabled(features.EphemeralContainers) { - storage[resource+"/ephemeralcontainers"] = podStorage.EphemeralContainers - } + storage[resource+"/ephemeralcontainers"] = podStorage.EphemeralContainers } if resource := "bindings"; apiResourceConfigSource.ResourceEnabled(corev1.SchemeGroupVersion.WithResource(resource)) { diff --git a/pkg/volume/util/util_test.go b/pkg/volume/util/util_test.go index 715838c5e31..9b7e7559144 100644 --- a/pkg/volume/util/util_test.go +++ b/pkg/volume/util/util_test.go @@ -28,10 +28,7 @@ import ( "k8s.io/apimachinery/pkg/api/resource" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/util/sets" - utilfeature "k8s.io/apiserver/pkg/util/feature" - featuregatetesting "k8s.io/component-base/featuregate/testing" _ "k8s.io/kubernetes/pkg/apis/core/install" - "k8s.io/kubernetes/pkg/features" "k8s.io/kubernetes/pkg/util/slice" "k8s.io/kubernetes/pkg/volume" utilptr "k8s.io/utils/pointer" @@ -581,7 +578,6 @@ func TestMakeAbsolutePath(t *testing.T) { } func TestGetPodVolumeNames(t *testing.T) { - defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.EphemeralContainers, true)() tests := []struct { name string pod *v1.Pod diff --git a/test/e2e/common/node/ephemeral_containers.go b/test/e2e/common/node/ephemeral_containers.go index 066652eb1c1..69899ddf7d7 100644 --- a/test/e2e/common/node/ephemeral_containers.go +++ b/test/e2e/common/node/ephemeral_containers.go @@ -20,12 +20,10 @@ import ( "time" v1 "k8s.io/api/core/v1" - apierrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/kubernetes/pkg/kubelet/util/format" "k8s.io/kubernetes/test/e2e/framework" e2epod "k8s.io/kubernetes/test/e2e/framework/pod" - e2eskipper "k8s.io/kubernetes/test/e2e/framework/skipper" imageutils "k8s.io/kubernetes/test/utils/image" admissionapi "k8s.io/pod-security-admission/api" @@ -69,11 +67,6 @@ var _ = SIGDescribe("Ephemeral Containers [NodeConformance]", func() { }, } err := podClient.AddEphemeralContainerSync(pod, ec, time.Minute) - // BEGIN TODO: Remove when EphemeralContainers feature gate is retired. - if apierrors.IsNotFound(err) { - e2eskipper.Skipf("Skipping test because EphemeralContainers feature disabled (error: %q)", err) - } - // END TODO: Remove when EphemeralContainers feature gate is retired. framework.ExpectNoError(err, "Failed to patch ephemeral containers in pod %q", format.Pod(pod)) ginkgo.By("checking pod container endpoints") diff --git a/test/e2e/framework/util.go b/test/e2e/framework/util.go index 3429ec2ba1a..54bde0cb964 100644 --- a/test/e2e/framework/util.go +++ b/test/e2e/framework/util.go @@ -50,7 +50,6 @@ import ( "k8s.io/apimachinery/pkg/util/uuid" "k8s.io/apimachinery/pkg/util/wait" "k8s.io/apimachinery/pkg/watch" - utilfeature "k8s.io/apiserver/pkg/util/feature" "k8s.io/client-go/dynamic" clientset "k8s.io/client-go/kubernetes" restclient "k8s.io/client-go/rest" @@ -58,7 +57,6 @@ import ( "k8s.io/client-go/tools/clientcmd" clientcmdapi "k8s.io/client-go/tools/clientcmd/api" watchtools "k8s.io/client-go/tools/watch" - "k8s.io/component-base/featuregate" testutils "k8s.io/kubernetes/test/utils" imageutils "k8s.io/kubernetes/test/utils/image" uexec "k8s.io/utils/exec" @@ -776,8 +774,6 @@ func (f *Framework) testContainerOutputMatcher(scenarioName string, type ContainerType int const ( - // FeatureEphemeralContainers allows running an ephemeral container in pod namespaces to troubleshoot a running pod - FeatureEphemeralContainers featuregate.Feature = "EphemeralContainers" // Containers is for normal containers Containers ContainerType = 1 << iota // InitContainers is for init containers @@ -790,11 +786,7 @@ const ( // types except for the ones guarded by feature gate. // Copied from pkg/api/v1/pod to avoid pulling extra dependencies func allFeatureEnabledContainers() ContainerType { - containerType := AllContainers - if !utilfeature.DefaultFeatureGate.Enabled(FeatureEphemeralContainers) { - containerType &= ^EphemeralContainers - } - return containerType + return AllContainers } // ContainerVisitor is called with each container spec, and returns true diff --git a/test/e2e/framework/volume/fixtures.go b/test/e2e/framework/volume/fixtures.go index 54d0418a415..bba6fa05365 100644 --- a/test/e2e/framework/volume/fixtures.go +++ b/test/e2e/framework/volume/fixtures.go @@ -609,12 +609,6 @@ func testVolumeClient(f *framework.Framework, config TestConfig, fsGroup *int64, ec.Name = "volume-ephemeral-container" err = f.PodClient().AddEphemeralContainerSync(clientPod, ec, timeouts.PodStart) // The API server will return NotFound for the subresource when the feature is disabled - // BEGIN TODO: remove after EphemeralContainers feature gate is retired - if apierrors.IsNotFound(err) { - framework.Logf("Skipping ephemeral container re-test because feature is disabled (error: %q)", err) - return - } - // END TODO: remove after EphemeralContainers feature gate is retired framework.ExpectNoError(err, "failed to add ephemeral container for re-test") testVolumeContent(f, clientPod, ec.Name, fsGroup, fsType, tests) } diff --git a/test/integration/apiserver/admissionwebhook/admission_test.go b/test/integration/apiserver/admissionwebhook/admission_test.go index eee81848208..64f612f996e 100644 --- a/test/integration/apiserver/admissionwebhook/admission_test.go +++ b/test/integration/apiserver/admissionwebhook/admission_test.go @@ -491,7 +491,7 @@ func testWebhookAdmission(t *testing.T, watchCache bool) { // force enable all resources so we can check storage. "--runtime-config=api/all=true", // enable feature-gates that protect resources to check their storage, too. - "--feature-gates=EphemeralContainers=true", + // e.g. "--feature-gates=EphemeralContainers=true", }, etcdConfig) defer server.TearDownFn() diff --git a/test/integration/pods/pods_test.go b/test/integration/pods/pods_test.go index 7f69d6a11fe..225ff46b10e 100644 --- a/test/integration/pods/pods_test.go +++ b/test/integration/pods/pods_test.go @@ -23,15 +23,11 @@ import ( "testing" v1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/types" - utilfeature "k8s.io/apiserver/pkg/util/feature" clientset "k8s.io/client-go/kubernetes" typedv1 "k8s.io/client-go/kubernetes/typed/core/v1" - featuregatetesting "k8s.io/component-base/featuregate/testing" kubeapiservertesting "k8s.io/kubernetes/cmd/kube-apiserver/app/testing" - "k8s.io/kubernetes/pkg/features" "k8s.io/kubernetes/test/integration" "k8s.io/kubernetes/test/integration/framework" ) @@ -190,8 +186,6 @@ func TestPodReadOnlyFilesystem(t *testing.T) { } func TestPodCreateEphemeralContainers(t *testing.T) { - defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.EphemeralContainers, true)() - // Disable ServiceAccount admission plugin as we don't have serviceaccount controller running. server := kubeapiservertesting.StartTestServerOrDie(t, nil, []string{"--disable-admission-plugins=ServiceAccount"}, framework.SharedEtcd()) defer server.TearDownFn() @@ -261,8 +255,6 @@ func setUpEphemeralContainers(podsClient typedv1.PodInterface, pod *v1.Pod, cont } func TestPodPatchEphemeralContainers(t *testing.T) { - defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.EphemeralContainers, true)() - // Disable ServiceAccount admission plugin as we don't have serviceaccount controller running. server := kubeapiservertesting.StartTestServerOrDie(t, nil, []string{"--disable-admission-plugins=ServiceAccount"}, framework.SharedEtcd()) defer server.TearDownFn() @@ -494,8 +486,6 @@ func TestPodPatchEphemeralContainers(t *testing.T) { } func TestPodUpdateEphemeralContainers(t *testing.T) { - defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.EphemeralContainers, true)() - // Disable ServiceAccount admission plugin as we don't have serviceaccount controller running. server := kubeapiservertesting.StartTestServerOrDie(t, nil, []string{"--disable-admission-plugins=ServiceAccount"}, framework.SharedEtcd()) defer server.TearDownFn() @@ -684,61 +674,3 @@ func TestPodUpdateEphemeralContainers(t *testing.T) { integration.DeletePodOrErrorf(t, client, ns.Name, pod.Name) } } - -// TestPodEphemeralContainersDisabled tests that the API server returns a 404 when the feature is disabled (because the subresource won't exist). -// This validates that the feature gate is working, but kubectl also uses the 404 to guess that the feature is disabled on the server. -func TestPodEphemeralContainersDisabled(t *testing.T) { - defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.EphemeralContainers, false)() - - // Disable ServiceAccount admission plugin as we don't have serviceaccount controller running. - server := kubeapiservertesting.StartTestServerOrDie(t, nil, []string{"--disable-admission-plugins=ServiceAccount"}, framework.SharedEtcd()) - defer server.TearDownFn() - - client := clientset.NewForConfigOrDie(server.ClientConfig) - - ns := framework.CreateNamespaceOrDie(client, "pod-ephemeral-containers-disabled", t) - defer framework.DeleteNamespaceOrDie(client, ns, t) - - pod := &v1.Pod{ - ObjectMeta: metav1.ObjectMeta{ - Name: "ephemeral-container-pod", - }, - Spec: v1.PodSpec{ - Containers: []v1.Container{ - { - Name: "fake-name", - Image: "fakeimage", - }, - }, - }, - } - pod, err := setUpEphemeralContainers(client.CoreV1().Pods(ns.Name), pod, nil) - if err != nil { - t.Fatal(err) - } - defer integration.DeletePodOrErrorf(t, client, ns.Name, pod.Name) - - pod.Spec.EphemeralContainers = append(pod.Spec.EphemeralContainers, v1.EphemeralContainer{ - EphemeralContainerCommon: v1.EphemeralContainerCommon{ - Name: "debugger", - Image: "debugimage", - ImagePullPolicy: "Always", - TerminationMessagePolicy: "File", - }, - }) - - if _, err = client.CoreV1().Pods(ns.Name).UpdateEphemeralContainers(context.TODO(), pod.Name, pod, metav1.UpdateOptions{}); err == nil { - t.Fatalf("got nil error when updating ephemeral containers with feature disabled, wanted %q", metav1.StatusReasonNotFound) - } - - se, ok := err.(*errors.StatusError) - if !ok { - t.Fatalf("got error %#v, expected StatusError", err) - } - if se.ErrStatus.Reason != metav1.StatusReasonNotFound { - t.Errorf("got error reason %q when updating ephemeral containers with feature disabled, want %q: %#v", se.ErrStatus.Reason, metav1.StatusReasonNotFound, se) - } - if se.ErrStatus.Details.Name != "" { - t.Errorf("got error details with name %q, want %q: %#v", se.ErrStatus.Details.Name, "", se) - } -}