Skip to content

Commit 2fabf5f

Browse files
authored
Merge pull request kubernetes#128029 from bouaouda-achraf/oom-adjust-score-pod-aware
kubelet(OOM-score-adj): change OOM score adjustment calculation for sidecar container
2 parents 78fed9d + e6a518a commit 2fabf5f

File tree

3 files changed

+343
-65
lines changed

3 files changed

+343
-65
lines changed

pkg/kubelet/qos/helpers.go

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
/*
2+
Copyright 2024 The Kubernetes Authors.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
// Package qos contains helper functions for quality of service.
18+
// For each resource (memory, CPU) Kubelet supports three classes of containers.
19+
// Memory guaranteed containers will receive the highest priority and will get all the resources
20+
// they need.
21+
// Burstable containers will be guaranteed their request and can "burst" and use more resources
22+
// when available.
23+
// Best-Effort containers, which don't specify a request, can use resources only if not being used
24+
// by other pods.
25+
26+
package qos // import "k8s.io/kubernetes/pkg/kubelet/qos"
27+
28+
import (
29+
v1 "k8s.io/api/core/v1"
30+
)
31+
32+
// minRegularContainerMemory returns the minimum memory resource quantity
33+
// across all regular containers in pod.Spec.Containers.
34+
// It does not include initContainers (both restartable and non-restartable).
35+
func minRegularContainerMemory(pod v1.Pod) int64 {
36+
memoryValue := pod.Spec.Containers[0].Resources.Requests.Memory().Value()
37+
for _, container := range pod.Spec.Containers[1:] {
38+
if container.Resources.Requests.Memory().Value() < memoryValue {
39+
memoryValue = container.Resources.Requests.Memory().Value()
40+
}
41+
}
42+
return memoryValue
43+
}

pkg/kubelet/qos/policy.go

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,9 @@ package qos
1818

1919
import (
2020
v1 "k8s.io/api/core/v1"
21+
utilfeature "k8s.io/apiserver/pkg/util/feature"
2122
v1qos "k8s.io/kubernetes/pkg/apis/core/v1/helper/qos"
23+
"k8s.io/kubernetes/pkg/features"
2224
"k8s.io/kubernetes/pkg/kubelet/types"
2325
)
2426

@@ -63,6 +65,20 @@ func GetContainerOOMScoreAdjust(pod *v1.Pod, container *v1.Container, memoryCapa
6365
// Note that this is a heuristic, it won't work if a container has many small processes.
6466
memoryRequest := container.Resources.Requests.Memory().Value()
6567
oomScoreAdjust := 1000 - (1000*memoryRequest)/memoryCapacity
68+
69+
// adapt the sidecarContainer memoryRequest for OOM ADJ calculation
70+
// calculate the oom score adjustment based on: max-memory( currentSideCarContainer , min-memory(regular containers) ) .
71+
if utilfeature.DefaultFeatureGate.Enabled(features.SidecarContainers) && isSidecarContainer(pod, container) {
72+
// check min memory quantity in regular containers
73+
minMemoryRequest := minRegularContainerMemory(*pod)
74+
minMemoryOomScoreAdjust := 1000 - (1000*minMemoryRequest)/memoryCapacity
75+
// the OOM adjustment for sidecar container will match
76+
// or fall below the OOM score adjustment of regular containers in the Pod.
77+
if oomScoreAdjust > minMemoryOomScoreAdjust {
78+
oomScoreAdjust = minMemoryOomScoreAdjust
79+
}
80+
}
81+
6682
// A guaranteed pod using 100% of memory can have an OOM score of 10. Ensure
6783
// that burstable pods have a higher OOM score adjustment.
6884
if int(oomScoreAdjust) < (1000 + guaranteedOOMScoreAdj) {
@@ -74,3 +90,18 @@ func GetContainerOOMScoreAdjust(pod *v1.Pod, container *v1.Container, memoryCapa
7490
}
7591
return int(oomScoreAdjust)
7692
}
93+
94+
// isSidecarContainer returns a boolean indicating whether a container is a sidecar or not.
95+
// Since v1.Container does not directly specify whether a container is a sidecar,
96+
// this function uses available indicators (container.RestartPolicy == v1.ContainerRestartPolicyAlways)
97+
// to make that determination.
98+
func isSidecarContainer(pod *v1.Pod, container *v1.Container) bool {
99+
if container.RestartPolicy != nil && *container.RestartPolicy == v1.ContainerRestartPolicyAlways {
100+
for _, initContainer := range pod.Spec.InitContainers {
101+
if initContainer.Name == container.Name {
102+
return true
103+
}
104+
}
105+
}
106+
return false
107+
}

0 commit comments

Comments
 (0)