mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-25 04:33:26 +00:00
Merge pull request #85218 from giuseppe/cgroupv2
kubelet: add initial support for cgroupv2
This commit is contained in:
commit
34c8b26c9f
@ -21,6 +21,7 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"path"
|
"path"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@ -153,10 +154,11 @@ func (l *libcontainerAdapter) newManager(cgroups *libcontainerconfigs.Cgroup, pa
|
|||||||
if !cgroupsystemd.UseSystemd() {
|
if !cgroupsystemd.UseSystemd() {
|
||||||
panic("systemd cgroup manager not available")
|
panic("systemd cgroup manager not available")
|
||||||
}
|
}
|
||||||
return &cgroupsystemd.LegacyManager{
|
f, err := cgroupsystemd.NewSystemdCgroupsManager()
|
||||||
Cgroups: cgroups,
|
if err != nil {
|
||||||
Paths: paths,
|
return nil, err
|
||||||
}, nil
|
}
|
||||||
|
return f(cgroups, paths), nil
|
||||||
}
|
}
|
||||||
return nil, fmt.Errorf("invalid cgroup manager configuration")
|
return nil, fmt.Errorf("invalid cgroup manager configuration")
|
||||||
}
|
}
|
||||||
@ -254,6 +256,7 @@ func (m *cgroupManagerImpl) Exists(name CgroupName) bool {
|
|||||||
// in https://github.com/opencontainers/runc/issues/1440
|
// in https://github.com/opencontainers/runc/issues/1440
|
||||||
// once resolved, we can remove this code.
|
// once resolved, we can remove this code.
|
||||||
whitelistControllers := sets.NewString("cpu", "cpuacct", "cpuset", "memory", "systemd")
|
whitelistControllers := sets.NewString("cpu", "cpuacct", "cpuset", "memory", "systemd")
|
||||||
|
|
||||||
if utilfeature.DefaultFeatureGate.Enabled(kubefeatures.SupportPodPidsLimit) || utilfeature.DefaultFeatureGate.Enabled(kubefeatures.SupportNodePidsLimit) {
|
if utilfeature.DefaultFeatureGate.Enabled(kubefeatures.SupportPodPidsLimit) || utilfeature.DefaultFeatureGate.Enabled(kubefeatures.SupportNodePidsLimit) {
|
||||||
whitelistControllers.Insert("pids")
|
whitelistControllers.Insert("pids")
|
||||||
}
|
}
|
||||||
@ -369,14 +372,31 @@ func (m *cgroupManagerImpl) toResources(resourceConfig *ResourceConfig) *libcont
|
|||||||
if resourceConfig.Memory != nil {
|
if resourceConfig.Memory != nil {
|
||||||
resources.Memory = *resourceConfig.Memory
|
resources.Memory = *resourceConfig.Memory
|
||||||
}
|
}
|
||||||
if resourceConfig.CpuShares != nil {
|
if libcontainercgroups.IsCgroup2UnifiedMode() {
|
||||||
resources.CpuShares = *resourceConfig.CpuShares
|
if resourceConfig.CpuShares != nil {
|
||||||
}
|
// Convert from the range [2-262144] to [1-10000]
|
||||||
if resourceConfig.CpuQuota != nil {
|
resources.CpuWeight = (1 + ((*resourceConfig.CpuShares-2)*9999)/262142)
|
||||||
resources.CpuQuota = *resourceConfig.CpuQuota
|
}
|
||||||
}
|
|
||||||
if resourceConfig.CpuPeriod != nil {
|
quota := "max"
|
||||||
resources.CpuPeriod = *resourceConfig.CpuPeriod
|
period := "100000"
|
||||||
|
if resourceConfig.CpuQuota != nil {
|
||||||
|
quota = strconv.FormatInt(*resourceConfig.CpuQuota, 10)
|
||||||
|
}
|
||||||
|
if resourceConfig.CpuPeriod != nil {
|
||||||
|
period = strconv.FormatUint(*resourceConfig.CpuPeriod, 10)
|
||||||
|
}
|
||||||
|
resources.CpuMax = fmt.Sprintf("%s %s", quota, period)
|
||||||
|
} else {
|
||||||
|
if resourceConfig.CpuShares != nil {
|
||||||
|
resources.CpuShares = *resourceConfig.CpuShares
|
||||||
|
}
|
||||||
|
if resourceConfig.CpuQuota != nil {
|
||||||
|
resources.CpuQuota = *resourceConfig.CpuQuota
|
||||||
|
}
|
||||||
|
if resourceConfig.CpuPeriod != nil {
|
||||||
|
resources.CpuPeriod = *resourceConfig.CpuPeriod
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if utilfeature.DefaultFeatureGate.Enabled(kubefeatures.SupportPodPidsLimit) || utilfeature.DefaultFeatureGate.Enabled(kubefeatures.SupportNodePidsLimit) {
|
if utilfeature.DefaultFeatureGate.Enabled(kubefeatures.SupportPodPidsLimit) || utilfeature.DefaultFeatureGate.Enabled(kubefeatures.SupportNodePidsLimit) {
|
||||||
if resourceConfig.PidsLimit != nil {
|
if resourceConfig.PidsLimit != nil {
|
||||||
|
@ -161,6 +161,10 @@ func validateSystemRequirements(mountUtil mount.Interface) (features, error) {
|
|||||||
return f, fmt.Errorf("%s - %v", localErr, err)
|
return f, fmt.Errorf("%s - %v", localErr, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if cgroups.IsCgroup2UnifiedMode() {
|
||||||
|
return f, nil
|
||||||
|
}
|
||||||
|
|
||||||
expectedCgroups := sets.NewString("cpu", "cpuacct", "cpuset", "memory")
|
expectedCgroups := sets.NewString("cpu", "cpuacct", "cpuset", "memory")
|
||||||
for _, mountPoint := range mountPoints {
|
for _, mountPoint := range mountPoints {
|
||||||
if mountPoint.Type == cgroupMountType {
|
if mountPoint.Type == cgroupMountType {
|
||||||
@ -884,6 +888,11 @@ func getContainer(pid int) (string, error) {
|
|||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if cgroups.IsCgroup2UnifiedMode() {
|
||||||
|
c, _ := cgs[""]
|
||||||
|
return c, nil
|
||||||
|
}
|
||||||
|
|
||||||
cpu, found := cgs["cpu"]
|
cpu, found := cgs["cpu"]
|
||||||
if !found {
|
if !found {
|
||||||
return "", cgroups.NewNotFoundError("cpu")
|
return "", cgroups.NewNotFoundError("cpu")
|
||||||
|
@ -19,9 +19,11 @@ package cm
|
|||||||
import (
|
import (
|
||||||
"bufio"
|
"bufio"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
|
||||||
libcontainercgroups "github.com/opencontainers/runc/libcontainer/cgroups"
|
libcontainercgroups "github.com/opencontainers/runc/libcontainer/cgroups"
|
||||||
|
|
||||||
@ -32,6 +34,7 @@ import (
|
|||||||
v1helper "k8s.io/kubernetes/pkg/apis/core/v1/helper"
|
v1helper "k8s.io/kubernetes/pkg/apis/core/v1/helper"
|
||||||
v1qos "k8s.io/kubernetes/pkg/apis/core/v1/helper/qos"
|
v1qos "k8s.io/kubernetes/pkg/apis/core/v1/helper/qos"
|
||||||
kubefeatures "k8s.io/kubernetes/pkg/features"
|
kubefeatures "k8s.io/kubernetes/pkg/features"
|
||||||
|
"k8s.io/kubernetes/pkg/kubelet/cm/util"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -181,8 +184,8 @@ func ResourceConfigForPod(pod *v1.Pod, enforceCPULimits bool, cpuPeriod uint64)
|
|||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetCgroupSubsystems returns information about the mounted cgroup subsystems
|
// getCgroupSubsystemsV1 returns information about the mounted cgroup v1 subsystems
|
||||||
func GetCgroupSubsystems() (*CgroupSubsystems, error) {
|
func getCgroupSubsystemsV1() (*CgroupSubsystems, error) {
|
||||||
// get all cgroup mounts.
|
// get all cgroup mounts.
|
||||||
allCgroups, err := libcontainercgroups.GetCgroupMounts(true)
|
allCgroups, err := libcontainercgroups.GetCgroupMounts(true)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -203,6 +206,41 @@ func GetCgroupSubsystems() (*CgroupSubsystems, error) {
|
|||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// getCgroupSubsystemsV2 returns information about the enabled cgroup v2 subsystems
|
||||||
|
func getCgroupSubsystemsV2() (*CgroupSubsystems, error) {
|
||||||
|
content, err := ioutil.ReadFile(filepath.Join(util.CgroupRoot, "cgroup.controllers"))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
mounts := []libcontainercgroups.Mount{}
|
||||||
|
controllers := strings.Fields(string(content))
|
||||||
|
mountPoints := make(map[string]string, len(controllers))
|
||||||
|
for _, controller := range controllers {
|
||||||
|
mountPoints[controller] = util.CgroupRoot
|
||||||
|
m := libcontainercgroups.Mount{
|
||||||
|
Mountpoint: util.CgroupRoot,
|
||||||
|
Root: util.CgroupRoot,
|
||||||
|
Subsystems: []string{controller},
|
||||||
|
}
|
||||||
|
mounts = append(mounts, m)
|
||||||
|
}
|
||||||
|
|
||||||
|
return &CgroupSubsystems{
|
||||||
|
Mounts: mounts,
|
||||||
|
MountPoints: mountPoints,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetCgroupSubsystems returns information about the mounted cgroup subsystems
|
||||||
|
func GetCgroupSubsystems() (*CgroupSubsystems, error) {
|
||||||
|
if libcontainercgroups.IsCgroup2UnifiedMode() {
|
||||||
|
return getCgroupSubsystemsV2()
|
||||||
|
}
|
||||||
|
|
||||||
|
return getCgroupSubsystemsV1()
|
||||||
|
}
|
||||||
|
|
||||||
// getCgroupProcs takes a cgroup directory name as an argument
|
// getCgroupProcs takes a cgroup directory name as an argument
|
||||||
// reads through the cgroup's procs file and returns a list of tgid's.
|
// reads through the cgroup's procs file and returns a list of tgid's.
|
||||||
// It returns an empty list if a procs file doesn't exists
|
// It returns an empty list if a procs file doesn't exists
|
||||||
|
@ -23,19 +23,35 @@ import (
|
|||||||
libcontainerutils "github.com/opencontainers/runc/libcontainer/utils"
|
libcontainerutils "github.com/opencontainers/runc/libcontainer/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
// CgroupRoot is the base path where cgroups are mounted
|
||||||
|
CgroupRoot = "/sys/fs/cgroup"
|
||||||
|
)
|
||||||
|
|
||||||
// GetPids gets pids of the desired cgroup
|
// GetPids gets pids of the desired cgroup
|
||||||
// Forked from opencontainers/runc/libcontainer/cgroup/fs.Manager.GetPids()
|
// Forked from opencontainers/runc/libcontainer/cgroup/fs.Manager.GetPids()
|
||||||
func GetPids(cgroupPath string) ([]int, error) {
|
func GetPids(cgroupPath string) ([]int, error) {
|
||||||
dir, err := getCgroupPath(cgroupPath)
|
dir := ""
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
if libcontainercgroups.IsCgroup2UnifiedMode() {
|
||||||
|
path, err := filepath.Rel("/", cgroupPath)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
dir = filepath.Join(CgroupRoot, path)
|
||||||
|
} else {
|
||||||
|
var err error
|
||||||
|
dir, err = getCgroupV1Path(cgroupPath)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return libcontainercgroups.GetPids(dir)
|
return libcontainercgroups.GetPids(dir)
|
||||||
}
|
}
|
||||||
|
|
||||||
// getCgroupPath gets the file path to the "devices" subsystem of the desired cgroup.
|
// getCgroupV1Path gets the file path to the "devices" subsystem of the desired cgroup.
|
||||||
// cgroupPath is the path in the cgroup hierarchy.
|
// cgroupPath is the path in the cgroup hierarchy.
|
||||||
func getCgroupPath(cgroupPath string) (string, error) {
|
func getCgroupV1Path(cgroupPath string) (string, error) {
|
||||||
cgroupPath = libcontainerutils.CleanPath(cgroupPath)
|
cgroupPath = libcontainerutils.CleanPath(cgroupPath)
|
||||||
|
|
||||||
mnt, root, err := libcontainercgroups.FindCgroupMountpointAndRoot(cgroupPath, "devices")
|
mnt, root, err := libcontainercgroups.FindCgroupMountpointAndRoot(cgroupPath, "devices")
|
||||||
@ -50,7 +66,7 @@ func getCgroupPath(cgroupPath string) (string, error) {
|
|||||||
return filepath.Join(root, mnt, cgroupPath), nil
|
return filepath.Join(root, mnt, cgroupPath), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
parentPath, err := getCgroupParentPath(mnt, root)
|
parentPath, err := getCgroupV1ParentPath(mnt, root)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
@ -58,8 +74,8 @@ func getCgroupPath(cgroupPath string) (string, error) {
|
|||||||
return filepath.Join(parentPath, cgroupPath), nil
|
return filepath.Join(parentPath, cgroupPath), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// getCgroupParentPath gets the parent filepath to this cgroup, for resolving relative cgroup paths.
|
// getCgroupV1ParentPath gets the parent filepath to this cgroup, for resolving relative cgroup paths.
|
||||||
func getCgroupParentPath(mountpoint, root string) (string, error) {
|
func getCgroupV1ParentPath(mountpoint, root string) (string, error) {
|
||||||
// Use GetThisCgroupDir instead of GetInitCgroupDir, because the creating
|
// Use GetThisCgroupDir instead of GetInitCgroupDir, because the creating
|
||||||
// process could in container and shared pid namespace with host, and
|
// process could in container and shared pid namespace with host, and
|
||||||
// /proc/1/cgroup could point to whole other world of cgroups.
|
// /proc/1/cgroup could point to whole other world of cgroups.
|
||||||
|
Loading…
Reference in New Issue
Block a user