Fix detection of docker cgroup on RHEL

Check docker's pid file, then fallback to pidof when trying to determine the pid for docker. The
latest docker RPM for RHEL changes /usr/bin/docker from an executable to a shell script (to support
/usr/bin/docker-current and /usr/bin/docker-latest). The pidof check for docker fails in this case,
so we check /var/run/docker.pid first (the default location), and fallback to pidof if that fails.
This commit is contained in:
Andy Goldstein 2016-05-19 15:44:42 -04:00
parent 9784dff94e
commit 6744a7417a

View File

@ -20,6 +20,7 @@ package cm
import ( import (
"fmt" "fmt"
"io/ioutil"
"os" "os"
"os/exec" "os/exec"
"path" "path"
@ -39,6 +40,7 @@ import (
utilerrors "k8s.io/kubernetes/pkg/util/errors" utilerrors "k8s.io/kubernetes/pkg/util/errors"
"k8s.io/kubernetes/pkg/util/mount" "k8s.io/kubernetes/pkg/util/mount"
"k8s.io/kubernetes/pkg/util/oom" "k8s.io/kubernetes/pkg/util/oom"
"k8s.io/kubernetes/pkg/util/runtime"
"k8s.io/kubernetes/pkg/util/sets" "k8s.io/kubernetes/pkg/util/sets"
utilsysctl "k8s.io/kubernetes/pkg/util/sysctl" utilsysctl "k8s.io/kubernetes/pkg/util/sysctl"
"k8s.io/kubernetes/pkg/util/wait" "k8s.io/kubernetes/pkg/util/wait"
@ -51,6 +53,9 @@ const (
DockerMemoryLimitThresholdPercent = 70 DockerMemoryLimitThresholdPercent = 70
// The minimum memory limit allocated to docker container: 150Mi // The minimum memory limit allocated to docker container: 150Mi
MinDockerMemoryLimit = 150 * 1024 * 1024 MinDockerMemoryLimit = 150 * 1024 * 1024
dockerProcessName = "docker"
dockerPidFile = "/var/run/docker.pid"
) )
// A non-user container tracked by the Kubelet. // A non-user container tracked by the Kubelet.
@ -262,11 +267,12 @@ func (cm *containerManagerImpl) setupNode() error {
systemContainers = append(systemContainers, cont) systemContainers = append(systemContainers, cont)
} else { } else {
cm.periodicTasks = append(cm.periodicTasks, func() { cm.periodicTasks = append(cm.periodicTasks, func() {
cont, err := getContainerNameForProcess("docker") cont, err := getContainerNameForProcess(dockerProcessName, dockerPidFile)
if err != nil { if err != nil {
glog.Error(err) glog.Error(err)
return return
} }
glog.V(2).Infof("Discovered runtime cgroups name: %s", cont)
cm.Lock() cm.Lock()
defer cm.Unlock() defer cm.Unlock()
cm.RuntimeCgroupsName = cont cm.RuntimeCgroupsName = cont
@ -324,8 +330,8 @@ func (cm *containerManagerImpl) setupNode() error {
return nil return nil
} }
func getContainerNameForProcess(name string) (string, error) { func getContainerNameForProcess(name, pidFile string) (string, error) {
pids, err := getPidsForProcess(name) pids, err := getPidsForProcess(name, pidFile)
if err != nil { if err != nil {
return "", fmt.Errorf("failed to detect process id for %q - %v", name, err) return "", fmt.Errorf("failed to detect process id for %q - %v", name, err)
} }
@ -418,7 +424,36 @@ func isProcessRunningInHost(pid int) (bool, error) {
return initMntNs == processMntNs, nil return initMntNs == processMntNs, nil
} }
func getPidsForProcess(name string) ([]int, error) { func getPidFromPidFile(pidFile string) (int, error) {
file, err := os.Open(pidFile)
if err != nil {
return 0, fmt.Errorf("error opening pid file %s: %v", pidFile, err)
}
defer file.Close()
data, err := ioutil.ReadAll(file)
if err != nil {
return 0, fmt.Errorf("error reading pid file %s: %v", pidFile, err)
}
pid, err := strconv.Atoi(string(data))
if err != nil {
return 0, fmt.Errorf("error parsing %s as a number: %v", string(data), err)
}
return pid, nil
}
func getPidsForProcess(name, pidFile string) ([]int, error) {
if len(pidFile) > 0 {
if pid, err := getPidFromPidFile(pidFile); err == nil {
return []int{pid}, nil
} else {
// log the error and fall back to pidof
runtime.HandleError(err)
}
}
out, err := exec.Command("pidof", name).Output() out, err := exec.Command("pidof", name).Output()
if err != nil { if err != nil {
return []int{}, fmt.Errorf("failed to find pid of %q: %v", name, err) return []int{}, fmt.Errorf("failed to find pid of %q: %v", name, err)
@ -438,7 +473,7 @@ func getPidsForProcess(name string) ([]int, error) {
// Ensures that the Docker daemon is in the desired container. // Ensures that the Docker daemon is in the desired container.
func ensureDockerInContainer(cadvisor cadvisor.Interface, oomScoreAdj int, manager *fs.Manager) error { func ensureDockerInContainer(cadvisor cadvisor.Interface, oomScoreAdj int, manager *fs.Manager) error {
pids, err := getPidsForProcess("docker") pids, err := getPidsForProcess(dockerProcessName, dockerPidFile)
if err != nil { if err != nil {
return err return err
} }