diff --git a/pkg/kubelet/status/status_manager.go b/pkg/kubelet/status/status_manager.go index 5b6e7ea5a7a..c7cb740586e 100644 --- a/pkg/kubelet/status/status_manager.go +++ b/pkg/kubelet/status/status_manager.go @@ -993,7 +993,7 @@ func (m *manager) needsReconcile(uid types.UID, status v1.PodStatus) bool { // Related issue #15262/PR #15263 to move apiserver to RFC339NANO is closed. func normalizeStatus(pod *v1.Pod, status *v1.PodStatus) *v1.PodStatus { bytesPerStatus := kubecontainer.MaxPodTerminationMessageLogLength - if containers := len(pod.Spec.Containers) + len(pod.Spec.InitContainers); containers > 0 { + if containers := len(pod.Spec.Containers) + len(pod.Spec.InitContainers) + len(pod.Spec.EphemeralContainers); containers > 0 { bytesPerStatus = bytesPerStatus / containers } normalizeTimeStamp := func(t *metav1.Time) { @@ -1021,23 +1021,23 @@ func normalizeStatus(pod *v1.Pod, status *v1.PodStatus) *v1.PodStatus { normalizeTimeStamp(&condition.LastTransitionTime) } - // update container statuses - for i := range status.ContainerStatuses { - cstatus := &status.ContainerStatuses[i] - normalizeContainerState(&cstatus.State) - normalizeContainerState(&cstatus.LastTerminationState) + normalizeContainerStatuses := func(containerStatuses []v1.ContainerStatus) { + for i := range containerStatuses { + cstatus := &containerStatuses[i] + normalizeContainerState(&cstatus.State) + normalizeContainerState(&cstatus.LastTerminationState) + } } - // Sort the container statuses, so that the order won't affect the result of comparison + + normalizeContainerStatuses(status.ContainerStatuses) sort.Sort(kubetypes.SortedContainerStatuses(status.ContainerStatuses)) - // update init container statuses - for i := range status.InitContainerStatuses { - cstatus := &status.InitContainerStatuses[i] - normalizeContainerState(&cstatus.State) - normalizeContainerState(&cstatus.LastTerminationState) - } - // Sort the container statuses, so that the order won't affect the result of comparison + normalizeContainerStatuses(status.InitContainerStatuses) kubetypes.SortInitContainerStatuses(pod, status.InitContainerStatuses) + + normalizeContainerStatuses(status.EphemeralContainerStatuses) + sort.Sort(kubetypes.SortedContainerStatuses(status.EphemeralContainerStatuses)) + return status } diff --git a/pkg/kubelet/status/status_manager_test.go b/pkg/kubelet/status/status_manager_test.go index 8d17f1691cc..ac371469a1e 100644 --- a/pkg/kubelet/status/status_manager_test.go +++ b/pkg/kubelet/status/status_manager_test.go @@ -445,22 +445,32 @@ func shuffle(statuses []v1.ContainerStatus) []v1.ContainerStatus { } func TestStatusEquality(t *testing.T) { - pod := v1.Pod{ - Spec: v1.PodSpec{}, - } - containerStatus := []v1.ContainerStatus{} - for i := 0; i < 10; i++ { - s := v1.ContainerStatus{ - Name: fmt.Sprintf("container%d", i), + getContainersAndStatuses := func() ([]v1.Container, []v1.ContainerStatus) { + var containers []v1.Container + var containerStatuses []v1.ContainerStatus + for i := 0; i < 10; i++ { + containerName := fmt.Sprintf("container%d", i) + containers = append(containers, v1.Container{Name: containerName}) + containerStatuses = append(containerStatuses, v1.ContainerStatus{Name: containerName}) } - containerStatus = append(containerStatus, s) + return containers, containerStatuses + } + containers, containerStatuses := getContainersAndStatuses() + pod := v1.Pod{ + Spec: v1.PodSpec{ + InitContainers: containers, + }, } podStatus := v1.PodStatus{ - ContainerStatuses: containerStatus, + ContainerStatuses: containerStatuses, + InitContainerStatuses: containerStatuses, + EphemeralContainerStatuses: containerStatuses, } for i := 0; i < 10; i++ { oldPodStatus := v1.PodStatus{ - ContainerStatuses: shuffle(podStatus.ContainerStatuses), + ContainerStatuses: shuffle(podStatus.ContainerStatuses), + InitContainerStatuses: shuffle(podStatus.InitContainerStatuses), + EphemeralContainerStatuses: shuffle(podStatus.EphemeralContainerStatuses), } normalizeStatus(&pod, &oldPodStatus) normalizeStatus(&pod, &podStatus) @@ -504,8 +514,9 @@ func TestStatusNormalizationEnforcesMaxBytes(t *testing.T) { containerStatus = append(containerStatus, s) } podStatus := v1.PodStatus{ - InitContainerStatuses: containerStatus[:24], - ContainerStatuses: containerStatus[24:], + InitContainerStatuses: containerStatus[:16], + ContainerStatuses: containerStatus[16:32], + EphemeralContainerStatuses: containerStatus[32:], } result := normalizeStatus(&pod, &podStatus) count := 0 @@ -521,6 +532,49 @@ func TestStatusNormalizationEnforcesMaxBytes(t *testing.T) { } } +func TestStatusNormalizeTimeStamp(t *testing.T) { + pod := v1.Pod{ + Spec: v1.PodSpec{}, + } + + now := metav1.Now() + podStatus := v1.PodStatus{ + ContainerStatuses: []v1.ContainerStatus{ + {State: v1.ContainerState{Running: &v1.ContainerStateRunning{StartedAt: now}}}, + {State: v1.ContainerState{Terminated: &v1.ContainerStateTerminated{StartedAt: now, FinishedAt: now}}}, + }, + InitContainerStatuses: []v1.ContainerStatus{ + {State: v1.ContainerState{Running: &v1.ContainerStateRunning{StartedAt: now}}}, + {State: v1.ContainerState{Terminated: &v1.ContainerStateTerminated{StartedAt: now, FinishedAt: now}}}, + }, + EphemeralContainerStatuses: []v1.ContainerStatus{ + {State: v1.ContainerState{Running: &v1.ContainerStateRunning{StartedAt: now}}}, + {State: v1.ContainerState{Terminated: &v1.ContainerStateTerminated{StartedAt: now, FinishedAt: now}}}, + }, + } + + expectedTime := now.DeepCopy().Rfc3339Copy() + expectedPodStatus := v1.PodStatus{ + ContainerStatuses: []v1.ContainerStatus{ + {State: v1.ContainerState{Running: &v1.ContainerStateRunning{StartedAt: expectedTime}}}, + {State: v1.ContainerState{Terminated: &v1.ContainerStateTerminated{StartedAt: expectedTime, FinishedAt: expectedTime}}}, + }, + InitContainerStatuses: []v1.ContainerStatus{ + {State: v1.ContainerState{Running: &v1.ContainerStateRunning{StartedAt: expectedTime}}}, + {State: v1.ContainerState{Terminated: &v1.ContainerStateTerminated{StartedAt: expectedTime, FinishedAt: expectedTime}}}, + }, + EphemeralContainerStatuses: []v1.ContainerStatus{ + {State: v1.ContainerState{Running: &v1.ContainerStateRunning{StartedAt: expectedTime}}}, + {State: v1.ContainerState{Terminated: &v1.ContainerStateTerminated{StartedAt: expectedTime, FinishedAt: expectedTime}}}, + }, + } + + normalizedStatus := normalizeStatus(&pod, &podStatus) + if !isPodStatusByKubeletEqual(&expectedPodStatus, normalizedStatus) { + t.Fatalf("The timestamp is not correctly converted to RFC3339 format.") + } +} + func TestStaticPod(t *testing.T) { staticPod := getTestPod() staticPod.Annotations = map[string]string{kubetypes.ConfigSourceAnnotationKey: "file"}