From f3c41b7650340bddfa44129c72e7f9fb79061b90 Mon Sep 17 00:00:00 2001 From: Akihiro Suda Date: Fri, 22 Jan 2021 22:08:08 +0900 Subject: [PATCH] fix cgroup2 support Fix issue 900 cgroup2 support was introduced in PR 2584, but got broken in f3de60ff3191dc3a0ae7ce8393e388700f48ed88 It was failing with "F1210 19:13:37.305388 4955 server.go:181] cannot set feature gate SupportPodPidsLimit to false, feature is locked to true" Signed-off-by: Akihiro Suda --- pkg/daemons/agent/agent.go | 28 ++++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/pkg/daemons/agent/agent.go b/pkg/daemons/agent/agent.go index 7ba93b78cdd..b589a4740fb 100644 --- a/pkg/daemons/agent/agent.go +++ b/pkg/daemons/agent/agent.go @@ -8,6 +8,8 @@ import ( "strings" "time" + "github.com/containerd/cgroups" + cgroupsv2 "github.com/containerd/cgroups/v2" "github.com/opencontainers/runc/libcontainer/system" "github.com/rancher/k3s/pkg/daemons/config" "github.com/rancher/k3s/pkg/daemons/executor" @@ -188,6 +190,26 @@ func checkCgroups() (kubeletRoot, runtimeRoot string, hasCFS, hasPIDs bool) { } defer f.Close() + v2 := cgroups.Mode() == cgroups.Unified + if v2 { + m, err := cgroupsv2.LoadManager("/sys/fs/cgroup", "/") + if err != nil { + return "", "", false, false + } + controllers, err := m.Controllers() + if err != nil { + return "", "", false, false + } + for _, c := range controllers { + switch c { + case "cpu": + hasCFS = true + case "pids": + hasPIDs = true + } + } + } + scan := bufio.NewScanner(f) for scan.Scan() { parts := strings.Split(scan.Text(), ":") @@ -195,6 +217,7 @@ func checkCgroups() (kubeletRoot, runtimeRoot string, hasCFS, hasPIDs bool) { continue } systems := strings.Split(parts[1], ",") + // when v2, systems = {""} (only contains a single empty string) for _, system := range systems { if system == "pids" { hasPIDs = true @@ -203,7 +226,7 @@ func checkCgroups() (kubeletRoot, runtimeRoot string, hasCFS, hasPIDs bool) { if _, err := os.Stat(p); err == nil { hasCFS = true } - } else if system == "name=systemd" { + } else if system == "name=systemd" || v2 { // If we detect that we are running under a `.scope` unit with systemd // we can assume we are being directly invoked from the command line // and thus need to set our kubelet root to something out of the context @@ -239,8 +262,9 @@ func checkCgroups() (kubeletRoot, runtimeRoot string, hasCFS, hasPIDs bool) { continue } systems := strings.Split(parts[1], ",") + // when v2, systems = {""} (only contains a single empty string) for _, system := range systems { - if system == "name=systemd" { + if system == "name=systemd" || v2 { last := parts[len(parts)-1] if last != "/" && last != "/init.scope" { kubeletRoot = "/" + version.Program