From 62fe566e68620fd691723079f1fcf98cead0f479 Mon Sep 17 00:00:00 2001 From: Vishnu kannan Date: Thu, 4 Feb 2016 13:34:56 -0800 Subject: [PATCH] Kubelet will not move docker daemons running in containers. Signed-off-by: Vishnu kannan --- pkg/kubelet/cm/container_manager_linux.go | 26 +++++++++++++--- pkg/kubelet/kubelet.go | 38 +++++++++++------------ 2 files changed, 41 insertions(+), 23 deletions(-) diff --git a/pkg/kubelet/cm/container_manager_linux.go b/pkg/kubelet/cm/container_manager_linux.go index 31d016e9ca..5fb8c360c1 100644 --- a/pkg/kubelet/cm/container_manager_linux.go +++ b/pkg/kubelet/cm/container_manager_linux.go @@ -300,6 +300,19 @@ func (cm *containerManagerImpl) SystemContainersLimit() api.ResourceList { } } +func isProcessRunningInHost(pid int) (bool, error) { + // Get init mount namespace. Mount namespace is unique for all containers. + initMntNs, err := os.Readlink("/proc/1/ns/mnt") + if err != nil { + return false, fmt.Errorf("failed to find mount namespace of init process") + } + processMntNs, err := os.Readlink(fmt.Sprintf("/proc/%d/ns/mnt", pid)) + if err != nil { + return false, fmt.Errorf("failed to find mount namespace of process %q", pid) + } + return initMntNs == processMntNs, nil +} + // Ensures that the Docker daemon is in the desired container. func ensureDockerInContainer(cadvisor cadvisor.Interface, oomScoreAdj int, manager *fs.Manager) error { // What container is Docker in? @@ -322,6 +335,15 @@ func ensureDockerInContainer(cadvisor cadvisor.Interface, oomScoreAdj int, manag // 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. + continue + } + cont, err := getContainer(pid) if err != nil { errs = append(errs, fmt.Errorf("failed to find container of PID %d: %v", pid, err)) @@ -365,10 +387,6 @@ func getContainer(pid int) (string, error) { // The reason of leaving kernel threads at root cgroup is that we don't want to tie the // execution of these threads with to-be defined /system quota and create priority inversions. // -// The reason of leaving process 1 at root cgroup is that libcontainer hardcoded on -// the base cgroup path based on process 1. Please see: -// https://github.com/kubernetes/kubernetes/issues/12789#issuecomment-132384126 -// for detail explanation. func ensureSystemContainer(rootContainer *fs.Manager, manager *fs.Manager) error { // Move non-kernel PIDs to the system container. attemptsRemaining := 10 diff --git a/pkg/kubelet/kubelet.go b/pkg/kubelet/kubelet.go index a94b90aff0..d4459a49bb 100644 --- a/pkg/kubelet/kubelet.go +++ b/pkg/kubelet/kubelet.go @@ -891,22 +891,7 @@ func (kl *Kubelet) StartGarbageCollection() { // initializeModules will initialize internal modules that do not require the container runtime to be up. // Note that the modules here must not depend on modules that are not initialized here. func (kl *Kubelet) initializeModules() error { - // Promethues metrics. - metrics.Register(kl.runtimeCache) - - // Step 1: Setup filesystem directories. - if err := kl.setupDataDirs(); err != nil { - return err - } - - // Step 2: If the container logs directory does not exist, create it. - if _, err := os.Stat(containerLogsDir); err != nil { - if err := kl.os.Mkdir(containerLogsDir, 0755); err != nil { - glog.Errorf("Failed to create directory %q: %v", containerLogsDir, err) - } - } - - // Step 3: Move Kubelet to a container, if required. + // Step 1: Move Kubelet to a container, if required. if kl.resourceContainer != "" { // Fixme: I need to reside inside ContainerManager interface. err := util.RunInResourceContainer(kl.resourceContainer) @@ -916,17 +901,32 @@ func (kl *Kubelet) initializeModules() error { glog.Infof("Running in container %q", kl.resourceContainer) } - // Step 4: Start the image manager. + // Step 2: Promethues metrics. + metrics.Register(kl.runtimeCache) + + // Step 3: Setup filesystem directories. + if err := kl.setupDataDirs(); err != nil { + return err + } + + // Step 4: If the container logs directory does not exist, create it. + if _, err := os.Stat(containerLogsDir); err != nil { + if err := kl.os.Mkdir(containerLogsDir, 0755); err != nil { + glog.Errorf("Failed to create directory %q: %v", containerLogsDir, err) + } + } + + // Step 5: Start the image manager. if err := kl.imageManager.Start(); err != nil { return fmt.Errorf("Failed to start ImageManager, images may not be garbage collected: %v", err) } - // Step 5: Start container manager. + // Step 6: Start container manager. if err := kl.containerManager.Start(kl.nodeConfig); err != nil { return fmt.Errorf("Failed to start ContainerManager %v", err) } - // Step 6: Start out of memory watcher. + // Step 7: Start out of memory watcher. if err := kl.oomWatcher.Start(kl.nodeRef); err != nil { return fmt.Errorf("Failed to start OOM watcher %v", err) }