topologymanager: promote TopologyManagerPolicyOptions feature to beta

* Promote TopologyManagerPolicyOptions feature to beta
* Promote PreferClosestNUMANodes TopologyManagerPolicyOption to beta

Signed-off-by: PiotrProkop <pprokop@nvidia.com>
This commit is contained in:
PiotrProkop 2023-06-30 10:20:42 +02:00
parent 23833b9c81
commit f855a23b45
7 changed files with 81 additions and 50 deletions

View File

@ -743,18 +743,18 @@ func run(ctx context.Context, s *options.KubeletServer, kubeDeps *kubelet.Depend
ReservedSystemCPUs: reservedSystemCPUs, ReservedSystemCPUs: reservedSystemCPUs,
HardEvictionThresholds: hardEvictionThresholds, HardEvictionThresholds: hardEvictionThresholds,
}, },
QOSReserved: *experimentalQOSReserved, QOSReserved: *experimentalQOSReserved,
CPUManagerPolicy: s.CPUManagerPolicy, CPUManagerPolicy: s.CPUManagerPolicy,
CPUManagerPolicyOptions: cpuManagerPolicyOptions, CPUManagerPolicyOptions: cpuManagerPolicyOptions,
CPUManagerReconcilePeriod: s.CPUManagerReconcilePeriod.Duration, CPUManagerReconcilePeriod: s.CPUManagerReconcilePeriod.Duration,
ExperimentalMemoryManagerPolicy: s.MemoryManagerPolicy, ExperimentalMemoryManagerPolicy: s.MemoryManagerPolicy,
ExperimentalMemoryManagerReservedMemory: s.ReservedMemory, ExperimentalMemoryManagerReservedMemory: s.ReservedMemory,
PodPidsLimit: s.PodPidsLimit, PodPidsLimit: s.PodPidsLimit,
EnforceCPULimits: s.CPUCFSQuota, EnforceCPULimits: s.CPUCFSQuota,
CPUCFSQuotaPeriod: s.CPUCFSQuotaPeriod.Duration, CPUCFSQuotaPeriod: s.CPUCFSQuotaPeriod.Duration,
TopologyManagerPolicy: s.TopologyManagerPolicy, TopologyManagerPolicy: s.TopologyManagerPolicy,
TopologyManagerScope: s.TopologyManagerScope, TopologyManagerScope: s.TopologyManagerScope,
ExperimentalTopologyManagerPolicyOptions: topologyManagerPolicyOptions, TopologyManagerPolicyOptions: topologyManagerPolicyOptions,
}, },
s.FailSwapOn, s.FailSwapOn,
kubeDeps.Recorder, kubeDeps.Recorder,

View File

@ -1064,7 +1064,7 @@ var defaultKubernetesFeatureGates = map[featuregate.Feature]featuregate.FeatureS
TopologyManagerPolicyBetaOptions: {Default: true, PreRelease: featuregate.Beta}, TopologyManagerPolicyBetaOptions: {Default: true, PreRelease: featuregate.Beta},
TopologyManagerPolicyOptions: {Default: false, PreRelease: featuregate.Alpha}, TopologyManagerPolicyOptions: {Default: true, PreRelease: featuregate.Beta},
VolumeCapacityPriority: {Default: false, PreRelease: featuregate.Alpha}, VolumeCapacityPriority: {Default: false, PreRelease: featuregate.Alpha},

View File

@ -146,18 +146,18 @@ type NodeConfig struct {
KubeletRootDir string KubeletRootDir string
ProtectKernelDefaults bool ProtectKernelDefaults bool
NodeAllocatableConfig NodeAllocatableConfig
QOSReserved map[v1.ResourceName]int64 QOSReserved map[v1.ResourceName]int64
CPUManagerPolicy string CPUManagerPolicy string
CPUManagerPolicyOptions map[string]string CPUManagerPolicyOptions map[string]string
TopologyManagerScope string TopologyManagerScope string
CPUManagerReconcilePeriod time.Duration CPUManagerReconcilePeriod time.Duration
ExperimentalMemoryManagerPolicy string ExperimentalMemoryManagerPolicy string
ExperimentalMemoryManagerReservedMemory []kubeletconfig.MemoryReservation ExperimentalMemoryManagerReservedMemory []kubeletconfig.MemoryReservation
PodPidsLimit int64 PodPidsLimit int64
EnforceCPULimits bool EnforceCPULimits bool
CPUCFSQuotaPeriod time.Duration CPUCFSQuotaPeriod time.Duration
TopologyManagerPolicy string TopologyManagerPolicy string
ExperimentalTopologyManagerPolicyOptions map[string]string TopologyManagerPolicyOptions map[string]string
} }
type NodeAllocatableConfig struct { type NodeAllocatableConfig struct {

View File

@ -292,7 +292,7 @@ func NewContainerManager(mountUtil mount.Interface, cadvisorInterface cadvisor.I
machineInfo.Topology, machineInfo.Topology,
nodeConfig.TopologyManagerPolicy, nodeConfig.TopologyManagerPolicy,
nodeConfig.TopologyManagerScope, nodeConfig.TopologyManagerScope,
nodeConfig.ExperimentalTopologyManagerPolicyOptions, nodeConfig.TopologyManagerPolicyOptions,
) )
if err != nil { if err != nil {

View File

@ -30,10 +30,10 @@ const (
) )
var ( var (
alphaOptions = sets.NewString( alphaOptions = sets.NewString()
betaOptions = sets.NewString(
PreferClosestNUMANodes, PreferClosestNUMANodes,
) )
betaOptions = sets.NewString()
stableOptions = sets.NewString() stableOptions = sets.NewString()
) )

View File

@ -29,6 +29,7 @@ import (
) )
var fancyBetaOption = "fancy-new-option" var fancyBetaOption = "fancy-new-option"
var fancyAlphaOption = "fancy-alpha-option"
type optionAvailTest struct { type optionAvailTest struct {
option string option string
@ -39,15 +40,17 @@ type optionAvailTest struct {
func TestNewTopologyManagerOptions(t *testing.T) { func TestNewTopologyManagerOptions(t *testing.T) {
testCases := []struct { testCases := []struct {
description string description string
policyOptions map[string]string policyOptions map[string]string
featureGate featuregate.Feature featureGate featuregate.Feature
expectedErr error featureGateEnable bool
expectedOptions PolicyOptions expectedErr error
expectedOptions PolicyOptions
}{ }{
{ {
description: "return TopologyManagerOptions with PreferClosestNUMA set to true", description: "return TopologyManagerOptions with PreferClosestNUMA set to true",
featureGate: pkgfeatures.TopologyManagerPolicyAlphaOptions, featureGate: pkgfeatures.TopologyManagerPolicyBetaOptions,
featureGateEnable: true,
expectedOptions: PolicyOptions{ expectedOptions: PolicyOptions{
PreferClosestNUMA: true, PreferClosestNUMA: true,
}, },
@ -55,39 +58,66 @@ func TestNewTopologyManagerOptions(t *testing.T) {
PreferClosestNUMANodes: "true", PreferClosestNUMANodes: "true",
}, },
}, },
{
description: "fail to set option when TopologyManagerPolicyBetaOptions feature gate is not set",
featureGate: pkgfeatures.TopologyManagerPolicyBetaOptions,
policyOptions: map[string]string{
PreferClosestNUMANodes: "true",
},
expectedErr: fmt.Errorf("Topology Manager Policy Beta-level Options not enabled,"),
},
{ {
description: "return empty TopologyManagerOptions", description: "return empty TopologyManagerOptions",
}, },
{ {
description: "fail to parse options", description: "fail to parse options",
featureGate: pkgfeatures.TopologyManagerPolicyAlphaOptions, featureGate: pkgfeatures.TopologyManagerPolicyAlphaOptions,
featureGateEnable: true,
policyOptions: map[string]string{ policyOptions: map[string]string{
PreferClosestNUMANodes: "not a boolean", PreferClosestNUMANodes: "not a boolean",
}, },
expectedErr: fmt.Errorf("bad value for option"), expectedErr: fmt.Errorf("bad value for option"),
}, },
{ {
description: "test beta options success", description: "test beta options success",
featureGate: pkgfeatures.TopologyManagerPolicyBetaOptions, featureGate: pkgfeatures.TopologyManagerPolicyBetaOptions,
featureGateEnable: true,
policyOptions: map[string]string{ policyOptions: map[string]string{
fancyBetaOption: "true", fancyBetaOption: "true",
}, },
}, },
{ {
description: "test beta options success", description: "test beta options fail",
featureGate: pkgfeatures.TopologyManagerPolicyBetaOptions,
policyOptions: map[string]string{ policyOptions: map[string]string{
fancyBetaOption: "true", fancyBetaOption: "true",
}, },
expectedErr: fmt.Errorf("Topology Manager Policy Beta-level Options not enabled,"), expectedErr: fmt.Errorf("Topology Manager Policy Beta-level Options not enabled,"),
}, },
{
description: "test alpha options success",
featureGate: pkgfeatures.TopologyManagerPolicyAlphaOptions,
featureGateEnable: true,
policyOptions: map[string]string{
fancyAlphaOption: "true",
},
},
{
description: "test alpha options fail",
policyOptions: map[string]string{
fancyAlphaOption: "true",
},
expectedErr: fmt.Errorf("Topology Manager Policy Alpha-level Options not enabled,"),
},
} }
betaOptions = sets.NewString(fancyBetaOption) betaOptions.Insert(fancyBetaOption)
alphaOptions = sets.NewString(fancyAlphaOption)
for _, tcase := range testCases { for _, tcase := range testCases {
t.Run(tcase.description, func(t *testing.T) { t.Run(tcase.description, func(t *testing.T) {
if tcase.featureGate != "" { if tcase.featureGate != "" {
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, tcase.featureGate, true)() defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, tcase.featureGate, tcase.featureGateEnable)()
} }
opts, err := NewPolicyOptions(tcase.policyOptions) opts, err := NewPolicyOptions(tcase.policyOptions)
if tcase.expectedErr != nil { if tcase.expectedErr != nil {
@ -112,7 +142,7 @@ func TestPolicyDefaultsAvailable(t *testing.T) {
}, },
{ {
option: PreferClosestNUMANodes, option: PreferClosestNUMANodes,
expectedAvailable: false, expectedAvailable: true,
}, },
} }
for _, testCase := range testCases { for _, testCase := range testCases {
@ -142,15 +172,15 @@ func TestPolicyOptionsAvailable(t *testing.T) {
}, },
{ {
option: PreferClosestNUMANodes, option: PreferClosestNUMANodes,
featureGate: pkgfeatures.TopologyManagerPolicyAlphaOptions, featureGate: pkgfeatures.TopologyManagerPolicyBetaOptions,
featureGateEnable: true, featureGateEnable: true,
expectedAvailable: true, expectedAvailable: true,
}, },
{ {
option: PreferClosestNUMANodes, option: PreferClosestNUMANodes,
featureGate: pkgfeatures.TopologyManagerPolicyBetaOptions, featureGate: pkgfeatures.TopologyManagerPolicyAlphaOptions,
featureGateEnable: true, featureGateEnable: false,
expectedAvailable: false, expectedAvailable: true,
}, },
} }
for _, testCase := range testCases { for _, testCase := range testCases {

View File

@ -21,7 +21,7 @@ import (
"time" "time"
cadvisorapi "github.com/google/cadvisor/info/v1" cadvisorapi "github.com/google/cadvisor/info/v1"
"k8s.io/api/core/v1" v1 "k8s.io/api/core/v1"
"k8s.io/klog/v2" "k8s.io/klog/v2"
"k8s.io/kubernetes/pkg/kubelet/cm/topologymanager/bitmask" "k8s.io/kubernetes/pkg/kubelet/cm/topologymanager/bitmask"
"k8s.io/kubernetes/pkg/kubelet/lifecycle" "k8s.io/kubernetes/pkg/kubelet/lifecycle"
@ -133,10 +133,9 @@ var _ Manager = &manager{}
// NewManager creates a new TopologyManager based on provided policy and scope // NewManager creates a new TopologyManager based on provided policy and scope
func NewManager(topology []cadvisorapi.Node, topologyPolicyName string, topologyScopeName string, topologyPolicyOptions map[string]string) (Manager, error) { func NewManager(topology []cadvisorapi.Node, topologyPolicyName string, topologyScopeName string, topologyPolicyOptions map[string]string) (Manager, error) {
klog.InfoS("Creating topology manager with policy per scope", "topologyPolicyName", topologyPolicyName, "topologyScopeName", topologyScopeName)
// When policy is none, the scope is not relevant, so we can short circuit here. // When policy is none, the scope is not relevant, so we can short circuit here.
if topologyPolicyName == PolicyNone { if topologyPolicyName == PolicyNone {
klog.InfoS("Creating topology manager with none policy")
return &manager{scope: NewNoneScope()}, nil return &manager{scope: NewNoneScope()}, nil
} }
@ -145,6 +144,8 @@ func NewManager(topology []cadvisorapi.Node, topologyPolicyName string, topology
return nil, err return nil, err
} }
klog.InfoS("Creating topology manager with policy per scope", "topologyPolicyName", topologyPolicyName, "topologyScopeName", topologyScopeName, "topologyPolicyOptions", opts)
numaInfo, err := NewNUMAInfo(topology, opts) numaInfo, err := NewNUMAInfo(topology, opts)
if err != nil { if err != nil {
return nil, fmt.Errorf("cannot discover NUMA topology: %w", err) return nil, fmt.Errorf("cannot discover NUMA topology: %w", err)