Skip to content

Commit 14653d6

Browse files
author
k8s-merge-robot
committed
Merge pull request kubernetes#20169 from vishh/20117
Auto commit by PR queue bot
2 parents 11c42f7 + df1f164 commit 14653d6

File tree

3 files changed

+62
-26
lines changed

3 files changed

+62
-26
lines changed

pkg/kubelet/dockertools/manager.go

Lines changed: 34 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1357,6 +1357,38 @@ func containerAndPodFromLabels(inspect *docker.Container) (pod *api.Pod, contain
13571357
return
13581358
}
13591359

1360+
func (dm *DockerManager) applyOOMScoreAdj(container *api.Container, containerInfo *docker.Container) error {
1361+
cgroupName, err := dm.procFs.GetFullContainerName(containerInfo.State.Pid)
1362+
if err != nil {
1363+
if err == os.ErrNotExist {
1364+
// Container exited. We cannot do anything about it. Ignore this error.
1365+
glog.V(2).Infof("Failed to apply OOM score adj on container %q with ID %q. Init process does not exist.", containerInfo.Name, containerInfo.ID)
1366+
return nil
1367+
}
1368+
return err
1369+
}
1370+
// Set OOM score of the container based on the priority of the container.
1371+
// Processes in lower-priority pods should be killed first if the system runs out of memory.
1372+
// The main pod infrastructure container is considered high priority, since if it is killed the
1373+
// whole pod will die.
1374+
// TODO: Cache this value.
1375+
var oomScoreAdj int
1376+
if containerInfo.Name == PodInfraContainerName {
1377+
oomScoreAdj = qos.PodInfraOOMAdj
1378+
} else {
1379+
oomScoreAdj = qos.GetContainerOOMScoreAdjust(container, int64(dm.machineInfo.MemoryCapacity))
1380+
}
1381+
if err = dm.oomAdjuster.ApplyOOMScoreAdjContainer(cgroupName, oomScoreAdj, 5); err != nil {
1382+
if err == os.ErrNotExist {
1383+
// Container exited. We cannot do anything about it. Ignore this error.
1384+
glog.V(2).Infof("Failed to apply OOM score adj on container %q with ID %q. Init process does not exist.", containerInfo.Name, containerInfo.ID)
1385+
return nil
1386+
}
1387+
return err
1388+
}
1389+
return nil
1390+
}
1391+
13601392
// Run a single container from a pod. Returns the docker container ID
13611393
// If do not need to pass labels, just pass nil.
13621394
func (dm *DockerManager) runContainerInPod(pod *api.Pod, container *api.Container, netMode, ipcMode, pidMode string, restartCount int) (kubecontainer.ContainerID, error) {
@@ -1418,24 +1450,9 @@ func (dm *DockerManager) runContainerInPod(pod *api.Pod, container *api.Containe
14181450
return kubecontainer.ContainerID{}, fmt.Errorf("can't get init PID for container %q", id)
14191451
}
14201452

1421-
// Set OOM score of the container based on the priority of the container.
1422-
// Processes in lower-priority pods should be killed first if the system runs out of memory.
1423-
// The main pod infrastructure container is considered high priority, since if it is killed the
1424-
// whole pod will die.
1425-
var oomScoreAdj int
1426-
if container.Name == PodInfraContainerName {
1427-
oomScoreAdj = qos.PodInfraOOMAdj
1428-
} else {
1429-
oomScoreAdj = qos.GetContainerOOMScoreAdjust(container, int64(dm.machineInfo.MemoryCapacity))
1430-
}
1431-
cgroupName, err := dm.procFs.GetFullContainerName(containerInfo.State.Pid)
1432-
if err != nil {
1433-
return kubecontainer.ContainerID{}, fmt.Errorf("GetFullContainerName: %v", err)
1434-
}
1435-
if err = dm.oomAdjuster.ApplyOOMScoreAdjContainer(cgroupName, oomScoreAdj, 5); err != nil {
1436-
return kubecontainer.ContainerID{}, fmt.Errorf("ApplyOOMScoreAdjContainer: %v", err)
1453+
if err := dm.applyOOMScoreAdj(container, containerInfo); err != nil {
1454+
return kubecontainer.ContainerID{}, fmt.Errorf("failed to apply oom-score-adj to container %q- %v", err, containerInfo.Name)
14371455
}
1438-
14391456
// The addNDotsOption call appends the ndots option to the resolv.conf file generated by docker.
14401457
// This resolv.conf file is shared by all containers of the same pod, and needs to be modified only once per pod.
14411458
// we modify it when the pause container is created since it is the first container created in the pod since it holds

pkg/util/oom/oom_linux.go

Lines changed: 24 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ package oom
2121
import (
2222
"fmt"
2323
"io/ioutil"
24+
"os"
2425
"path"
2526
"strconv"
2627

@@ -48,7 +49,18 @@ func getPids(cgroupName string) ([]int, error) {
4849
return fsManager.GetPids()
4950
}
5051

52+
func syscallNotExists(err error) bool {
53+
if err == nil {
54+
return false
55+
}
56+
if e, ok := err.(*os.SyscallError); ok && os.IsNotExist(e) {
57+
return true
58+
}
59+
return false
60+
}
61+
5162
// Writes 'value' to /proc/<pid>/oom_score_adj. PID = 0 means self
63+
// Returns os.ErrNotExist if the `pid` does not exist.
5264
func applyOOMScoreAdj(pid int, oomScoreAdj int) error {
5365
if pid < 0 {
5466
return fmt.Errorf("invalid PID %d specified for oom_score_adj", pid)
@@ -61,20 +73,18 @@ func applyOOMScoreAdj(pid int, oomScoreAdj int) error {
6173
pidStr = strconv.Itoa(pid)
6274
}
6375

64-
oomScoreAdjPath := path.Join("/proc", pidStr, "oom_score_adj")
6576
maxTries := 2
77+
oomScoreAdjPath := path.Join("/proc", pidStr, "oom_score_adj")
78+
value := strconv.Itoa(oomScoreAdj)
6679
var err error
6780
for i := 0; i < maxTries; i++ {
68-
_, readErr := ioutil.ReadFile(oomScoreAdjPath)
69-
if readErr != nil {
70-
err = fmt.Errorf("failed to read oom_score_adj: %v", readErr)
71-
} else if writeErr := ioutil.WriteFile(oomScoreAdjPath, []byte(strconv.Itoa(oomScoreAdj)), 0700); writeErr != nil {
72-
err = fmt.Errorf("failed to set oom_score_adj to %d: %v", oomScoreAdj, writeErr)
73-
} else {
74-
return nil
81+
if err = ioutil.WriteFile(oomScoreAdjPath, []byte(value), 0700); err != nil {
82+
if syscallNotExists(err) {
83+
return os.ErrNotExist
84+
}
85+
err = fmt.Errorf("failed to apply oom-score-adj to pid %d (%v)", err)
7586
}
7687
}
77-
7888
return err
7989
}
8090

@@ -86,6 +96,10 @@ func (oomAdjuster *OOMAdjuster) applyOOMScoreAdjContainer(cgroupName string, oom
8696
continueAdjusting := false
8797
pidList, err := oomAdjuster.pidLister(cgroupName)
8898
if err != nil {
99+
if syscallNotExists(err) {
100+
// Nothing to do since the container doesn't exist anymore.
101+
return os.ErrNotExist
102+
}
89103
continueAdjusting = true
90104
glog.Errorf("Error getting process list for cgroup %s: %+v", cgroupName, err)
91105
} else if len(pidList) == 0 {
@@ -97,6 +111,7 @@ func (oomAdjuster *OOMAdjuster) applyOOMScoreAdjContainer(cgroupName string, oom
97111
if err = oomAdjuster.ApplyOOMScoreAdj(pid, oomScoreAdj); err == nil {
98112
adjustedProcessSet[pid] = true
99113
}
114+
// Processes can come and go while we try to apply oom score adjust value. So ignore errors here.
100115
}
101116
}
102117
}

pkg/util/procfs/procfs.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ package procfs
1919
import (
2020
"fmt"
2121
"io/ioutil"
22+
"os"
2223
"path"
2324
"strconv"
2425
"strings"
@@ -48,6 +49,9 @@ func (pfs *ProcFS) GetFullContainerName(pid int) (string, error) {
4849
filePath := path.Join("/proc", strconv.Itoa(pid), "cgroup")
4950
content, err := ioutil.ReadFile(filePath)
5051
if err != nil {
52+
if e, ok := err.(*os.SyscallError); ok && os.IsNotExist(e) {
53+
return "", os.ErrNotExist
54+
}
5155
return "", err
5256
}
5357
return containerNameFromProcCgroup(string(content))

0 commit comments

Comments
 (0)