Skip to content

Commit 791323d

Browse files
committed
WIP: nrt: make it possible to consume MaxAllowdNUMANodes
TODO Signed-off-by: Francesco Romani <[email protected]>
1 parent c48a8fa commit 791323d

File tree

5 files changed

+43
-29
lines changed

5 files changed

+43
-29
lines changed

pkg/noderesourcetopology/filter.go

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -35,10 +35,6 @@ import (
3535
"sigs.k8s.io/scheduler-plugins/pkg/util"
3636
)
3737

38-
// The maximum number of NUMA nodes that Topology Manager allows is 8
39-
// https://kubernetes.io/docs/tasks/administer-cluster/topology-manager/#known-limitations
40-
const highestNUMAID = 8
41-
4238
type PolicyHandler func(pod *v1.Pod, zoneMap topologyv1alpha2.ZoneList) *framework.Status
4339

4440
func singleNUMAContainerLevelHandler(lh logr.Logger, pod *v1.Pod, info *filterInfo) *framework.Status {
@@ -85,7 +81,7 @@ func singleNUMAContainerLevelHandler(lh logr.Logger, pod *v1.Pod, info *filterIn
8581
// resourcesAvailableInAnyNUMANodes checks for sufficient resource and return the NUMAID that would be selected by Kubelet.
8682
// this function requires NUMANodeList with properly populated NUMANode, NUMAID should be in range 0-63
8783
func resourcesAvailableInAnyNUMANodes(lh logr.Logger, info *filterInfo, resources v1.ResourceList) (int, bool, string) {
88-
numaID := highestNUMAID
84+
numaID := info.topologyManager.MaxNUMANodes // highest NUMA ID
8985
bitmask := bm.NewEmptyBitMask()
9086
// set all bits, each bit is a NUMA node, if resources couldn't be aligned
9187
// on the NUMA node, bit should be unset

pkg/noderesourcetopology/least_numa.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ func leastNUMAContainerScopeScore(lh logr.Logger, pod *v1.Pod, info *scoreInfo)
6767
return framework.MaxNodeScore, nil
6868
}
6969

70-
return normalizeScore(maxNUMANodesCount, allContainersMinAvgDistance), nil
70+
return normalizeScore(maxNUMANodesCount, allContainersMinAvgDistance, info.topologyManager.MaxNUMANodes), nil
7171
}
7272

7373
func leastNUMAPodScopeScore(lh logr.Logger, pod *v1.Pod, info *scoreInfo) (int64, *framework.Status) {
@@ -85,11 +85,11 @@ func leastNUMAPodScopeScore(lh logr.Logger, pod *v1.Pod, info *scoreInfo) (int64
8585
return framework.MinNodeScore, nil
8686
}
8787

88-
return normalizeScore(numaNodes.Count(), isMinAvgDistance), nil
88+
return normalizeScore(numaNodes.Count(), isMinAvgDistance, info.topologyManager.MaxNUMANodes), nil
8989
}
9090

91-
func normalizeScore(numaNodesCount int, isMinAvgDistance bool) int64 {
92-
numaNodeScore := framework.MaxNodeScore / highestNUMAID
91+
func normalizeScore(numaNodesCount int, isMinAvgDistance bool, highestNUMAID int) int64 {
92+
numaNodeScore := framework.MaxNodeScore / int64(highestNUMAID)
9393
score := framework.MaxNodeScore - int64(numaNodesCount)*numaNodeScore
9494
if isMinAvgDistance {
9595
// if distance between NUMA domains is optimal add half of numaNodeScore to make this node more favorable

pkg/noderesourcetopology/least_numa_test.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import (
2525
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
2626
"k8s.io/klog/v2"
2727
"k8s.io/kubernetes/pkg/kubelet/cm/topologymanager/bitmask"
28+
"sigs.k8s.io/scheduler-plugins/pkg/noderesourcetopology/nodeconfig"
2829
)
2930

3031
const (
@@ -746,7 +747,7 @@ func TestNormalizeScore(t *testing.T) {
746747

747748
for _, tc := range tcases {
748749
t.Run(tc.description, func(t *testing.T) {
749-
normalizedScore := normalizeScore(tc.score, tc.optimalDistance)
750+
normalizedScore := normalizeScore(tc.score, tc.optimalDistance, nodeconfig.DefaultMaxNUMANodes)
750751
if normalizedScore != tc.expectedScore {
751752
t.Errorf("Expected normalizedScore to be %d not %d", tc.expectedScore, normalizedScore)
752753
}

pkg/noderesourcetopology/nodeconfig/topologymanager.go

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ package nodeconfig
1818

1919
import (
2020
"fmt"
21+
"strconv"
2122

2223
kubeletconfig "k8s.io/kubernetes/pkg/kubelet/apis/config"
2324

@@ -26,11 +27,14 @@ import (
2627
)
2728

2829
const (
29-
AttributeScope = "topologyManagerScope"
30-
AttributePolicy = "topologyManagerPolicy"
30+
DefaultMaxNUMANodes = 8 // legacy setting and default value for TopologyManager. NOTE: kube doesn't expose this constant
3131
)
3232

33-
// TODO: handle topologyManagerPolicyOptions added in k8s 1.26
33+
const (
34+
AttributeScope = "topologyManagerScope"
35+
AttributePolicy = "topologyManagerPolicy"
36+
AttributeMaxNUMANodes = "topologyManagerMaxNUMANodes"
37+
)
3438

3539
func IsValidScope(scope string) bool {
3640
if scope == kubeletconfig.ContainerTopologyManagerScope || scope == kubeletconfig.PodTopologyManagerScope {
@@ -48,14 +52,16 @@ func IsValidPolicy(policy string) bool {
4852
}
4953

5054
type TopologyManager struct {
51-
Scope string
52-
Policy string
55+
Scope string
56+
Policy string
57+
MaxNUMANodes int
5358
}
5459

5560
func TopologyManagerDefaults() TopologyManager {
5661
return TopologyManager{
57-
Scope: kubeletconfig.ContainerTopologyManagerScope,
58-
Policy: kubeletconfig.NoneTopologyManagerPolicy,
62+
Scope: kubeletconfig.ContainerTopologyManagerScope,
63+
Policy: kubeletconfig.NoneTopologyManagerPolicy,
64+
MaxNUMANodes: DefaultMaxNUMANodes,
5965
}
6066
}
6167

@@ -70,7 +76,7 @@ func TopologyManagerFromNodeResourceTopology(lh logr.Logger, nodeTopology *topol
7076
}
7177

7278
func (conf TopologyManager) String() string {
73-
return fmt.Sprintf("policy=%q scope=%q", conf.Policy, conf.Scope)
79+
return fmt.Sprintf("policy=%q scope=%q maxNUMANodes=%d", conf.Policy, conf.Scope, conf.MaxNUMANodes)
7480
}
7581

7682
func (conf TopologyManager) Equal(other TopologyManager) bool {
@@ -93,7 +99,13 @@ func (conf *TopologyManager) updateFromAttributes(attrs topologyv1alpha2.Attribu
9399
conf.Policy = attr.Value
94100
continue
95101
}
96-
// TODO: handle topologyManagerPolicyOptions added in k8s 1.26
102+
if attr.Name == AttributeMaxNUMANodes {
103+
// the value is used in a division
104+
if val, err := strconv.Atoi(attr.Value); err == nil && val > 1 {
105+
conf.MaxNUMANodes = val
106+
continue
107+
}
108+
}
97109
}
98110
}
99111

pkg/noderesourcetopology/nodeconfig/topologymanager_test.go

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -427,8 +427,9 @@ func TestConfigFromNRT(t *testing.T) {
427427
},
428428
},
429429
expected: TopologyManager{
430-
Policy: kubeletconfig.BestEffortTopologyManagerPolicy,
431-
Scope: kubeletconfig.PodTopologyManagerScope,
430+
Policy: kubeletconfig.BestEffortTopologyManagerPolicy,
431+
Scope: kubeletconfig.PodTopologyManagerScope,
432+
MaxNUMANodes: DefaultMaxNUMANodes,
432433
},
433434
},
434435
{
@@ -440,8 +441,9 @@ func TestConfigFromNRT(t *testing.T) {
440441
},
441442
},
442443
expected: TopologyManager{
443-
Policy: kubeletconfig.RestrictedTopologyManagerPolicy,
444-
Scope: kubeletconfig.ContainerTopologyManagerScope,
444+
Policy: kubeletconfig.RestrictedTopologyManagerPolicy,
445+
Scope: kubeletconfig.ContainerTopologyManagerScope,
446+
MaxNUMANodes: DefaultMaxNUMANodes,
445447
},
446448
},
447449
{
@@ -455,8 +457,9 @@ func TestConfigFromNRT(t *testing.T) {
455457
},
456458
},
457459
expected: TopologyManager{
458-
Policy: kubeletconfig.RestrictedTopologyManagerPolicy,
459-
Scope: kubeletconfig.ContainerTopologyManagerScope,
460+
Policy: kubeletconfig.RestrictedTopologyManagerPolicy,
461+
Scope: kubeletconfig.ContainerTopologyManagerScope,
462+
MaxNUMANodes: DefaultMaxNUMANodes,
460463
},
461464
},
462465
{
@@ -473,8 +476,9 @@ func TestConfigFromNRT(t *testing.T) {
473476
},
474477
},
475478
expected: TopologyManager{
476-
Policy: kubeletconfig.BestEffortTopologyManagerPolicy,
477-
Scope: kubeletconfig.ContainerTopologyManagerScope,
479+
Policy: kubeletconfig.BestEffortTopologyManagerPolicy,
480+
Scope: kubeletconfig.ContainerTopologyManagerScope,
481+
MaxNUMANodes: DefaultMaxNUMANodes,
478482
},
479483
},
480484
{
@@ -495,8 +499,9 @@ func TestConfigFromNRT(t *testing.T) {
495499
},
496500
},
497501
expected: TopologyManager{
498-
Policy: kubeletconfig.RestrictedTopologyManagerPolicy,
499-
Scope: kubeletconfig.ContainerTopologyManagerScope,
502+
Policy: kubeletconfig.RestrictedTopologyManagerPolicy,
503+
Scope: kubeletconfig.ContainerTopologyManagerScope,
504+
MaxNUMANodes: DefaultMaxNUMANodes,
500505
},
501506
},
502507
}

0 commit comments

Comments
 (0)