Commit e397cb4e authored by Akihiro Suda's avatar Akihiro Suda Committed by Darren Shepherd

kubelet/cm: ignore cgroups error when running in userns

This is a hacky POC; we need to implement rootless PCM in the proper way. Especially, pcm.Exists(existingPodName) needs to be implemented to return true even when cgroups is not available. Signed-off-by: 's avatarAkihiro Suda <suda.akihiro@lab.ntt.co.jp>
parent 446dd3ff
......@@ -145,6 +145,7 @@ go_library(
"//vendor/github.com/google/cadvisor/events:go_default_library",
"//vendor/github.com/google/cadvisor/info/v1:go_default_library",
"//vendor/github.com/google/cadvisor/info/v2:go_default_library",
"//vendor/github.com/opencontainers/runc/libcontainer/system:go_default_library",
"//vendor/k8s.io/klog:go_default_library",
"//vendor/k8s.io/utils/exec:go_default_library",
"//vendor/k8s.io/utils/integer:go_default_library",
......
......@@ -29,6 +29,7 @@ import (
cgroupfs "github.com/opencontainers/runc/libcontainer/cgroups/fs"
cgroupsystemd "github.com/opencontainers/runc/libcontainer/cgroups/systemd"
libcontainerconfigs "github.com/opencontainers/runc/libcontainer/configs"
rsystem "github.com/opencontainers/runc/libcontainer/system"
"k8s.io/klog"
"k8s.io/apimachinery/pkg/util/sets"
......@@ -148,8 +149,9 @@ func (l *libcontainerAdapter) newManager(cgroups *libcontainerconfigs.Cgroup, pa
switch l.cgroupManagerType {
case libcontainerCgroupfs:
return &cgroupfs.Manager{
Cgroups: cgroups,
Paths: paths,
Cgroups: cgroups,
Rootless: rsystem.RunningInUserNS(),
Paths: paths,
}, nil
case libcontainerSystemd:
// this means you asked systemd to manage cgroups, but systemd was not on the host, so all you can do is panic...
......@@ -482,7 +484,9 @@ func (m *cgroupManagerImpl) Create(cgroupConfig *CgroupConfig) error {
// in the tasks file. We use the function to create all the required
// cgroup files but not attach any "real" pid to the cgroup.
if err := manager.Apply(-1); err != nil {
return err
if !rsystem.RunningInUserNS() {
return err
}
}
// it may confuse why we call set after we do apply, but the issue is that runc
......
......@@ -481,13 +481,20 @@ func (cm *containerManagerImpl) setupNode(activePods ActivePodsFunc) error {
},
}
cont.ensureStateFunc = func(_ *fs.Manager) error {
return ensureProcessInContainerWithOOMScore(os.Getpid(), qos.KubeletOOMScoreAdj, &manager)
err := ensureProcessInContainerWithOOMScore(os.Getpid(), qos.KubeletOOMScoreAdj, &manager)
if rsystem.RunningInUserNS() {
// if we are in userns, cgroups might not be available
err = nil
}
return err
}
systemContainers = append(systemContainers, cont)
} else {
cm.periodicTasks = append(cm.periodicTasks, func() {
if err := ensureProcessInContainerWithOOMScore(os.Getpid(), qos.KubeletOOMScoreAdj, nil); err != nil {
klog.Error(err)
if !rsystem.RunningInUserNS() {
klog.Error(err)
}
return
}
cont, err := getContainer(os.Getpid())
......
......@@ -28,6 +28,7 @@ import (
units "github.com/docker/go-units"
cgroupfs "github.com/opencontainers/runc/libcontainer/cgroups/fs"
rsystem "github.com/opencontainers/runc/libcontainer/system"
"k8s.io/api/core/v1"
utilfeature "k8s.io/apiserver/pkg/util/feature"
"k8s.io/kubernetes/pkg/api/v1/resource"
......@@ -82,7 +83,9 @@ func (m *qosContainerManagerImpl) Start(getNodeAllocatable func() v1.ResourceLis
cm := m.cgroupManager
rootContainer := m.cgroupRoot
if !cm.Exists(rootContainer) {
return fmt.Errorf("root container %v doesn't exist", rootContainer)
if !rsystem.RunningInUserNS() {
return fmt.Errorf("root container %v doesn't exist", rootContainer)
}
}
// Top level for Qos containers are created only for Burstable
......@@ -323,15 +326,23 @@ func (m *qosContainerManagerImpl) UpdateCgroups() error {
}
}
updateSuccess := true
for _, config := range qosConfigs {
err := m.cgroupManager.Update(config)
if err != nil {
klog.Errorf("[ContainerManager]: Failed to update QoS cgroup configuration")
return err
if rsystem.RunningInUserNS() {
// if we are in userns, cgroups might not available
updateSuccess = false
} else {
klog.Errorf("[ContainerManager]: Failed to update QoS cgroup configuration")
return err
}
}
}
klog.V(4).Infof("[ContainerManager]: Updated QoS cgroup configuration")
if updateSuccess {
klog.V(4).Infof("[ContainerManager]: Updated QoS cgroup configuration")
}
return nil
}
......
......@@ -36,6 +36,7 @@ go_library(
"//vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs:go_default_library",
"//vendor/github.com/opencontainers/runc/libcontainer/configs:go_default_library",
"//vendor/k8s.io/klog:go_default_library",
"//vendor/github.com/opencontainers/runc/libcontainer/system:go_default_library",
],
"@io_bazel_rules_go//go/platform:nacl": [
"//pkg/kubelet/dockershim/libdocker:go_default_library",
......
......@@ -27,6 +27,7 @@ import (
"github.com/opencontainers/runc/libcontainer/cgroups/fs"
"github.com/opencontainers/runc/libcontainer/configs"
rsystem "github.com/opencontainers/runc/libcontainer/system"
utilversion "k8s.io/apimachinery/pkg/util/version"
"k8s.io/apimachinery/pkg/util/wait"
"k8s.io/klog"
......@@ -95,7 +96,10 @@ func (m *containerManager) doWork() {
// 1. Ensure processes run in the cgroups if m.cgroupsManager is not nil.
// 2. Ensure processes have the OOM score applied.
if err := kubecm.EnsureDockerInContainer(version, dockerOOMScoreAdj, m.cgroupsManager); err != nil {
klog.Errorf("Unable to ensure the docker processes run in the desired containers: %v", err)
// if we are in userns, the operation is likely to fail, unless cgroupfs is properly chown-ed.
if !rsystem.RunningInUserNS() {
klog.Errorf("Unable to ensure the docker processes run in the desired containers: %v", err)
}
}
}
......
......@@ -33,7 +33,8 @@ import (
cadvisorapi "github.com/google/cadvisor/info/v1"
cadvisorapiv2 "github.com/google/cadvisor/info/v2"
"k8s.io/api/core/v1"
rsystem "github.com/opencontainers/runc/libcontainer/system"
v1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/fields"
"k8s.io/apimachinery/pkg/labels"
......@@ -1585,10 +1586,13 @@ func (kl *Kubelet) syncPod(o syncPodOptions) error {
break
}
}
// TODO(AkihiroSuda): implement rootless cgroup manager that can emulate Exists() properly
// Don't kill containers in pod if pod's cgroups already
// exists or the pod is running for the first time
podKilled := false
if !pcm.Exists(pod) && !firstSync {
if !pcm.Exists(pod) && !firstSync && !rsystem.RunningInUserNS() {
if err := kl.killPod(pod, nil, podStatus, nil); err == nil {
podKilled = true
}
......@@ -1607,7 +1611,9 @@ func (kl *Kubelet) syncPod(o syncPodOptions) error {
}
if err := pcm.EnsureExists(pod); err != nil {
kl.recorder.Eventf(pod, v1.EventTypeWarning, events.FailedToCreatePodContainer, "unable to ensure pod container exists: %v", err)
return fmt.Errorf("failed to ensure that the pod: %v cgroups exist and are correctly applied: %v", pod.UID, err)
if !rsystem.RunningInUserNS() {
return fmt.Errorf("failed to ensure that the pod: %v cgroups exist and are correctly applied: %v", pod.UID, err)
}
}
}
}
......
......@@ -30,6 +30,7 @@ go_library(
"//vendor/github.com/google/cadvisor/info/v1:go_default_library",
"//vendor/github.com/prometheus/client_golang/prometheus:go_default_library",
"//vendor/k8s.io/klog:go_default_library",
"//vendor/github.com/opencontainers/runc/libcontainer/system:go_default_library",
],
)
......
......@@ -21,7 +21,9 @@ import (
"k8s.io/klog"
rsystem "github.com/opencontainers/runc/libcontainer/system"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
statsapi "k8s.io/kubernetes/pkg/kubelet/apis/stats/v1alpha1"
"k8s.io/kubernetes/pkg/kubelet/util"
)
......@@ -74,7 +76,13 @@ func (sp *summaryProviderImpl) Get(updateStats bool) (*statsapi.Summary, error)
nodeConfig := sp.provider.GetNodeConfig()
rootStats, networkStats, err := sp.provider.GetCgroupStats("/", updateStats)
if err != nil {
return nil, fmt.Errorf("failed to get root cgroup stats: %v", err)
if !rsystem.RunningInUserNS() {
return nil, fmt.Errorf("failed to get root cgroup stats: %v", err)
}
// if we are in userns, cgroups might not be available
klog.Errorf("failed to get root cgroup stats: %v", err)
rootStats = &statsapi.ContainerStats{}
networkStats = &statsapi.NetworkStats{}
}
rootFsStats, err := sp.provider.RootFsStats()
if err != nil {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment