Skip to content

Instantly share code, notes, and snippets.

@kolyshkin
Created June 2, 2020 01:22
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kolyshkin/460faa44d952de70fc6676043e065402 to your computer and use it in GitHub Desktop.
Save kolyshkin/460faa44d952de70fc6676043e065402 to your computer and use it in GitHub Desktop.
diff --git a/pkg/kubelet/cm/cgroup_manager_linux.go b/pkg/kubelet/cm/cgroup_manager_linux.go
index 23830a09e74..237a8807184 100644
--- a/pkg/kubelet/cm/cgroup_manager_linux.go
+++ b/pkg/kubelet/cm/cgroup_manager_linux.go
@@ -28,6 +28,7 @@ import (
"time"
libcontainercgroups "github.com/opencontainers/runc/libcontainer/cgroups"
+ libcontainercgroupv1 "github.com/opencontainers/runc/libcontainer/cgroups/cgroupv1"
cgroupfs "github.com/opencontainers/runc/libcontainer/cgroups/fs"
cgroupfs2 "github.com/opencontainers/runc/libcontainer/cgroups/fs2"
cgroupsystemd "github.com/opencontainers/runc/libcontainer/cgroups/systemd"
@@ -149,20 +150,23 @@ func newLibcontainerAdapter(cgroupManagerType libcontainerCgroupManagerType) *li
func (l *libcontainerAdapter) newManager(cgroups *libcontainerconfigs.Cgroup, paths map[string]string) (libcontainercgroups.Manager, error) {
switch l.cgroupManagerType {
case libcontainerCgroupfs:
- return &cgroupfs.Manager{
- Cgroups: cgroups,
- Paths: paths,
- }, nil
+ if libcontainercgroups.IsCgroup2UnifiedMode() {
+ path := paths["cpu"]
+ return cgroupfs2.NewManager(cgroups, path, false)
+ }
+ return cgroupfs.NewManager(cgroups, paths, false), 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...
- if !cgroupsystemd.UseSystemd() {
+ if !cgroupsystemd.IsRunningSystemd() {
panic("systemd cgroup manager not available")
}
- f, err := cgroupsystemd.NewSystemdCgroupsManager()
- if err != nil {
- return nil, err
+ if libcontainercgroups.IsCgroup2UnifiedMode() {
+ path := paths["cpu"]
+ return cgroupsystemd.NewUnifiedManager(cgroups, path, false), nil
}
- return f(cgroups, paths), nil
+ return cgroupsystemd.NewLegacyManager(cgroups, paths), nil
+
}
return nil, fmt.Errorf("invalid cgroup manager configuration")
}
@@ -171,7 +175,7 @@ func (l *libcontainerAdapter) newManager(cgroups *libcontainerconfigs.Cgroup, pa
type CgroupSubsystems struct {
// Cgroup subsystem mounts.
// e.g.: "/sys/fs/cgroup/cpu" -> ["cpu", "cpuacct"]
- Mounts []libcontainercgroups.Mount
+ Mounts []libcontainercgroupv1.Mount
// Cgroup subsystem to their mount location.
// e.g.: "cpu" -> "/sys/fs/cgroup/cpu"
@@ -500,8 +504,6 @@ func setResourcesV2(cgroupConfig *libcontainerconfigs.Cgroup) error {
if err := propagateControllers(cgroupConfig.Path); err != nil {
return err
}
- allowAll := true
- cgroupConfig.Resources.AllowAllDevices = &allowAll
manager, err := cgroupfs2.NewManager(cgroupConfig, cgroupConfig.Path, false)
if err != nil {
diff --git a/pkg/kubelet/cm/container_manager_linux.go b/pkg/kubelet/cm/container_manager_linux.go
index a56bf8dc83d..8700ec031a8 100644
--- a/pkg/kubelet/cm/container_manager_linux.go
+++ b/pkg/kubelet/cm/container_manager_linux.go
@@ -20,6 +20,7 @@ package cm
import (
"bytes"
+ "errors"
"fmt"
"io/ioutil"
"os"
@@ -91,10 +92,10 @@ type systemContainer struct {
// Function that ensures the state of the container.
// m is the cgroup manager for the specified container.
- ensureStateFunc func(m *fs.Manager) error
+ ensureStateFunc func(m cgroups.Manager) error
// Manager for the cgroups of the external container.
- manager *fs.Manager
+ manager cgroups.Manager
}
func newSystemCgroups(containerName string) *systemContainer {
@@ -365,17 +366,12 @@ func (cm *containerManagerImpl) InternalContainerLifecycle() InternalContainerLi
}
// Create a cgroup container manager.
-func createManager(containerName string) *fs.Manager {
- allowAllDevices := true
- return &fs.Manager{
- Cgroups: &configs.Cgroup{
- Parent: "/",
- Name: containerName,
- Resources: &configs.Resources{
- AllowAllDevices: &allowAllDevices,
- },
- },
+func createManager(containerName string) cgroups.Manager {
+ config := &configs.Cgroup{
+ Parent: "/",
+ Name: containerName,
}
+ return fs.NewManager(config, nil, false)
}
type KernelTunableBehavior string
@@ -484,7 +480,7 @@ func (cm *containerManagerImpl) setupNode(activePods ActivePodsFunc) error {
return fmt.Errorf("system container cannot be root (\"/\")")
}
cont := newSystemCgroups(cm.SystemCgroupsName)
- cont.ensureStateFunc = func(manager *fs.Manager) error {
+ cont.ensureStateFunc = func(manager cgroups.Manager) error {
return ensureSystemCgroups("/", manager)
}
systemContainers = append(systemContainers, cont)
@@ -492,18 +488,13 @@ func (cm *containerManagerImpl) setupNode(activePods ActivePodsFunc) error {
if cm.KubeletCgroupsName != "" {
cont := newSystemCgroups(cm.KubeletCgroupsName)
- allowAllDevices := true
- manager := fs.Manager{
- Cgroups: &configs.Cgroup{
- Parent: "/",
- Name: cm.KubeletCgroupsName,
- Resources: &configs.Resources{
- AllowAllDevices: &allowAllDevices,
- },
- },
- }
- cont.ensureStateFunc = func(_ *fs.Manager) error {
- return ensureProcessInContainerWithOOMScore(os.Getpid(), qos.KubeletOOMScoreAdj, &manager)
+ config := &configs.Cgroup{
+ Parent: "/",
+ Name: cm.KubeletCgroupsName,
+ }
+ manager := fs.NewManager(config, nil, false)
+ cont.ensureStateFunc = func(_ cgroups.Manager) error {
+ return ensureProcessInContainerWithOOMScore(os.Getpid(), qos.KubeletOOMScoreAdj, manager)
}
systemContainers = append(systemContainers, cont)
} else {
@@ -821,7 +812,7 @@ func getPidsForProcess(name, pidFile string) ([]int, error) {
// Temporarily export the function to be used by dockershim.
// TODO(yujuhong): Move this function to dockershim once kubelet migrates to
// dockershim as the default.
-func EnsureDockerInContainer(dockerAPIVersion *utilversion.Version, oomScoreAdj int, manager *fs.Manager) error {
+func EnsureDockerInContainer(dockerAPIVersion *utilversion.Version, oomScoreAdj int, manager cgroups.Manager) error {
type process struct{ name, file string }
dockerProcs := []process{{dockerProcessName, dockerPidFile}}
if dockerAPIVersion.AtLeast(containerdAPIVersion) {
@@ -845,7 +836,7 @@ func EnsureDockerInContainer(dockerAPIVersion *utilversion.Version, oomScoreAdj
return utilerrors.NewAggregate(errs)
}
-func ensureProcessInContainerWithOOMScore(pid int, oomScoreAdj int, manager *fs.Manager) error {
+func ensureProcessInContainerWithOOMScore(pid int, oomScoreAdj int, manager cgroups.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
@@ -862,10 +853,11 @@ func ensureProcessInContainerWithOOMScore(pid int, oomScoreAdj int, manager *fs.
errs = append(errs, fmt.Errorf("failed to find container of PID %d: %v", pid, err))
}
- if cont != manager.Cgroups.Name {
+ cg, _ := manager.GetCgroups()
+ if cont != cg.Name {
err = manager.Apply(pid)
if err != nil {
- errs = append(errs, fmt.Errorf("failed to move PID %d (in %q) to %q: %v", pid, cont, manager.Cgroups.Name, err))
+ errs = append(errs, fmt.Errorf("failed to move PID %d (in %q) to %q: %v", pid, cont, cg.Name, err))
}
}
}
@@ -896,11 +888,11 @@ func getContainer(pid int) (string, error) {
cpu, found := cgs["cpu"]
if !found {
- return "", cgroups.NewNotFoundError("cpu")
+ return "", errors.New("container's cpu cgroup not found")
}
memory, found := cgs["memory"]
if !found {
- return "", cgroups.NewNotFoundError("memory")
+ return "", errors.New("container's memory cgroup not found")
}
// since we use this container for accounting, we need to ensure its a unified hierarchy.
@@ -936,7 +928,7 @@ 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.
//
-func ensureSystemCgroups(rootCgroupPath string, manager *fs.Manager) error {
+func ensureSystemCgroups(rootCgroupPath string, manager cgroups.Manager) error {
// Move non-kernel PIDs to the system container.
// Only keep errors on latest attempt.
var finalErr error
@@ -967,7 +959,8 @@ func ensureSystemCgroups(rootCgroupPath string, manager *fs.Manager) error {
for _, pid := range pids {
err := manager.Apply(pid)
if err != nil {
- finalErr = fmt.Errorf("failed to move PID %d into the system container %q: %v", pid, manager.Cgroups.Name, err)
+ cg, _ := manager.GetCgroups()
+ finalErr = fmt.Errorf("failed to move PID %d into the system container %q: %v", pid, cg.Name, err)
}
}
diff --git a/pkg/kubelet/cm/helpers_linux.go b/pkg/kubelet/cm/helpers_linux.go
index ce2d9a9670f..26fad01dcf1 100644
--- a/pkg/kubelet/cm/helpers_linux.go
+++ b/pkg/kubelet/cm/helpers_linux.go
@@ -26,8 +26,9 @@ import (
"strings"
libcontainercgroups "github.com/opencontainers/runc/libcontainer/cgroups"
+ libcontainercgroupv1 "github.com/opencontainers/runc/libcontainer/cgroups/cgroupv1"
- "k8s.io/api/core/v1"
+ v1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/types"
utilfeature "k8s.io/apiserver/pkg/util/feature"
"k8s.io/kubernetes/pkg/api/v1/resource"
@@ -187,7 +188,7 @@ func ResourceConfigForPod(pod *v1.Pod, enforceCPULimits bool, cpuPeriod uint64)
// getCgroupSubsystemsV1 returns information about the mounted cgroup v1 subsystems
func getCgroupSubsystemsV1() (*CgroupSubsystems, error) {
// get all cgroup mounts.
- allCgroups, err := libcontainercgroups.GetCgroupMounts(true)
+ allCgroups, err := libcontainercgroupv1.GetCgroupMounts(true)
if err != nil {
return &CgroupSubsystems{}, err
}
@@ -213,12 +214,12 @@ func getCgroupSubsystemsV2() (*CgroupSubsystems, error) {
return nil, err
}
- mounts := []libcontainercgroups.Mount{}
+ mounts := []libcontainercgroupv1.Mount{}
controllers := strings.Fields(string(content))
mountPoints := make(map[string]string, len(controllers))
for _, controller := range controllers {
mountPoints[controller] = util.CgroupRoot
- m := libcontainercgroups.Mount{
+ m := libcontainercgroupv1.Mount{
Mountpoint: util.CgroupRoot,
Root: util.CgroupRoot,
Subsystems: []string{controller},
diff --git a/pkg/kubelet/cm/util/cgroups_linux.go b/pkg/kubelet/cm/util/cgroups_linux.go
index b7019a95088..2eac742a016 100644
--- a/pkg/kubelet/cm/util/cgroups_linux.go
+++ b/pkg/kubelet/cm/util/cgroups_linux.go
@@ -20,6 +20,7 @@ import (
"path/filepath"
libcontainercgroups "github.com/opencontainers/runc/libcontainer/cgroups"
+ libcontainercgroupv1 "github.com/opencontainers/runc/libcontainer/cgroups/cgroupv1"
libcontainerutils "github.com/opencontainers/runc/libcontainer/utils"
)
@@ -54,7 +55,7 @@ func GetPids(cgroupPath string) ([]int, error) {
func getCgroupV1Path(cgroupPath string) (string, error) {
cgroupPath = libcontainerutils.CleanPath(cgroupPath)
- mnt, root, err := libcontainercgroups.FindCgroupMountpointAndRoot(cgroupPath, "devices")
+ mnt, root, err := libcontainercgroupv1.FindCgroupMountpointAndRoot(cgroupPath, "devices")
// If we didn't mount the subsystem, there is no point we make the path.
if err != nil {
return "", err
@@ -79,7 +80,7 @@ func getCgroupV1ParentPath(mountpoint, root string) (string, error) {
// Use GetThisCgroupDir instead of GetInitCgroupDir, because the creating
// process could in container and shared pid namespace with host, and
// /proc/1/cgroup could point to whole other world of cgroups.
- initPath, err := libcontainercgroups.GetOwnCgroup("devices")
+ initPath, err := libcontainercgroupv1.GetOwnCgroup("devices")
if err != nil {
return "", err
}
diff --git a/pkg/kubelet/dockershim/cm/container_manager_linux.go b/pkg/kubelet/dockershim/cm/container_manager_linux.go
index e133134b0c0..af40f8f9663 100644
--- a/pkg/kubelet/dockershim/cm/container_manager_linux.go
+++ b/pkg/kubelet/dockershim/cm/container_manager_linux.go
@@ -25,6 +25,7 @@ import (
"strconv"
"time"
+ "github.com/opencontainers/runc/libcontainer/cgroups"
"github.com/opencontainers/runc/libcontainer/cgroups/fs"
"github.com/opencontainers/runc/libcontainer/configs"
utilversion "k8s.io/apimachinery/pkg/util/version"
@@ -68,7 +69,7 @@ type containerManager struct {
// Name of the cgroups.
cgroupsName string
// Manager for the cgroups.
- cgroupsManager *fs.Manager
+ cgroupsManager cgroups.Manager
}
func (m *containerManager) Start() error {
@@ -103,7 +104,7 @@ func (m *containerManager) doWork() {
}
}
-func createCgroupManager(name string) (*fs.Manager, error) {
+func createCgroupManager(name string) (cgroups.Manager, error) {
var memoryLimit uint64
memoryCapacity, err := getMemoryCapacity()
@@ -118,19 +119,15 @@ func createCgroupManager(name string) (*fs.Manager, error) {
}
klog.V(2).Infof("Configure resource-only container %q with memory limit: %d", name, memoryLimit)
- allowAllDevices := true
- cm := &fs.Manager{
- Cgroups: &configs.Cgroup{
- Parent: "/",
- Name: name,
- Resources: &configs.Resources{
- Memory: int64(memoryLimit),
- MemorySwap: -1,
- AllowAllDevices: &allowAllDevices,
- },
+ config := &configs.Cgroup{
+ Parent: "/",
+ Name: name,
+ Resources: &configs.Resources{
+ Memory: int64(memoryLimit),
+ MemorySwap: -1,
},
}
- return cm, nil
+ return fs.NewManager(config, nil, false), nil
}
// getMemoryCapacity returns the memory capacity on the machine in bytes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment