Move containerd process into docker cgroup for versions >= v1.11

pull/6/head
Tim St. Clair 2016-05-26 17:27:00 -07:00
parent f24b7a7391
commit e4d8dea0d7
1 changed files with 70 additions and 29 deletions

View File

@ -29,6 +29,7 @@ import (
"sync"
"time"
"github.com/blang/semver"
"github.com/golang/glog"
"github.com/opencontainers/runc/libcontainer/cgroups"
"github.com/opencontainers/runc/libcontainer/cgroups/fs"
@ -56,6 +57,13 @@ const (
dockerProcessName = "docker"
dockerPidFile = "/var/run/docker.pid"
containerdProcessName = "docker-containerd"
containerdPidFile = "/run/docker/libcontainerd/docker-containerd.pid"
)
var (
// The docker version in which containerd was introduced.
containerdVersion = semver.MustParse("1.11.0")
)
// A non-user container tracked by the Kubelet.
@ -261,8 +269,9 @@ func (cm *containerManagerImpl) setupNode() error {
},
},
}
dockerVersion := getDockerVersion(cm.cadvisorInterface)
cont.ensureStateFunc = func(manager *fs.Manager) error {
return ensureDockerInContainer(cm.cadvisorInterface, -900, dockerContainer)
return ensureDockerInContainer(dockerVersion, -900, dockerContainer)
}
systemContainers = append(systemContainers, cont)
} else {
@ -370,6 +379,7 @@ func (cm *containerManagerImpl) Start() error {
}
}
if numEnsureStateFuncs >= 0 {
// Run ensure state functions every minute.
go wait.Until(func() {
for _, cont := range cm.systemContainers {
if cont.ensureStateFunc != nil {
@ -382,7 +392,6 @@ func (cm *containerManagerImpl) Start() error {
}
// Run ensure state functions every minute.
if len(cm.periodicTasks) > 0 {
go wait.Until(func() {
for _, task := range cm.periodicTasks {
@ -472,23 +481,41 @@ func getPidsForProcess(name, pidFile string) ([]int, error) {
}
// Ensures that the Docker daemon is in the desired container.
func ensureDockerInContainer(cadvisor cadvisor.Interface, oomScoreAdj int, manager *fs.Manager) error {
pids, err := getPidsForProcess(dockerProcessName, dockerPidFile)
if err != nil {
return err
func ensureDockerInContainer(dockerVersion semver.Version, oomScoreAdj int, manager *fs.Manager) error {
type process struct{ name, file string }
dockerProcs := []process{{dockerProcessName, dockerPidFile}}
if dockerVersion.GTE(containerdVersion) {
dockerProcs = append(dockerProcs, process{containerdProcessName, containerdPidFile})
}
// Move if the pid is not already in the desired container.
errs := []error{}
for _, pid := range pids {
if runningInHost, err := isProcessRunningInHost(pid); err != nil {
errs = append(errs, err)
// Err on the side of caution. Avoid moving the docker daemon unless we are able to identify its context.
continue
} else if !runningInHost {
// Docker daemon is running inside a container. Don't touch that.
var errs []error
for _, proc := range dockerProcs {
pids, err := getPidsForProcess(proc.name, proc.file)
if err != nil {
errs = append(errs, fmt.Errorf("failed to get pids for %q: %v", proc.name, err))
continue
}
// Move if the pid is not already in the desired container.
for _, pid := range pids {
if err := ensureProcessInContainer(pid, oomScoreAdj, manager); err != nil {
errs = append(errs, fmt.Errorf("errors moving %q pid: %v", proc.name, err))
}
}
}
return utilerrors.NewAggregate(errs)
}
func ensureProcessInContainer(pid int, oomScoreAdj int, manager *fs.Manager) error {
if runningInHost, err := isProcessRunningInHost(pid); err != nil {
// Err on the side of caution. Avoid moving the docker daemon unless we are able to identify its context.
return err
} else if !runningInHost {
// Process is running inside a container. Don't touch that.
return nil
}
var errs []error
cont, err := getContainer(pid)
if err != nil {
errs = append(errs, fmt.Errorf("failed to find container of PID %d: %v", pid, err))
@ -506,8 +533,6 @@ func ensureDockerInContainer(cadvisor cadvisor.Interface, oomScoreAdj int, manag
if err := oomAdjuster.ApplyOOMScoreAdj(pid, oomScoreAdj); err != nil {
errs = append(errs, fmt.Errorf("failed to apply oom score %d to PID %d", oomScoreAdj, pid))
}
}
return utilerrors.NewAggregate(errs)
}
@ -585,3 +610,19 @@ func isKernelPid(pid int) bool {
_, err := os.Readlink(fmt.Sprintf("/proc/%d/exe", pid))
return err != nil
}
// Helper for getting the docker version.
func getDockerVersion(cadvisor cadvisor.Interface) semver.Version {
var fallback semver.Version // Fallback to zero-value by default.
versions, err := cadvisor.VersionInfo()
if err != nil {
glog.Errorf("Error requesting cAdvisor VersionInfo: %v", err)
return fallback
}
dockerVersion, err := semver.Parse(versions.DockerVersion)
if err != nil {
glog.Errorf("Error parsing docker version %q: %v", versions.DockerVersion, err)
return fallback
}
return dockerVersion
}