diff --git a/cmd/kubelet/app/server.go b/cmd/kubelet/app/server.go index 64e39e3322d..34bac9c53a9 100644 --- a/cmd/kubelet/app/server.go +++ b/cmd/kubelet/app/server.go @@ -732,6 +732,16 @@ func run(ctx context.Context, s *options.KubeletServer, kubeDeps *kubelet.Depend devicePluginEnabled := utilfeature.DefaultFeatureGate.Enabled(features.DevicePlugins) + var cpuManagerPolicyOptions map[string]string + if utilfeature.DefaultFeatureGate.Enabled(features.CPUManager) { + if utilfeature.DefaultFeatureGate.Enabled(features.CPUManagerPolicyOptions) { + cpuManagerPolicyOptions = s.CPUManagerPolicyOptions + } else if s.CPUManagerPolicyOptions != nil { + return fmt.Errorf("CPU Manager policy options %v require feature gates %q, %q enabled", + s.CPUManagerPolicyOptions, features.CPUManager, features.CPUManagerPolicyOptions) + } + } + kubeDeps.ContainerManager, err = cm.NewContainerManager( kubeDeps.Mounter, kubeDeps.CAdvisorInterface, @@ -756,6 +766,7 @@ func run(ctx context.Context, s *options.KubeletServer, kubeDeps *kubelet.Depend }, QOSReserved: *experimentalQOSReserved, ExperimentalCPUManagerPolicy: s.CPUManagerPolicy, + ExperimentalCPUManagerPolicyOptions: cpuManagerPolicyOptions, ExperimentalCPUManagerReconcilePeriod: s.CPUManagerReconcilePeriod.Duration, ExperimentalMemoryManagerPolicy: s.MemoryManagerPolicy, ExperimentalMemoryManagerReservedMemory: s.ReservedMemory, diff --git a/pkg/features/kube_features.go b/pkg/features/kube_features.go index 841686d615a..7bc5d0de2ac 100644 --- a/pkg/features/kube_features.go +++ b/pkg/features/kube_features.go @@ -789,6 +789,12 @@ const ( // // Enables kubelet to support memory QoS with cgroups v2. MemoryQoS featuregate.Feature = "MemoryQoS" + + // owner: @fromanirh + // alpha: v1.22 + // + // Allow fine-tuning of cpumanager policies + CPUManagerPolicyOptions featuregate.Feature = "CPUManagerPolicyOptions" ) func init() { @@ -906,6 +912,7 @@ var defaultKubernetesFeatureGates = map[featuregate.Feature]featuregate.FeatureS DelegateFSGroupToCSIDriver: {Default: false, PreRelease: featuregate.Alpha}, KubeletInUserNamespace: {Default: false, PreRelease: featuregate.Alpha}, MemoryQoS: {Default: false, PreRelease: featuregate.Alpha}, + CPUManagerPolicyOptions: {Default: false, PreRelease: featuregate.Alpha}, // inherited features from generic apiserver, relisted here to get a conflict if it is changed // unintentionally on either side: diff --git a/pkg/kubelet/cm/container_manager.go b/pkg/kubelet/cm/container_manager.go index 73e9b88c03d..5dbe856094c 100644 --- a/pkg/kubelet/cm/container_manager.go +++ b/pkg/kubelet/cm/container_manager.go @@ -134,6 +134,7 @@ type NodeConfig struct { NodeAllocatableConfig QOSReserved map[v1.ResourceName]int64 ExperimentalCPUManagerPolicy string + ExperimentalCPUManagerPolicyOptions map[string]string ExperimentalTopologyManagerScope string ExperimentalCPUManagerReconcilePeriod time.Duration ExperimentalMemoryManagerPolicy string diff --git a/pkg/kubelet/cm/container_manager_linux.go b/pkg/kubelet/cm/container_manager_linux.go index b3a4ce786fc..14b62159acd 100644 --- a/pkg/kubelet/cm/container_manager_linux.go +++ b/pkg/kubelet/cm/container_manager_linux.go @@ -332,6 +332,7 @@ func NewContainerManager(mountUtil mount.Interface, cadvisorInterface cadvisor.I if utilfeature.DefaultFeatureGate.Enabled(kubefeatures.CPUManager) { cm.cpuManager, err = cpumanager.NewManager( nodeConfig.ExperimentalCPUManagerPolicy, + nodeConfig.ExperimentalCPUManagerPolicyOptions, nodeConfig.ExperimentalCPUManagerReconcilePeriod, machineInfo, nodeConfig.NodeAllocatableConfig.ReservedSystemCPUs, diff --git a/pkg/kubelet/cm/cpumanager/cpu_manager.go b/pkg/kubelet/cm/cpumanager/cpu_manager.go index 5fd0ec9275f..b8ebf935562 100644 --- a/pkg/kubelet/cm/cpumanager/cpu_manager.go +++ b/pkg/kubelet/cm/cpumanager/cpu_manager.go @@ -143,7 +143,7 @@ func (s *sourcesReadyStub) AddSource(source string) {} func (s *sourcesReadyStub) AllReady() bool { return true } // NewManager creates new cpu manager based on provided policy -func NewManager(cpuPolicyName string, reconcilePeriod time.Duration, machineInfo *cadvisorapi.MachineInfo, specificCPUs cpuset.CPUSet, nodeAllocatableReservation v1.ResourceList, stateFileDirectory string, affinity topologymanager.Store) (Manager, error) { +func NewManager(cpuPolicyName string, cpuPolicyOptions map[string]string, reconcilePeriod time.Duration, machineInfo *cadvisorapi.MachineInfo, specificCPUs cpuset.CPUSet, nodeAllocatableReservation v1.ResourceList, stateFileDirectory string, affinity topologymanager.Store) (Manager, error) { var topo *topology.CPUTopology var policy Policy diff --git a/pkg/kubelet/cm/cpumanager/cpu_manager_test.go b/pkg/kubelet/cm/cpumanager/cpu_manager_test.go index 58ff1e56e44..08ad4611a65 100644 --- a/pkg/kubelet/cm/cpumanager/cpu_manager_test.go +++ b/pkg/kubelet/cm/cpumanager/cpu_manager_test.go @@ -634,7 +634,7 @@ func TestCPUManagerGenerate(t *testing.T) { } defer os.RemoveAll(sDir) - mgr, err := NewManager(testCase.cpuPolicyName, 5*time.Second, machineInfo, cpuset.NewCPUSet(), testCase.nodeAllocatableReservation, sDir, topologymanager.NewFakeManager()) + mgr, err := NewManager(testCase.cpuPolicyName, nil, 5*time.Second, machineInfo, cpuset.NewCPUSet(), testCase.nodeAllocatableReservation, sDir, topologymanager.NewFakeManager()) if testCase.expectedError != nil { if !strings.Contains(err.Error(), testCase.expectedError.Error()) { t.Errorf("Unexpected error message. Have: %s wants %s", err.Error(), testCase.expectedError.Error())