From 9d6c1030db0cabff5b9a007ea88d092a88766ae5 Mon Sep 17 00:00:00 2001 From: Gunju Kim Date: Wed, 12 Jul 2023 20:54:21 +0900 Subject: [PATCH] Generate containers ready condition including restartable init containers --- pkg/kubelet/kubelet_pods.go | 7 +-- pkg/kubelet/status/generate.go | 15 ++++++ pkg/kubelet/status/generate_test.go | 72 ++++++++++++++++++++++++++++ pkg/kubelet/status/status_manager.go | 5 +- 4 files changed, 94 insertions(+), 5 deletions(-) diff --git a/pkg/kubelet/kubelet_pods.go b/pkg/kubelet/kubelet_pods.go index 7e593de8949..ac79ae5b152 100644 --- a/pkg/kubelet/kubelet_pods.go +++ b/pkg/kubelet/kubelet_pods.go @@ -1725,9 +1725,10 @@ func (kl *Kubelet) generateAPIPodStatus(pod *v1.Pod, podStatus *kubecontainer.Po if utilfeature.DefaultFeatureGate.Enabled(features.PodReadyToStartContainersCondition) { s.Conditions = append(s.Conditions, status.GeneratePodReadyToStartContainersCondition(pod, podStatus)) } - s.Conditions = append(s.Conditions, status.GeneratePodInitializedCondition(&pod.Spec, append(s.InitContainerStatuses, s.ContainerStatuses...), s.Phase)) - s.Conditions = append(s.Conditions, status.GeneratePodReadyCondition(&pod.Spec, s.Conditions, s.ContainerStatuses, s.Phase)) - s.Conditions = append(s.Conditions, status.GenerateContainersReadyCondition(&pod.Spec, s.ContainerStatuses, s.Phase)) + allContainerStatuses := append(s.InitContainerStatuses, s.ContainerStatuses...) + s.Conditions = append(s.Conditions, status.GeneratePodInitializedCondition(&pod.Spec, allContainerStatuses, s.Phase)) + s.Conditions = append(s.Conditions, status.GeneratePodReadyCondition(&pod.Spec, s.Conditions, allContainerStatuses, s.Phase)) + s.Conditions = append(s.Conditions, status.GenerateContainersReadyCondition(&pod.Spec, allContainerStatuses, s.Phase)) s.Conditions = append(s.Conditions, v1.PodCondition{ Type: v1.PodScheduled, Status: v1.ConditionTrue, diff --git a/pkg/kubelet/status/generate.go b/pkg/kubelet/status/generate.go index 7c6c1179a20..c6707345b67 100644 --- a/pkg/kubelet/status/generate.go +++ b/pkg/kubelet/status/generate.go @@ -55,6 +55,21 @@ func GenerateContainersReadyCondition(spec *v1.PodSpec, containerStatuses []v1.C } unknownContainers := []string{} unreadyContainers := []string{} + + for _, container := range spec.InitContainers { + if !kubetypes.IsRestartableInitContainer(&container) { + continue + } + + if containerStatus, ok := podutil.GetContainerStatus(containerStatuses, container.Name); ok { + if !containerStatus.Ready { + unreadyContainers = append(unreadyContainers, container.Name) + } + } else { + unknownContainers = append(unknownContainers, container.Name) + } + } + for _, container := range spec.Containers { if containerStatus, ok := podutil.GetContainerStatus(containerStatuses, container.Name); ok { if !containerStatus.Ready { diff --git a/pkg/kubelet/status/generate_test.go b/pkg/kubelet/status/generate_test.go index d185db2cc23..6bb32079998 100644 --- a/pkg/kubelet/status/generate_test.go +++ b/pkg/kubelet/status/generate_test.go @@ -30,6 +30,10 @@ import ( "k8s.io/utils/pointer" ) +var ( + containerRestartPolicyAlways = v1.ContainerRestartPolicyAlways +) + func TestGenerateContainersReadyCondition(t *testing.T) { tests := []struct { spec *v1.PodSpec @@ -112,6 +116,74 @@ func TestGenerateContainersReadyCondition(t *testing.T) { podPhase: v1.PodSucceeded, expectReady: getPodCondition(v1.ContainersReady, v1.ConditionFalse, PodCompleted, ""), }, + { + spec: &v1.PodSpec{ + InitContainers: []v1.Container{ + {Name: "restartable-init-1", RestartPolicy: &containerRestartPolicyAlways}, + }, + Containers: []v1.Container{ + {Name: "regular-1"}, + }, + }, + containerStatuses: []v1.ContainerStatus{ + getReadyStatus("regular-1"), + }, + podPhase: v1.PodRunning, + expectReady: getPodCondition(v1.ContainersReady, v1.ConditionFalse, ContainersNotReady, "containers with unknown status: [restartable-init-1]"), + }, + { + spec: &v1.PodSpec{ + InitContainers: []v1.Container{ + {Name: "restartable-init-1", RestartPolicy: &containerRestartPolicyAlways}, + {Name: "restartable-init-2", RestartPolicy: &containerRestartPolicyAlways}, + }, + Containers: []v1.Container{ + {Name: "regular-1"}, + }, + }, + containerStatuses: []v1.ContainerStatus{ + getReadyStatus("restartable-init-1"), + getReadyStatus("restartable-init-2"), + getReadyStatus("regular-1"), + }, + podPhase: v1.PodRunning, + expectReady: getPodCondition(v1.ContainersReady, v1.ConditionTrue, "", ""), + }, + { + spec: &v1.PodSpec{ + InitContainers: []v1.Container{ + {Name: "restartable-init-1", RestartPolicy: &containerRestartPolicyAlways}, + {Name: "restartable-init-2", RestartPolicy: &containerRestartPolicyAlways}, + }, + Containers: []v1.Container{ + {Name: "regular-1"}, + }, + }, + containerStatuses: []v1.ContainerStatus{ + getReadyStatus("restartable-init-1"), + getReadyStatus("regular-1"), + }, + podPhase: v1.PodRunning, + expectReady: getPodCondition(v1.ContainersReady, v1.ConditionFalse, ContainersNotReady, "containers with unknown status: [restartable-init-2]"), + }, + { + spec: &v1.PodSpec{ + InitContainers: []v1.Container{ + {Name: "restartable-init-1", RestartPolicy: &containerRestartPolicyAlways}, + {Name: "restartable-init-2", RestartPolicy: &containerRestartPolicyAlways}, + }, + Containers: []v1.Container{ + {Name: "regular-1"}, + }, + }, + containerStatuses: []v1.ContainerStatus{ + getReadyStatus("restartable-init-1"), + getNotReadyStatus("restartable-init-2"), + getReadyStatus("regular-1"), + }, + podPhase: v1.PodRunning, + expectReady: getPodCondition(v1.ContainersReady, v1.ConditionFalse, ContainersNotReady, "containers with unready status: [restartable-init-2]"), + }, } for i, test := range tests { diff --git a/pkg/kubelet/status/status_manager.go b/pkg/kubelet/status/status_manager.go index ed553215c1e..e43c5874481 100644 --- a/pkg/kubelet/status/status_manager.go +++ b/pkg/kubelet/status/status_manager.go @@ -349,8 +349,9 @@ func (m *manager) SetContainerReadiness(podUID types.UID, containerID kubecontai status.Conditions = append(status.Conditions, condition) } } - updateConditionFunc(v1.PodReady, GeneratePodReadyCondition(&pod.Spec, status.Conditions, status.ContainerStatuses, status.Phase)) - updateConditionFunc(v1.ContainersReady, GenerateContainersReadyCondition(&pod.Spec, status.ContainerStatuses, status.Phase)) + allContainerStatuses := append(status.InitContainerStatuses, status.ContainerStatuses...) + updateConditionFunc(v1.PodReady, GeneratePodReadyCondition(&pod.Spec, status.Conditions, allContainerStatuses, status.Phase)) + updateConditionFunc(v1.ContainersReady, GenerateContainersReadyCondition(&pod.Spec, allContainerStatuses, status.Phase)) m.updateStatusInternal(pod, status, false, false) }