mirror of
				https://github.com/optim-enterprises-bv/kubernetes.git
				synced 2025-11-04 12:18:16 +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