Excluding Control Plane Nodes from Topology Hints calculations

This commit is contained in:
Rob Scott 2021-09-02 20:47:52 -07:00
parent 82da9bdaab
commit d7a640d831
No known key found for this signature in database
GPG Key ID: D91A796D0CFF0C5D
2 changed files with 58 additions and 6 deletions

View File

@ -170,9 +170,15 @@ func (t *TopologyCache) SetNodes(nodes []*v1.Node) {
totalCPU := resource.Quantity{}
for _, node := range nodes {
if !NodeReady(node.Status) {
if hasExcludedLabels(node.Labels) {
klog.V(2).Infof("Ignoring node %s because it has an excluded label", node.Name)
continue
}
if !NodeReady(node.Status) {
klog.V(2).Infof("Ignoring node %s because it is not ready: %v", node.Name, node.Status.Conditions)
continue
}
nodeCPU := node.Status.Allocatable.Cpu()
zone, ok := node.Labels[v1.LabelTopologyZone]
@ -254,3 +260,18 @@ func (t *TopologyCache) getAllocations(numEndpoints int) map[string]Allocation {
return allocations
}
// Nodes with any of these labels set to any value will be excluded from
// topology capacity calculations.
func hasExcludedLabels(labels map[string]string) bool {
if len(labels) == 0 {
return false
}
if _, ok := labels["node-role.kubernetes.io/control-plane"]; ok {
return true
}
if _, ok := labels["node-role.kubernetes.io/master"]; ok {
return true
}
return false
}

View File

@ -20,7 +20,7 @@ import (
"reflect"
"testing"
"k8s.io/api/core/v1"
v1 "k8s.io/api/core/v1"
discovery "k8s.io/api/discovery/v1"
"k8s.io/apimachinery/pkg/api/resource"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@ -290,9 +290,10 @@ func TestAddHints(t *testing.T) {
func TestSetNodes(t *testing.T) {
type nodeInfo struct {
zone string
cpu resource.Quantity
ready v1.ConditionStatus
zone string
cpu resource.Quantity
ready v1.ConditionStatus
labels map[string]string
}
testCases := []struct {
@ -348,6 +349,16 @@ func TestSetNodes(t *testing.T) {
expectSufficientNodeInfo: false,
expectedCPUByZone: nil,
expectedRatios: nil,
}, {
name: "2 zones, control plane node in 1, ready node in 1",
nodes: []nodeInfo{
{zone: "zone-a", cpu: resource.MustParse("1000m"), ready: v1.ConditionTrue},
{zone: "zone-b", cpu: resource.MustParse("1000m"), ready: v1.ConditionTrue,
labels: map[string]string{"node-role.kubernetes.io/control-plane": ""}},
},
expectSufficientNodeInfo: false,
expectedCPUByZone: nil,
expectedRatios: nil,
}, {
name: "2 zones, unready node in 1, ready node in 2",
nodes: []nodeInfo{
@ -364,6 +375,23 @@ func TestSetNodes(t *testing.T) {
"zone-a": 0.5,
"zone-b": 0.5,
},
}, {
name: "2 zones, control plane node in 1, ready node in 2",
nodes: []nodeInfo{
{zone: "zone-a", cpu: resource.MustParse("1000m"), ready: v1.ConditionTrue},
{zone: "zone-b", cpu: resource.MustParse("1000m"), ready: v1.ConditionTrue},
{zone: "zone-b", cpu: resource.MustParse("1000m"), ready: v1.ConditionTrue,
labels: map[string]string{"node-role.kubernetes.io/control-plane": ""}},
},
expectSufficientNodeInfo: true,
expectedCPUByZone: map[string]*resource.Quantity{
"zone-a": resource.NewQuantity(1, resource.BinarySI),
"zone-b": resource.NewQuantity(1, resource.BinarySI),
},
expectedRatios: map[string]float64{
"zone-a": 0.5,
"zone-b": 0.5,
},
}, {
name: "3 zones, 4 nodes in 1, 2 nodes in 1, 1 node in 1",
nodes: []nodeInfo{
@ -393,7 +421,10 @@ func TestSetNodes(t *testing.T) {
cache := NewTopologyCache()
nodes := make([]*v1.Node, 0, len(tc.nodes))
for _, node := range tc.nodes {
labels := map[string]string{}
labels := node.labels
if labels == nil {
labels = map[string]string{}
}
if node.zone != "" {
labels[v1.LabelTopologyZone] = node.zone
}