From 1a7630c09799a7c39ae02e3f03f5e7add3089941 Mon Sep 17 00:00:00 2001 From: Gunju Kim Date: Fri, 25 Apr 2025 15:50:25 +0900 Subject: [PATCH] Remove deprecated LegacySidecarContainers feature gate --- pkg/features/kube_features.go | 13 - .../kuberuntime/kuberuntime_container.go | 63 --- .../kuberuntime/kuberuntime_manager.go | 119 ++---- .../kuberuntime/kuberuntime_manager_test.go | 403 ------------------ .../reference/versioned_feature_list.yaml | 10 - 5 files changed, 25 insertions(+), 583 deletions(-) diff --git a/pkg/features/kube_features.go b/pkg/features/kube_features.go index 1e2366b9aae..cfa832643cf 100644 --- a/pkg/features/kube_features.go +++ b/pkg/features/kube_features.go @@ -490,14 +490,6 @@ const ( // Add support for distributed tracing in the kubelet KubeletTracing featuregate.Feature = "KubeletTracing" - // owner: @gjkim42 - // - // Enable legacy code path in pkg/kubelet/kuberuntime that predates the - // SidecarContainers feature. This temporary feature gate is disabled by - // default and intended to safely remove the redundant code path. This is - // only available in v1.33 and will be removed in v1.34. - LegacySidecarContainers featuregate.Feature = "LegacySidecarContainers" - // owner: @Sh4d1,@RyanAoh,@rikatz // kep: http://kep.k8s.io/1860 // LoadBalancerIPMode enables the IPMode field in the LoadBalancerIngress status of a Service @@ -1338,11 +1330,6 @@ var defaultVersionedKubernetesFeatureGates = map[featuregate.Feature]featuregate {Version: version.MustParse("1.34"), Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.37 }, - LegacySidecarContainers: { - {Version: version.MustParse("1.0"), Default: true, PreRelease: featuregate.GA}, - {Version: version.MustParse("1.33"), Default: false, PreRelease: featuregate.Deprecated}, - }, - LoadBalancerIPMode: { {Version: version.MustParse("1.29"), Default: false, PreRelease: featuregate.Alpha}, {Version: version.MustParse("1.30"), Default: true, PreRelease: featuregate.Beta}, diff --git a/pkg/kubelet/kuberuntime/kuberuntime_container.go b/pkg/kubelet/kuberuntime/kuberuntime_container.go index c20faf416b5..82c1529184f 100644 --- a/pkg/kubelet/kuberuntime/kuberuntime_container.go +++ b/pkg/kubelet/kuberuntime/kuberuntime_container.go @@ -974,65 +974,6 @@ func (m *kubeGenericRuntimeManager) purgeInitContainers(ctx context.Context, pod } } -// findNextInitContainerToRun returns the status of the last failed container, the -// index of next init container to start, or done if there are no further init containers. -// Status is only returned if an init container is failed, in which case next will -// point to the current container. -// TODO: Remove this function as this is a subset of the -// computeInitContainerActions. -func findNextInitContainerToRun(pod *v1.Pod, podStatus *kubecontainer.PodStatus) (status *kubecontainer.Status, next *v1.Container, done bool) { - if len(pod.Spec.InitContainers) == 0 { - return nil, nil, true - } - - // If any of the main containers have status and are Running, then all init containers must - // have been executed at some point in the past. However, they could have been removed - // from the container runtime now, and if we proceed, it would appear as if they - // never ran and will re-execute improperly. - for i := range pod.Spec.Containers { - container := &pod.Spec.Containers[i] - status := podStatus.FindContainerStatusByName(container.Name) - if status != nil && status.State == kubecontainer.ContainerStateRunning { - return nil, nil, true - } - } - - // If there are failed containers, return the status of the last failed one. - for i := len(pod.Spec.InitContainers) - 1; i >= 0; i-- { - container := &pod.Spec.InitContainers[i] - status := podStatus.FindContainerStatusByName(container.Name) - if status != nil && isInitContainerFailed(status) { - return status, container, false - } - } - - // There are no failed containers now. - for i := len(pod.Spec.InitContainers) - 1; i >= 0; i-- { - container := &pod.Spec.InitContainers[i] - status := podStatus.FindContainerStatusByName(container.Name) - if status == nil { - continue - } - - // container is still running, return not done. - if status.State == kubecontainer.ContainerStateRunning { - return nil, nil, false - } - - if status.State == kubecontainer.ContainerStateExited { - // all init containers successful - if i == (len(pod.Spec.InitContainers) - 1) { - return nil, nil, true - } - - // all containers up to i successful, go to i+1 - return nil, &pod.Spec.InitContainers[i+1], false - } - } - - return nil, &pod.Spec.InitContainers[0], false -} - // hasAnyRegularContainerCreated returns true if any regular container has been // created, which indicates all init containers have been initialized. func hasAnyRegularContainerCreated(pod *v1.Pod, podStatus *kubecontainer.PodStatus) bool { @@ -1062,10 +1003,6 @@ func hasAnyRegularContainerCreated(pod *v1.Pod, podStatus *kubecontainer.PodStat // - Start the first init container that has not been started. // - Restart all restartable init containers that have started but are not running. // - Kill the restartable init containers that are not alive or started. -// -// Note that this is a function for the SidecarContainers feature. -// Please sync with the findNextInitContainerToRun function if any changes are -// made, as either this or that function will be called. func (m *kubeGenericRuntimeManager) computeInitContainerActions(pod *v1.Pod, podStatus *kubecontainer.PodStatus, changes *podActions) bool { if len(pod.Spec.InitContainers) == 0 { return true diff --git a/pkg/kubelet/kuberuntime/kuberuntime_manager.go b/pkg/kubelet/kuberuntime/kuberuntime_manager.go index caa800c038f..c286e7a07b7 100644 --- a/pkg/kubelet/kuberuntime/kuberuntime_manager.go +++ b/pkg/kubelet/kuberuntime/kuberuntime_manager.go @@ -531,15 +531,9 @@ type podActions struct { // The attempt number of creating sandboxes for the pod. Attempt uint32 - // The next init container to start. - // TODO: Either this or InitContainersToStart will be used. Remove this - // field once it is not needed. - NextInitContainerToStart *v1.Container // InitContainersToStart keeps a list of indexes for the init containers to // start, where the index is the index of the specific init container in the // pod spec (pod.Spec.InitContainers). - // NOTE: This is a field for SidecarContainers feature. Either this or - // NextInitContainerToStart will be set. InitContainersToStart []int // ContainersToStart keeps a list of indexes for the containers to start, // where the index is the index of the specific container in the pod spec ( @@ -909,10 +903,6 @@ func (m *kubeGenericRuntimeManager) computePodActions(ctx context.Context, pod * ContainersToKill: make(map[kubecontainer.ContainerID]containerToKillInfo), } - // TODO: Remove handleRestartableInitContainers value with the - // LegacySidecarContainers feature gate. - handleRestartableInitContainers := types.HasRestartableInitContainer(pod) || !utilfeature.DefaultFeatureGate.Enabled(features.LegacySidecarContainers) - // If we need to (re-)create the pod sandbox, everything will need to be // killed and recreated, and init containers should be purged. if createPodSandbox { @@ -942,15 +932,10 @@ func (m *kubeGenericRuntimeManager) computePodActions(ctx context.Context, pod * // is done and there is no container to start. if len(containersToStart) == 0 { hasInitialized := false - // TODO: Remove this code path as logically it is the subset of the next - // code path. - if !handleRestartableInitContainers { - _, _, hasInitialized = findNextInitContainerToRun(pod, podStatus) - } else { - // If there is any regular container, it means all init containers have - // been initialized. - hasInitialized = hasAnyRegularContainerCreated(pod, podStatus) - } + + // If there is any regular container, it means all init containers have + // been initialized. + hasInitialized = hasAnyRegularContainerCreated(pod, podStatus) if hasInitialized { changes.CreateSandbox = false @@ -962,13 +947,7 @@ func (m *kubeGenericRuntimeManager) computePodActions(ctx context.Context, pod * // state. if len(pod.Spec.InitContainers) != 0 { // Pod has init containers, return the first one. - // TODO: Remove this code path as logically it is the subset of the next - // code path. - if !handleRestartableInitContainers { - changes.NextInitContainerToStart = &pod.Spec.InitContainers[0] - } else { - changes.InitContainersToStart = []int{0} - } + changes.InitContainersToStart = []int{0} return changes } @@ -991,40 +970,11 @@ func (m *kubeGenericRuntimeManager) computePodActions(ctx context.Context, pod * } // Check initialization progress. - // TODO: Remove this code path as logically it is the subset of the next - // code path. - if !handleRestartableInitContainers { - initLastStatus, next, done := findNextInitContainerToRun(pod, podStatus) - if !done { - if next != nil { - initFailed := initLastStatus != nil && isInitContainerFailed(initLastStatus) - if initFailed && !shouldRestartOnFailure(pod) { - changes.KillPod = true - } else { - // Always try to stop containers in unknown state first. - if initLastStatus != nil && initLastStatus.State == kubecontainer.ContainerStateUnknown { - changes.ContainersToKill[initLastStatus.ID] = containerToKillInfo{ - name: next.Name, - container: next, - message: fmt.Sprintf("Init container is in %q state, try killing it before restart", - initLastStatus.State), - reason: reasonUnknown, - } - } - changes.NextInitContainerToStart = next - } - } - // Initialization failed or still in progress. Skip inspecting non-init - // containers. - return changes - } - } else { - hasInitialized := m.computeInitContainerActions(pod, podStatus, &changes) - if changes.KillPod || !hasInitialized { - // Initialization failed or still in progress. Skip inspecting non-init - // containers. - return changes - } + hasInitialized := m.computeInitContainerActions(pod, podStatus, &changes) + if changes.KillPod || !hasInitialized { + // Initialization failed or still in progress. Skip inspecting non-init + // containers. + return changes } // Number of running containers to keep. @@ -1109,13 +1059,9 @@ func (m *kubeGenericRuntimeManager) computePodActions(ctx context.Context, pod * if keepCount == 0 && len(changes.ContainersToStart) == 0 { changes.KillPod = true - // TODO: Remove this code path as logically it is the subset of the next - // code path. - if handleRestartableInitContainers { - // To prevent the restartable init containers to keep pod alive, we should - // not restart them. - changes.InitContainersToStart = nil - } + // To prevent the restartable init containers to keep pod alive, we should + // not restart them. + changes.InitContainersToStart = nil } return changes @@ -1371,36 +1317,21 @@ func (m *kubeGenericRuntimeManager) SyncPod(ctx context.Context, pod *v1.Pod, po start(ctx, "ephemeral container", metrics.EphemeralContainer, ephemeralContainerStartSpec(&pod.Spec.EphemeralContainers[idx])) } - // TODO: Remove this code path as logically it is the subset of the next - // code path. - if !types.HasRestartableInitContainer(pod) && utilfeature.DefaultFeatureGate.Enabled(features.LegacySidecarContainers) { - // Step 6: start the init container. - if container := podContainerChanges.NextInitContainerToStart; container != nil { - // Start the next init container. - if err := start(ctx, "init container", metrics.InitContainer, containerStartSpec(container)); err != nil { - return + // Step 6: start init containers. + for _, idx := range podContainerChanges.InitContainersToStart { + container := &pod.Spec.InitContainers[idx] + // Start the next init container. + if err := start(ctx, "init container", metrics.InitContainer, containerStartSpec(container)); err != nil { + if podutil.IsRestartableInitContainer(container) { + klog.V(4).InfoS("Failed to start the restartable init container for the pod, skipping", "initContainerName", container.Name, "pod", klog.KObj(pod)) + continue } - - // Successfully started the container; clear the entry in the failure - klog.V(4).InfoS("Completed init container for pod", "containerName", container.Name, "pod", klog.KObj(pod)) + klog.V(4).InfoS("Failed to initialize the pod, as the init container failed to start, aborting", "initContainerName", container.Name, "pod", klog.KObj(pod)) + return } - } else { - // Step 6: start init containers. - for _, idx := range podContainerChanges.InitContainersToStart { - container := &pod.Spec.InitContainers[idx] - // Start the next init container. - if err := start(ctx, "init container", metrics.InitContainer, containerStartSpec(container)); err != nil { - if podutil.IsRestartableInitContainer(container) { - klog.V(4).InfoS("Failed to start the restartable init container for the pod, skipping", "initContainerName", container.Name, "pod", klog.KObj(pod)) - continue - } - klog.V(4).InfoS("Failed to initialize the pod, as the init container failed to start, aborting", "initContainerName", container.Name, "pod", klog.KObj(pod)) - return - } - // Successfully started the container; clear the entry in the failure - klog.V(4).InfoS("Completed init container for pod", "containerName", container.Name, "pod", klog.KObj(pod)) - } + // Successfully started the container; clear the entry in the failure + klog.V(4).InfoS("Completed init container for pod", "containerName", container.Name, "pod", klog.KObj(pod)) } // Step 7: For containers in podContainerChanges.ContainersToUpdate[CPU,Memory] list, invoke UpdateContainerResources diff --git a/pkg/kubelet/kuberuntime/kuberuntime_manager_test.go b/pkg/kubelet/kuberuntime/kuberuntime_manager_test.go index 21343efcb49..0d7c31efb76 100644 --- a/pkg/kubelet/kuberuntime/kuberuntime_manager_test.go +++ b/pkg/kubelet/kuberuntime/kuberuntime_manager_test.go @@ -57,7 +57,6 @@ import ( imagetypes "k8s.io/kubernetes/pkg/kubelet/images" "k8s.io/kubernetes/pkg/kubelet/metrics" proberesults "k8s.io/kubernetes/pkg/kubelet/prober/results" - kubelettypes "k8s.io/kubernetes/pkg/kubelet/types" "k8s.io/utils/ptr" ) @@ -1496,246 +1495,6 @@ func TestComputePodActionsWithInitContainers(t *testing.T) { } } -func TestComputePodActionsWithInitContainersWithLegacySidecarContainers(t *testing.T) { - _, _, m, err := createTestRuntimeManager() - require.NoError(t, err) - - // Creating a pair reference pod and status for the test cases to refer - // the specific fields. - basePod, baseStatus := makeBasePodAndStatusWithInitContainers() - noAction := podActions{ - SandboxID: baseStatus.SandboxStatuses[0].Id, - ContainersToStart: []int{}, - ContainersToKill: map[kubecontainer.ContainerID]containerToKillInfo{}, - } - - for desc, test := range map[string]struct { - mutatePodFn func(*v1.Pod) - mutateStatusFn func(*kubecontainer.PodStatus) - actions podActions - }{ - "initialization completed; start all containers": { - actions: podActions{ - SandboxID: baseStatus.SandboxStatuses[0].Id, - ContainersToStart: []int{0, 1, 2}, - ContainersToKill: getKillMapWithInitContainers(basePod, baseStatus, []int{}), - }, - }, - "no init containers have been started; start the first one": { - mutateStatusFn: func(status *kubecontainer.PodStatus) { - status.ContainerStatuses = nil - }, - actions: podActions{ - SandboxID: baseStatus.SandboxStatuses[0].Id, - NextInitContainerToStart: &basePod.Spec.InitContainers[0], - InitContainersToStart: []int{0}, - ContainersToStart: []int{}, - ContainersToKill: getKillMapWithInitContainers(basePod, baseStatus, []int{}), - }, - }, - "initialization in progress; do nothing": { - mutatePodFn: func(pod *v1.Pod) { pod.Spec.RestartPolicy = v1.RestartPolicyAlways }, - mutateStatusFn: func(status *kubecontainer.PodStatus) { - status.ContainerStatuses[2].State = kubecontainer.ContainerStateRunning - }, - actions: noAction, - }, - "Kill pod and restart the first init container if the pod sandbox is dead": { - mutatePodFn: func(pod *v1.Pod) { pod.Spec.RestartPolicy = v1.RestartPolicyAlways }, - mutateStatusFn: func(status *kubecontainer.PodStatus) { - status.SandboxStatuses[0].State = runtimeapi.PodSandboxState_SANDBOX_NOTREADY - }, - actions: podActions{ - KillPod: true, - CreateSandbox: true, - SandboxID: baseStatus.SandboxStatuses[0].Id, - Attempt: uint32(1), - NextInitContainerToStart: &basePod.Spec.InitContainers[0], - InitContainersToStart: []int{0}, - ContainersToStart: []int{}, - ContainersToKill: getKillMapWithInitContainers(basePod, baseStatus, []int{}), - }, - }, - "initialization failed; restart the last init container if RestartPolicy == Always": { - mutatePodFn: func(pod *v1.Pod) { pod.Spec.RestartPolicy = v1.RestartPolicyAlways }, - mutateStatusFn: func(status *kubecontainer.PodStatus) { - status.ContainerStatuses[2].ExitCode = 137 - }, - actions: podActions{ - SandboxID: baseStatus.SandboxStatuses[0].Id, - NextInitContainerToStart: &basePod.Spec.InitContainers[2], - InitContainersToStart: []int{2}, - ContainersToStart: []int{}, - ContainersToKill: getKillMapWithInitContainers(basePod, baseStatus, []int{}), - }, - }, - "initialization failed; restart the last init container if RestartPolicy == OnFailure": { - mutatePodFn: func(pod *v1.Pod) { pod.Spec.RestartPolicy = v1.RestartPolicyOnFailure }, - mutateStatusFn: func(status *kubecontainer.PodStatus) { - status.ContainerStatuses[2].ExitCode = 137 - }, - actions: podActions{ - SandboxID: baseStatus.SandboxStatuses[0].Id, - NextInitContainerToStart: &basePod.Spec.InitContainers[2], - InitContainersToStart: []int{2}, - ContainersToStart: []int{}, - ContainersToKill: getKillMapWithInitContainers(basePod, baseStatus, []int{}), - }, - }, - "initialization failed; kill pod if RestartPolicy == Never": { - mutatePodFn: func(pod *v1.Pod) { pod.Spec.RestartPolicy = v1.RestartPolicyNever }, - mutateStatusFn: func(status *kubecontainer.PodStatus) { - status.ContainerStatuses[2].ExitCode = 137 - }, - actions: podActions{ - KillPod: true, - SandboxID: baseStatus.SandboxStatuses[0].Id, - ContainersToStart: []int{}, - ContainersToKill: getKillMapWithInitContainers(basePod, baseStatus, []int{}), - }, - }, - "init container state unknown; kill and recreate the last init container if RestartPolicy == Always": { - mutatePodFn: func(pod *v1.Pod) { pod.Spec.RestartPolicy = v1.RestartPolicyAlways }, - mutateStatusFn: func(status *kubecontainer.PodStatus) { - status.ContainerStatuses[2].State = kubecontainer.ContainerStateUnknown - }, - actions: podActions{ - SandboxID: baseStatus.SandboxStatuses[0].Id, - NextInitContainerToStart: &basePod.Spec.InitContainers[2], - InitContainersToStart: []int{2}, - ContainersToStart: []int{}, - ContainersToKill: getKillMapWithInitContainers(basePod, baseStatus, []int{2}), - }, - }, - "init container state unknown; kill and recreate the last init container if RestartPolicy == OnFailure": { - mutatePodFn: func(pod *v1.Pod) { pod.Spec.RestartPolicy = v1.RestartPolicyOnFailure }, - mutateStatusFn: func(status *kubecontainer.PodStatus) { - status.ContainerStatuses[2].State = kubecontainer.ContainerStateUnknown - }, - actions: podActions{ - SandboxID: baseStatus.SandboxStatuses[0].Id, - NextInitContainerToStart: &basePod.Spec.InitContainers[2], - InitContainersToStart: []int{2}, - ContainersToStart: []int{}, - ContainersToKill: getKillMapWithInitContainers(basePod, baseStatus, []int{2}), - }, - }, - "init container state unknown; kill pod if RestartPolicy == Never": { - mutatePodFn: func(pod *v1.Pod) { pod.Spec.RestartPolicy = v1.RestartPolicyNever }, - mutateStatusFn: func(status *kubecontainer.PodStatus) { - status.ContainerStatuses[2].State = kubecontainer.ContainerStateUnknown - }, - actions: podActions{ - KillPod: true, - SandboxID: baseStatus.SandboxStatuses[0].Id, - ContainersToStart: []int{}, - ContainersToKill: getKillMapWithInitContainers(basePod, baseStatus, []int{}), - }, - }, - "Pod sandbox not ready, init container failed, but RestartPolicy == Never; kill pod only": { - mutatePodFn: func(pod *v1.Pod) { pod.Spec.RestartPolicy = v1.RestartPolicyNever }, - mutateStatusFn: func(status *kubecontainer.PodStatus) { - status.SandboxStatuses[0].State = runtimeapi.PodSandboxState_SANDBOX_NOTREADY - }, - actions: podActions{ - KillPod: true, - CreateSandbox: false, - SandboxID: baseStatus.SandboxStatuses[0].Id, - Attempt: uint32(1), - ContainersToStart: []int{}, - ContainersToKill: getKillMapWithInitContainers(basePod, baseStatus, []int{}), - }, - }, - "Pod sandbox not ready, and RestartPolicy == Never, but no visible init containers; create a new pod sandbox": { - mutatePodFn: func(pod *v1.Pod) { pod.Spec.RestartPolicy = v1.RestartPolicyNever }, - mutateStatusFn: func(status *kubecontainer.PodStatus) { - status.SandboxStatuses[0].State = runtimeapi.PodSandboxState_SANDBOX_NOTREADY - status.ContainerStatuses = []*kubecontainer.Status{} - }, - actions: podActions{ - KillPod: true, - CreateSandbox: true, - SandboxID: baseStatus.SandboxStatuses[0].Id, - Attempt: uint32(1), - NextInitContainerToStart: &basePod.Spec.InitContainers[0], - InitContainersToStart: []int{0}, - ContainersToStart: []int{}, - ContainersToKill: getKillMapWithInitContainers(basePod, baseStatus, []int{}), - }, - }, - "Pod sandbox not ready, init container failed, and RestartPolicy == OnFailure; create a new pod sandbox": { - mutatePodFn: func(pod *v1.Pod) { pod.Spec.RestartPolicy = v1.RestartPolicyOnFailure }, - mutateStatusFn: func(status *kubecontainer.PodStatus) { - status.SandboxStatuses[0].State = runtimeapi.PodSandboxState_SANDBOX_NOTREADY - status.ContainerStatuses[2].ExitCode = 137 - }, - actions: podActions{ - KillPod: true, - CreateSandbox: true, - SandboxID: baseStatus.SandboxStatuses[0].Id, - Attempt: uint32(1), - NextInitContainerToStart: &basePod.Spec.InitContainers[0], - InitContainersToStart: []int{0}, - ContainersToStart: []int{}, - ContainersToKill: getKillMapWithInitContainers(basePod, baseStatus, []int{}), - }, - }, - "some of the init container statuses are missing but the last init container is running, don't restart preceding ones": { - mutatePodFn: func(pod *v1.Pod) { pod.Spec.RestartPolicy = v1.RestartPolicyAlways }, - mutateStatusFn: func(status *kubecontainer.PodStatus) { - status.ContainerStatuses[2].State = kubecontainer.ContainerStateRunning - status.ContainerStatuses = status.ContainerStatuses[2:] - }, - actions: podActions{ - KillPod: false, - SandboxID: baseStatus.SandboxStatuses[0].Id, - ContainersToStart: []int{}, - ContainersToKill: getKillMapWithInitContainers(basePod, baseStatus, []int{}), - }, - }, - "an init container is in the created state due to an unknown error when starting container; restart it": { - mutatePodFn: func(pod *v1.Pod) { pod.Spec.RestartPolicy = v1.RestartPolicyAlways }, - mutateStatusFn: func(status *kubecontainer.PodStatus) { - status.ContainerStatuses[2].State = kubecontainer.ContainerStateCreated - }, - actions: podActions{ - KillPod: false, - SandboxID: baseStatus.SandboxStatuses[0].Id, - NextInitContainerToStart: &basePod.Spec.InitContainers[2], - InitContainersToStart: []int{2}, - ContainersToStart: []int{}, - ContainersToKill: getKillMapWithInitContainers(basePod, baseStatus, []int{}), - }, - }, - } { - t.Run(desc, func(t *testing.T) { - featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.LegacySidecarContainers, true) - pod, status := makeBasePodAndStatusWithInitContainers() - if test.mutatePodFn != nil { - test.mutatePodFn(pod) - } - if test.mutateStatusFn != nil { - test.mutateStatusFn(status) - } - ctx := context.Background() - actions := m.computePodActions(ctx, pod, status) - handleRestartableInitContainers := kubelettypes.HasRestartableInitContainer(pod) - if !handleRestartableInitContainers { - // If sidecar containers are disabled or the pod does not have any - // restartable init container, we should not see any - // InitContainersToStart in the actions. - test.actions.InitContainersToStart = nil - } else { - // If sidecar containers are enabled and the pod has any - // restartable init container, we should not see any - // NextInitContainerToStart in the actions. - test.actions.NextInitContainerToStart = nil - } - verifyActions(t, &test.actions, &actions, desc) - }) - } -} - func makeBasePodAndStatusWithInitContainers() (*v1.Pod, *kubecontainer.PodStatus) { pod, status := makeBasePodAndStatus() pod.Spec.InitContainers = []v1.Container{ @@ -2336,168 +2095,6 @@ func TestComputePodActionsWithInitAndEphemeralContainers(t *testing.T) { } } -func TestComputePodActionsWithInitAndEphemeralContainersWithLegacySidecarContainers(t *testing.T) { - // Make sure existing test cases pass with feature enabled - TestComputePodActions(t) - TestComputePodActionsWithInitContainersWithLegacySidecarContainers(t) - - _, _, m, err := createTestRuntimeManager() - require.NoError(t, err) - - basePod, baseStatus := makeBasePodAndStatusWithInitAndEphemeralContainers() - noAction := podActions{ - SandboxID: baseStatus.SandboxStatuses[0].Id, - ContainersToStart: []int{}, - ContainersToKill: map[kubecontainer.ContainerID]containerToKillInfo{}, - } - - for desc, test := range map[string]struct { - mutatePodFn func(*v1.Pod) - mutateStatusFn func(*kubecontainer.PodStatus) - actions podActions - }{ - "steady state; do nothing; ignore ephemeral container": { - actions: noAction, - }, - "No ephemeral containers running; start one": { - mutateStatusFn: func(status *kubecontainer.PodStatus) { - status.ContainerStatuses = status.ContainerStatuses[:4] - }, - actions: podActions{ - SandboxID: baseStatus.SandboxStatuses[0].Id, - ContainersToStart: []int{}, - ContainersToKill: map[kubecontainer.ContainerID]containerToKillInfo{}, - EphemeralContainersToStart: []int{0}, - }, - }, - "Start second ephemeral container": { - mutatePodFn: func(pod *v1.Pod) { - pod.Spec.EphemeralContainers = append(pod.Spec.EphemeralContainers, v1.EphemeralContainer{ - EphemeralContainerCommon: v1.EphemeralContainerCommon{ - Name: "debug2", - Image: "busybox", - }, - }) - }, - actions: podActions{ - SandboxID: baseStatus.SandboxStatuses[0].Id, - ContainersToStart: []int{}, - ContainersToKill: map[kubecontainer.ContainerID]containerToKillInfo{}, - EphemeralContainersToStart: []int{1}, - }, - }, - "Ephemeral container exited; do not restart": { - mutatePodFn: func(pod *v1.Pod) { pod.Spec.RestartPolicy = v1.RestartPolicyAlways }, - mutateStatusFn: func(status *kubecontainer.PodStatus) { - status.ContainerStatuses[4].State = kubecontainer.ContainerStateExited - }, - actions: podActions{ - SandboxID: baseStatus.SandboxStatuses[0].Id, - ContainersToStart: []int{}, - ContainersToKill: map[kubecontainer.ContainerID]containerToKillInfo{}, - }, - }, - "initialization in progress; start ephemeral container": { - mutateStatusFn: func(status *kubecontainer.PodStatus) { - status.ContainerStatuses[3].State = kubecontainer.ContainerStateRunning - status.ContainerStatuses = status.ContainerStatuses[:4] - }, - actions: podActions{ - SandboxID: baseStatus.SandboxStatuses[0].Id, - ContainersToStart: []int{}, - ContainersToKill: map[kubecontainer.ContainerID]containerToKillInfo{}, - EphemeralContainersToStart: []int{0}, - }, - }, - "Create a new pod sandbox if the pod sandbox is dead, init container failed and RestartPolicy == OnFailure": { - mutatePodFn: func(pod *v1.Pod) { pod.Spec.RestartPolicy = v1.RestartPolicyOnFailure }, - mutateStatusFn: func(status *kubecontainer.PodStatus) { - status.SandboxStatuses[0].State = runtimeapi.PodSandboxState_SANDBOX_NOTREADY - status.ContainerStatuses = status.ContainerStatuses[3:] - status.ContainerStatuses[0].ExitCode = 137 - }, - actions: podActions{ - KillPod: true, - CreateSandbox: true, - SandboxID: baseStatus.SandboxStatuses[0].Id, - Attempt: uint32(1), - NextInitContainerToStart: &basePod.Spec.InitContainers[0], - InitContainersToStart: []int{0}, - ContainersToStart: []int{}, - ContainersToKill: getKillMapWithInitContainers(basePod, baseStatus, []int{}), - }, - }, - "Kill pod and do not restart ephemeral container if the pod sandbox is dead": { - mutatePodFn: func(pod *v1.Pod) { pod.Spec.RestartPolicy = v1.RestartPolicyAlways }, - mutateStatusFn: func(status *kubecontainer.PodStatus) { - status.SandboxStatuses[0].State = runtimeapi.PodSandboxState_SANDBOX_NOTREADY - }, - actions: podActions{ - KillPod: true, - CreateSandbox: true, - SandboxID: baseStatus.SandboxStatuses[0].Id, - Attempt: uint32(1), - NextInitContainerToStart: &basePod.Spec.InitContainers[0], - InitContainersToStart: []int{0}, - ContainersToStart: []int{}, - ContainersToKill: getKillMapWithInitContainers(basePod, baseStatus, []int{}), - }, - }, - "Kill pod if all containers exited except ephemeral container": { - mutatePodFn: func(pod *v1.Pod) { - pod.Spec.RestartPolicy = v1.RestartPolicyNever - }, - mutateStatusFn: func(status *kubecontainer.PodStatus) { - // all regular containers exited - for i := 0; i < 3; i++ { - status.ContainerStatuses[i].State = kubecontainer.ContainerStateExited - status.ContainerStatuses[i].ExitCode = 0 - } - }, - actions: podActions{ - SandboxID: baseStatus.SandboxStatuses[0].Id, - CreateSandbox: false, - KillPod: true, - ContainersToStart: []int{}, - ContainersToKill: map[kubecontainer.ContainerID]containerToKillInfo{}, - }, - }, - "Ephemeral container is in unknown state; leave it alone": { - mutatePodFn: func(pod *v1.Pod) { pod.Spec.RestartPolicy = v1.RestartPolicyNever }, - mutateStatusFn: func(status *kubecontainer.PodStatus) { - status.ContainerStatuses[4].State = kubecontainer.ContainerStateUnknown - }, - actions: noAction, - }, - } { - t.Run(desc, func(t *testing.T) { - featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.LegacySidecarContainers, true) - pod, status := makeBasePodAndStatusWithInitAndEphemeralContainers() - if test.mutatePodFn != nil { - test.mutatePodFn(pod) - } - if test.mutateStatusFn != nil { - test.mutateStatusFn(status) - } - ctx := context.Background() - actions := m.computePodActions(ctx, pod, status) - handleRestartableInitContainers := kubelettypes.HasRestartableInitContainer(pod) - if !handleRestartableInitContainers { - // If sidecar containers are disabled or the pod does not have any - // restartable init container, we should not see any - // InitContainersToStart in the actions. - test.actions.InitContainersToStart = nil - } else { - // If sidecar containers are enabled and the pod has any - // restartable init container, we should not see any - // NextInitContainerToStart in the actions. - test.actions.NextInitContainerToStart = nil - } - verifyActions(t, &test.actions, &actions, desc) - }) - } -} - func TestSyncPodWithSandboxAndDeletedPod(t *testing.T) { ctx := context.Background() fakeRuntime, _, m, err := createTestRuntimeManager() diff --git a/test/compatibility_lifecycle/reference/versioned_feature_list.yaml b/test/compatibility_lifecycle/reference/versioned_feature_list.yaml index 7c0ba01e63c..d654d692824 100644 --- a/test/compatibility_lifecycle/reference/versioned_feature_list.yaml +++ b/test/compatibility_lifecycle/reference/versioned_feature_list.yaml @@ -801,16 +801,6 @@ lockToDefault: true preRelease: GA version: "1.34" -- name: LegacySidecarContainers - versionedSpecs: - - default: true - lockToDefault: false - preRelease: GA - version: "1.0" - - default: false - lockToDefault: false - preRelease: Deprecated - version: "1.33" - name: ListFromCacheSnapshot versionedSpecs: - default: false