consider sidecar containers in maxContainerRestarts

Kubernetes-commit: 7533123eb5e7c6ecd59d00d236235581f7f1157b
This commit is contained in:
AxeZhan 2024-05-19 23:50:25 +08:00 committed by Kubernetes Publisher
parent 4ced6667a4
commit 4657409ea3
2 changed files with 114 additions and 8 deletions

View File

@ -21,6 +21,7 @@ import (
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/sets"
)
// IsPodAvailable returns true if a pod is available; false otherwise.
@ -113,8 +114,8 @@ func (s ByLogging) Less(i, j int) bool {
return afterOrZero(podReadyTime(s[j]), podReadyTime(s[i]))
}
// 5. Pods with containers with higher restart counts < lower restart counts
if maxContainerRestarts(s[i]) != maxContainerRestarts(s[j]) {
return maxContainerRestarts(s[i]) > maxContainerRestarts(s[j])
if res := compareMaxContainerRestarts(s[i], s[j]); res != nil {
return *res
}
// 6. older pods < newer pods < empty timestamp pods
if !s[i].CreationTimestamp.Equal(&s[j].CreationTimestamp) {
@ -161,8 +162,8 @@ func (s ActivePods) Less(i, j int) bool {
return afterOrZero(podReadyTime(s[i]), podReadyTime(s[j]))
}
// 7. Pods with containers with higher restart counts < lower restart counts
if maxContainerRestarts(s[i]) != maxContainerRestarts(s[j]) {
return maxContainerRestarts(s[i]) > maxContainerRestarts(s[j])
if res := compareMaxContainerRestarts(s[i], s[j]); res != nil {
return *res
}
// 8. Empty creation time pods < newer pods < older pods
if !s[i].CreationTimestamp.Equal(&s[j].CreationTimestamp) {
@ -190,12 +191,41 @@ func podReadyTime(pod *corev1.Pod) *metav1.Time {
return &metav1.Time{}
}
func maxContainerRestarts(pod *corev1.Pod) int {
maxRestarts := 0
func maxContainerRestarts(pod *corev1.Pod) (regularRestarts, sidecarRestarts int) {
for _, c := range pod.Status.ContainerStatuses {
maxRestarts = max(maxRestarts, int(c.RestartCount))
regularRestarts = max(regularRestarts, int(c.RestartCount))
}
return maxRestarts
names := sets.New[string]()
for _, c := range pod.Spec.InitContainers {
if c.RestartPolicy != nil && *c.RestartPolicy == corev1.ContainerRestartPolicyAlways {
names.Insert(c.Name)
}
}
for _, c := range pod.Status.InitContainerStatuses {
if names.Has(c.Name) {
sidecarRestarts = max(sidecarRestarts, int(c.RestartCount))
}
}
return
}
// We use *bool here to determine equality:
// true: pi has a higher container restart count.
// false: pj has a higher container restart count.
// nil: Both have the same container restart count.
func compareMaxContainerRestarts(pi *corev1.Pod, pj *corev1.Pod) *bool {
regularRestartsI, sidecarRestartsI := maxContainerRestarts(pi)
regularRestartsJ, sidecarRestartsJ := maxContainerRestarts(pj)
if regularRestartsI != regularRestartsJ {
res := regularRestartsI > regularRestartsJ
return &res
}
// If pods have the same restart count, an attempt is made to compare the restart counts of sidecar containers.
if sidecarRestartsI != sidecarRestartsJ {
res := sidecarRestartsI > sidecarRestartsJ
return &res
}
return nil
}
// ContainerType and VisitContainers are taken from

View File

@ -29,6 +29,7 @@ func TestActivePods(t *testing.T) {
time1 := metav1.Now()
time2 := metav1.NewTime(time1.Add(1 * time.Second))
time3 := metav1.NewTime(time1.Add(2 * time.Second))
restartAlways := corev1.ContainerRestartPolicyAlways
tests := []struct {
name string
@ -364,6 +365,81 @@ func TestActivePods(t *testing.T) {
},
},
},
{
name: "higher sidecar restart count should sort before lower restart count",
pod1: &corev1.Pod{
ObjectMeta: metav1.ObjectMeta{
Name: "podWithMoreRestarts",
Namespace: "default",
},
Spec: corev1.PodSpec{
NodeName: "node1",
InitContainers: []corev1.Container{
{
Name: "sidecar",
RestartPolicy: &restartAlways,
},
},
},
Status: corev1.PodStatus{
Phase: corev1.PodRunning,
Conditions: []corev1.PodCondition{
{
Type: corev1.PodReady,
Status: corev1.ConditionTrue,
LastTransitionTime: time1,
},
},
ContainerStatuses: []corev1.ContainerStatus{
{
RestartCount: 3,
},
},
InitContainerStatuses: []corev1.ContainerStatus{
{
Name: "sidecar",
RestartCount: 3,
},
},
},
},
pod2: &corev1.Pod{
ObjectMeta: metav1.ObjectMeta{
Name: "podWithLessRestarts",
Namespace: "default",
},
Spec: corev1.PodSpec{
NodeName: "node1",
InitContainers: []corev1.Container{
{
Name: "sidecar",
RestartPolicy: &restartAlways,
},
},
},
Status: corev1.PodStatus{
Phase: corev1.PodRunning,
Conditions: []corev1.PodCondition{
{
Type: corev1.PodReady,
Status: corev1.ConditionTrue,
LastTransitionTime: time1,
},
},
ContainerStatuses: []corev1.ContainerStatus{
{
RestartCount: 3,
},
},
InitContainerStatuses: []corev1.ContainerStatus{
{
Name: "sidecar",
RestartCount: 2,
},
},
},
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {