mirror of
				https://github.com/optim-enterprises-bv/kubernetes.git
				synced 2025-11-03 19:58:17 +00:00 
			
		
		
		
	Add support for basic cgroup management
This commit is contained in:
		
							
								
								
									
										113
									
								
								pkg/kubelet/cm/cgroup_manager_linux.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										113
									
								
								pkg/kubelet/cm/cgroup_manager_linux.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,113 @@
 | 
			
		||||
/*
 | 
			
		||||
Copyright 2016 The Kubernetes Authors All rights reserved.
 | 
			
		||||
 | 
			
		||||
Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
you may not use this file except in compliance with the License.
 | 
			
		||||
You may obtain a copy of the License at
 | 
			
		||||
 | 
			
		||||
    http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 | 
			
		||||
Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
See the License for the specific language governing permissions and
 | 
			
		||||
limitations under the License.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
package cm
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
 | 
			
		||||
	libcontainerconfigs "github.com/opencontainers/runc/libcontainer/configs"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// cgroupManagerImpl implements the CgroupManager interface.
 | 
			
		||||
// Its a stateless object which can be used to
 | 
			
		||||
// update,create or delete any number of cgroups
 | 
			
		||||
// It uses the Libcontainer raw fs cgroup manager for cgroup management.
 | 
			
		||||
type cgroupManagerImpl struct {
 | 
			
		||||
	// subsystems holds information about all the
 | 
			
		||||
	// mounted cgroup subsytems on the node
 | 
			
		||||
	subsystems *cgroupSubsystems
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Make sure that cgroupManagerImpl implements the CgroupManager interface
 | 
			
		||||
var _ CgroupManager = &cgroupManagerImpl{}
 | 
			
		||||
 | 
			
		||||
// NewCgroupManager is a factory method that returns a CgroupManager
 | 
			
		||||
func NewCgroupManager(cs *cgroupSubsystems) CgroupManager {
 | 
			
		||||
	return &cgroupManagerImpl{
 | 
			
		||||
		subsystems: cs,
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Destroy destroys the specified cgroup
 | 
			
		||||
func (m *cgroupManagerImpl) Destroy(cgroupConfig *CgroupConfig) error {
 | 
			
		||||
	//cgroup name
 | 
			
		||||
	name := cgroupConfig.Name
 | 
			
		||||
 | 
			
		||||
	// get the fscgroup Manager with the specified cgroup configuration
 | 
			
		||||
	fsCgroupManager, err := getLibcontainerCgroupManager(cgroupConfig, m.subsystems)
 | 
			
		||||
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return fmt.Errorf("Unable to destroy cgroup paths for cgroup %v : %v", name, err)
 | 
			
		||||
	}
 | 
			
		||||
	// Delete cgroups using libcontainers Managers Destroy() method
 | 
			
		||||
	if err := fsCgroupManager.Destroy(); err != nil {
 | 
			
		||||
		return fmt.Errorf("Unable to destroy cgroup paths for cgroup %v : %v", name, err)
 | 
			
		||||
	}
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Update updates the cgroup with the specified Cgroup Configuration
 | 
			
		||||
func (m *cgroupManagerImpl) Update(cgroupConfig *CgroupConfig) error {
 | 
			
		||||
	//cgroup name
 | 
			
		||||
	name := cgroupConfig.Name
 | 
			
		||||
 | 
			
		||||
	// get the fscgroup Manager with the specified cgroup configuration
 | 
			
		||||
	fsCgroupManager, err := getLibcontainerCgroupManager(cgroupConfig, m.subsystems)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return fmt.Errorf("Failed to update cgroup for %v : %v", name, err)
 | 
			
		||||
	}
 | 
			
		||||
	// get config object for passing to Set()
 | 
			
		||||
	config := &libcontainerconfigs.Config{
 | 
			
		||||
		Cgroups: fsCgroupManager.Cgroups,
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Update cgroup configuration using libcontainers Managers Set() method
 | 
			
		||||
	if err := fsCgroupManager.Set(config); err != nil {
 | 
			
		||||
		return fmt.Errorf("Failed to update cgroup for %v: %v", name, err)
 | 
			
		||||
	}
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Create creates the specified cgroup
 | 
			
		||||
func (m *cgroupManagerImpl) Create(cgroupConfig *CgroupConfig) error {
 | 
			
		||||
	//cgroup name
 | 
			
		||||
	name := cgroupConfig.Name
 | 
			
		||||
 | 
			
		||||
	// get the fscgroup Manager with the specified cgroup configuration
 | 
			
		||||
	fsCgroupManager, err := getLibcontainerCgroupManager(cgroupConfig, m.subsystems)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return fmt.Errorf("Failed to create cgroup for %v : %v", name, err)
 | 
			
		||||
	}
 | 
			
		||||
	// get config object for passing to libcontainer's Set() method
 | 
			
		||||
	config := &libcontainerconfigs.Config{
 | 
			
		||||
		Cgroups: fsCgroupManager.Cgroups,
 | 
			
		||||
	}
 | 
			
		||||
	//Apply(0) is a hack to create the cgroup directories for each resource
 | 
			
		||||
	// subsystem. The function [cgroups.Manager.apply()] applies cgroup
 | 
			
		||||
	// configuration to the process with the specified pid.
 | 
			
		||||
	// It creates cgroup files for each subsytems and writes the pid
 | 
			
		||||
	// 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 := fsCgroupManager.Apply(0); err != nil {
 | 
			
		||||
		return fmt.Errorf("Failed to create cgroup for %v: %v", name, err)
 | 
			
		||||
	}
 | 
			
		||||
	// Update cgroup configuration using libcontainers Managers Set() method
 | 
			
		||||
	if err := fsCgroupManager.Set(config); err != nil {
 | 
			
		||||
		return fmt.Errorf("Failed to create cgroup for %v: %v", name, err)
 | 
			
		||||
	}
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										42
									
								
								pkg/kubelet/cm/cgroup_manager_unsupported.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								pkg/kubelet/cm/cgroup_manager_unsupported.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,42 @@
 | 
			
		||||
// +build !linux
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
Copyright 2016 The Kubernetes Authors All rights reserved.
 | 
			
		||||
 | 
			
		||||
Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
you may not use this file except in compliance with the License.
 | 
			
		||||
You may obtain a copy of the License at
 | 
			
		||||
 | 
			
		||||
    http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 | 
			
		||||
Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
See the License for the specific language governing permissions and
 | 
			
		||||
limitations under the License.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
package cm
 | 
			
		||||
 | 
			
		||||
import "fmt"
 | 
			
		||||
 | 
			
		||||
type unsupportedCgroupManager struct{}
 | 
			
		||||
 | 
			
		||||
// Make sure that unsupportedCgroupManager implements the CgroupManager interface
 | 
			
		||||
var _ CgroupManager = &unsupportedCgroupManager{}
 | 
			
		||||
 | 
			
		||||
func NewCgroupManager(_ *cgroupSubsystems) CgroupManager {
 | 
			
		||||
	return &unsupportedCgroupManager{}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (m *unsupportedCgroupManager) Destroy(_ *CgroupConfig) error {
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (m *unsupportedCgroupManager) Update(_ *CgroupConfig) error {
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (m *unsupportedCgroupManager) Create(_ *CgroupConfig) error {
 | 
			
		||||
	return fmt.Errorf("Cgroup Manager is not supported in this build")
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										98
									
								
								pkg/kubelet/cm/helpers_linux.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										98
									
								
								pkg/kubelet/cm/helpers_linux.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,98 @@
 | 
			
		||||
/*
 | 
			
		||||
Copyright 2016 The Kubernetes Authors All rights reserved.
 | 
			
		||||
 | 
			
		||||
Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
you may not use this file except in compliance with the License.
 | 
			
		||||
You may obtain a copy of the License at
 | 
			
		||||
 | 
			
		||||
    http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 | 
			
		||||
Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
See the License for the specific language governing permissions and
 | 
			
		||||
limitations under the License.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
package cm
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"path"
 | 
			
		||||
 | 
			
		||||
	libcontainercgroups "github.com/opencontainers/runc/libcontainer/cgroups"
 | 
			
		||||
	cgroupfs "github.com/opencontainers/runc/libcontainer/cgroups/fs"
 | 
			
		||||
	libcontainerconfigs "github.com/opencontainers/runc/libcontainer/configs"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// cgroupSubsystems holds information about the mounted cgroup subsytems
 | 
			
		||||
type cgroupSubsystems struct {
 | 
			
		||||
	// Cgroup subsystem mounts.
 | 
			
		||||
	// e.g.: "/sys/fs/cgroup/cpu" -> ["cpu", "cpuacct"]
 | 
			
		||||
	mounts []libcontainercgroups.Mount
 | 
			
		||||
 | 
			
		||||
	// Cgroup subsystem to their mount location.
 | 
			
		||||
	// e.g.: "cpu" -> "/sys/fs/cgroup/cpu"
 | 
			
		||||
	mountPoints map[string]string
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// GetCgroupSubsystems returns information about the mounted cgroup subsystems
 | 
			
		||||
func getCgroupSubsystems() (*cgroupSubsystems, error) {
 | 
			
		||||
	// Get all cgroup mounts.
 | 
			
		||||
	allCgroups, err := libcontainercgroups.GetCgroupMounts()
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return &cgroupSubsystems{}, err
 | 
			
		||||
	}
 | 
			
		||||
	if len(allCgroups) == 0 {
 | 
			
		||||
		return &cgroupSubsystems{}, fmt.Errorf("failed to find cgroup mounts")
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	//TODO(@dubstack) should we trim to only the supported ones
 | 
			
		||||
	mountPoints := make(map[string]string, len(allCgroups))
 | 
			
		||||
	for _, mount := range allCgroups {
 | 
			
		||||
		for _, subsystem := range mount.Subsystems {
 | 
			
		||||
			mountPoints[subsystem] = mount.Mountpoint
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return &cgroupSubsystems{
 | 
			
		||||
		mounts:      allCgroups,
 | 
			
		||||
		mountPoints: mountPoints,
 | 
			
		||||
	}, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// getLibcontainerCgroupManager returns libcontainer's cgroups manager
 | 
			
		||||
// object with the specified cgroup configuration
 | 
			
		||||
func getLibcontainerCgroupManager(cgroupConfig *CgroupConfig, subsystems *cgroupSubsystems) (*cgroupfs.Manager, error) {
 | 
			
		||||
	// get cgroup name
 | 
			
		||||
	name := cgroupConfig.Name
 | 
			
		||||
 | 
			
		||||
	// Get map of all cgroup paths on the system for the particular cgroup
 | 
			
		||||
	cgroupPaths := make(map[string]string, len(subsystems.mountPoints))
 | 
			
		||||
	for key, val := range subsystems.mountPoints {
 | 
			
		||||
		cgroupPaths[key] = path.Join(val, name)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Extract the cgroup resource parameters
 | 
			
		||||
	resourceConfig := cgroupConfig.ResourceParameters
 | 
			
		||||
	resources := &libcontainerconfigs.Resources{}
 | 
			
		||||
	resources.AllowAllDevices = true
 | 
			
		||||
	if resourceConfig.Memory != nil {
 | 
			
		||||
		resources.Memory = *resourceConfig.Memory
 | 
			
		||||
	}
 | 
			
		||||
	if resourceConfig.CpuShares != nil {
 | 
			
		||||
		resources.CpuShares = *resourceConfig.CpuShares
 | 
			
		||||
	}
 | 
			
		||||
	if resourceConfig.CpuQuota != nil {
 | 
			
		||||
		resources.CpuQuota = *resourceConfig.CpuQuota
 | 
			
		||||
	}
 | 
			
		||||
	// Initialize libcontainer's cgroup config
 | 
			
		||||
	libcontainerCgroupConfig := &libcontainerconfigs.Cgroup{
 | 
			
		||||
		Name:      path.Base(name),
 | 
			
		||||
		Parent:    path.Dir(name),
 | 
			
		||||
		Resources: resources,
 | 
			
		||||
	}
 | 
			
		||||
	return &cgroupfs.Manager{
 | 
			
		||||
		Cgroups: libcontainerCgroupConfig,
 | 
			
		||||
		Paths:   cgroupPaths,
 | 
			
		||||
	}, nil
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										56
									
								
								pkg/kubelet/cm/types.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										56
									
								
								pkg/kubelet/cm/types.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,56 @@
 | 
			
		||||
/*
 | 
			
		||||
Copyright 2016 The Kubernetes Authors All rights reserved.
 | 
			
		||||
 | 
			
		||||
Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
you may not use this file except in compliance with the License.
 | 
			
		||||
You may obtain a copy of the License at
 | 
			
		||||
 | 
			
		||||
    http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 | 
			
		||||
Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
See the License for the specific language governing permissions and
 | 
			
		||||
limitations under the License.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
package cm
 | 
			
		||||
 | 
			
		||||
// ResourceConfig holds information about all the supported cgroup resource parameters.
 | 
			
		||||
type ResourceConfig struct {
 | 
			
		||||
	// Memory limit (in bytes).
 | 
			
		||||
	Memory *int64
 | 
			
		||||
	// CPU shares (relative weight vs. other containers).
 | 
			
		||||
	CpuShares *int64
 | 
			
		||||
	// CPU hardcap limit (in usecs). Allowed cpu time in a given period.
 | 
			
		||||
	CpuQuota *int64
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// CgroupConfig holds the cgroup configuration information.
 | 
			
		||||
// This is common object which is used to specify
 | 
			
		||||
// cgroup information to both systemd and raw cgroup fs
 | 
			
		||||
// implementation of the Cgroup Manager interface.
 | 
			
		||||
type CgroupConfig struct {
 | 
			
		||||
	// We would expect systemd implementation to make appropriate
 | 
			
		||||
	// name conversion. For example, if we pass /foo/bar
 | 
			
		||||
	// then systemd should convert the name to something like
 | 
			
		||||
	// foo.slice/foo-bar.slice
 | 
			
		||||
 | 
			
		||||
	// Fully qualified name
 | 
			
		||||
	Name string
 | 
			
		||||
	// ResourceParameters contains various cgroups settings to apply.
 | 
			
		||||
	ResourceParameters *ResourceConfig
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// CgroupManager allows for cgroup management.
 | 
			
		||||
// Supports Cgroup Creation ,Deletion and Updates.
 | 
			
		||||
type CgroupManager interface {
 | 
			
		||||
	// Create creates and applies the cgroup configurations on the cgroup.
 | 
			
		||||
	// It just creates the leaf cgroups.
 | 
			
		||||
	// It expects the parent cgroup to already exist.
 | 
			
		||||
	Create(*CgroupConfig) error
 | 
			
		||||
	// Destroys the cgroup.
 | 
			
		||||
	Destroy(*CgroupConfig) error
 | 
			
		||||
	// Update cgroup configuration.
 | 
			
		||||
	Update(*CgroupConfig) error
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user