Skip to content

Commit 7b18e2f

Browse files
authored
Merge pull request #8200 from wenxuan0923/wenx/fix-label-taints-1.31
[AKS VMs Pool] Add the missing labels/taints for VMs pool 1.31
2 parents 31422a8 + a4f5c91 commit 7b18e2f

File tree

3 files changed

+92
-15
lines changed

3 files changed

+92
-15
lines changed

cluster-autoscaler/cloudprovider/azure/azure_template.go

Lines changed: 28 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ const (
8989
// VMPoolNodeTemplate holds properties for node from VMPool
9090
type VMPoolNodeTemplate struct {
9191
AgentPoolName string
92-
Taints []string
92+
Taints []apiv1.Taint
9393
Labels map[string]*string
9494
OSDiskType *armcontainerservice.OSDiskType
9595
}
@@ -155,23 +155,33 @@ func buildNodeTemplateFromVMSS(vmss compute.VirtualMachineScaleSet, inputLabels
155155
}, nil
156156
}
157157

158-
func buildNodeTemplateFromVMPool(vmsPool armcontainerservice.AgentPool, location string, skuName string) (NodeTemplate, error) {
158+
func buildNodeTemplateFromVMPool(vmsPool armcontainerservice.AgentPool, location string, skuName string, labelsFromSpec map[string]string, taintsFromSpec string) (NodeTemplate, error) {
159159
if vmsPool.Properties == nil {
160160
return NodeTemplate{}, fmt.Errorf("vmsPool %s has nil properties", to.String(vmsPool.Name))
161161
}
162-
var labels map[string]*string
163-
if vmsPool.Properties.NodeLabels != nil {
164-
labels = vmsPool.Properties.NodeLabels
162+
// labels from the agentpool
163+
labels := vmsPool.Properties.NodeLabels
164+
// labels from spec
165+
for k, v := range labelsFromSpec {
166+
if labels == nil {
167+
labels = make(map[string]*string)
168+
}
169+
labels[k] = to.StringPtr(v)
165170
}
166171

167-
var taints []string
168-
if vmsPool.Properties.NodeTaints != nil {
169-
for _, taint := range vmsPool.Properties.NodeTaints {
170-
if taint != nil {
171-
taints = append(taints, *taint)
172-
}
172+
// taints from the agentpool
173+
taintsList := []string{}
174+
for _, taint := range vmsPool.Properties.NodeTaints {
175+
if to.String(taint) != "" {
176+
taintsList = append(taintsList, to.String(taint))
173177
}
174178
}
179+
// taints from spec
180+
if taintsFromSpec != "" {
181+
taintsList = append(taintsList, taintsFromSpec)
182+
}
183+
taintsStr := strings.Join(taintsList, ",")
184+
taints := extractTaintsFromSpecString(taintsStr)
175185

176186
var zones []string
177187
if vmsPool.Properties.AvailabilityZones != nil {
@@ -284,8 +294,7 @@ func processVMPoolTemplate(template NodeTemplate, nodeName string, node apiv1.No
284294
}
285295
}
286296
node.Labels = cloudprovider.JoinStringMaps(node.Labels, labels)
287-
taints := buildNodeTaintsForVMPool(template.VMPoolNodeTemplate.Taints)
288-
node.Spec.Taints = taints
297+
node.Spec.Taints = template.VMPoolNodeTemplate.Taints
289298
return node
290299
}
291300

@@ -459,14 +468,19 @@ func extractTaintsFromTags(tags map[string]*string) []apiv1.Taint {
459468
return taints
460469
}
461470

462-
// extractTaintsFromSpecString is for VMSS nodepool taints
471+
// extractTaintsFromSpecString is for nodepool taints
463472
// Example of a valid taints string, is the same argument to kubelet's `--register-with-taints`
464473
// "dedicated=foo:NoSchedule,group=bar:NoExecute,app=fizz:PreferNoSchedule"
465474
func extractTaintsFromSpecString(taintsString string) []apiv1.Taint {
466475
taints := make([]apiv1.Taint, 0)
476+
dedupMap := make(map[string]interface{})
467477
// First split the taints at the separator
468478
splits := strings.Split(taintsString, ",")
469479
for _, split := range splits {
480+
if dedupMap[split] != nil {
481+
continue
482+
}
483+
dedupMap[split] = struct{}{}
470484
valid, taint := constructTaintFromString(split)
471485
if valid {
472486
taints = append(taints, taint)

cluster-autoscaler/cloudprovider/azure/azure_template_test.go

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import (
2121
"strings"
2222
"testing"
2323

24+
"github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/containerservice/armcontainerservice/v5"
2425
"github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2022-08-01/compute"
2526
"github.com/Azure/go-autorest/autorest"
2627
"github.com/Azure/go-autorest/autorest/to"
@@ -137,6 +138,11 @@ func TestExtractTaintsFromSpecString(t *testing.T) {
137138
Value: "fizz",
138139
Effect: apiv1.TaintEffectPreferNoSchedule,
139140
},
141+
{
142+
Key: "dedicated", // duplicate key, should be ignored
143+
Value: "foo",
144+
Effect: apiv1.TaintEffectNoSchedule,
145+
},
140146
}
141147

142148
taints := extractTaintsFromSpecString(strings.Join(taintsString, ","))
@@ -222,6 +228,61 @@ func TestEmptyTopologyFromScaleSet(t *testing.T) {
222228
assert.True(t, ok)
223229
assert.Equal(t, expectedAzureDiskTopology, azureDiskTopology)
224230
}
231+
func TestBuildNodeTemplateFromVMPool(t *testing.T) {
232+
agentPoolName := "testpool"
233+
location := "eastus"
234+
skuName := "Standard_DS2_v2"
235+
labelKey := "foo"
236+
labelVal := "bar"
237+
taintStr := "dedicated=foo:NoSchedule,boo=fizz:PreferNoSchedule,group=bar:NoExecute"
238+
239+
osType := armcontainerservice.OSTypeLinux
240+
osDiskType := armcontainerservice.OSDiskTypeEphemeral
241+
zone1 := "1"
242+
zone2 := "2"
243+
244+
vmpool := armcontainerservice.AgentPool{
245+
Name: to.StringPtr(agentPoolName),
246+
Properties: &armcontainerservice.ManagedClusterAgentPoolProfileProperties{
247+
NodeLabels: map[string]*string{
248+
"existing": to.StringPtr("label"),
249+
"department": to.StringPtr("engineering"),
250+
},
251+
NodeTaints: []*string{to.StringPtr("group=bar:NoExecute")},
252+
OSType: &osType,
253+
OSDiskType: &osDiskType,
254+
AvailabilityZones: []*string{&zone1, &zone2},
255+
},
256+
}
257+
258+
labelsFromSpec := map[string]string{labelKey: labelVal}
259+
taintsFromSpec := taintStr
260+
261+
template, err := buildNodeTemplateFromVMPool(vmpool, location, skuName, labelsFromSpec, taintsFromSpec)
262+
assert.NoError(t, err)
263+
assert.Equal(t, skuName, template.SkuName)
264+
assert.Equal(t, location, template.Location)
265+
assert.ElementsMatch(t, []string{zone1, zone2}, template.Zones)
266+
assert.Equal(t, "linux", template.InstanceOS)
267+
assert.NotNil(t, template.VMPoolNodeTemplate)
268+
assert.Equal(t, agentPoolName, template.VMPoolNodeTemplate.AgentPoolName)
269+
assert.Equal(t, &osDiskType, template.VMPoolNodeTemplate.OSDiskType)
270+
// Labels: should include both from NodeLabels and labelsFromSpec
271+
assert.Contains(t, template.VMPoolNodeTemplate.Labels, "existing")
272+
assert.Equal(t, "label", *template.VMPoolNodeTemplate.Labels["existing"])
273+
assert.Contains(t, template.VMPoolNodeTemplate.Labels, "department")
274+
assert.Equal(t, "engineering", *template.VMPoolNodeTemplate.Labels["department"])
275+
assert.Contains(t, template.VMPoolNodeTemplate.Labels, labelKey)
276+
assert.Equal(t, labelVal, *template.VMPoolNodeTemplate.Labels[labelKey])
277+
// Taints: should include both from NodeTaints and taintsFromSpec
278+
taintSet := makeTaintSet(template.VMPoolNodeTemplate.Taints)
279+
expectedTaints := []apiv1.Taint{
280+
{Key: "group", Value: "bar", Effect: apiv1.TaintEffectNoExecute},
281+
{Key: "dedicated", Value: "foo", Effect: apiv1.TaintEffectNoSchedule},
282+
{Key: "boo", Value: "fizz", Effect: apiv1.TaintEffectPreferNoSchedule},
283+
}
284+
assert.Equal(t, makeTaintSet(expectedTaints), taintSet)
285+
}
225286

226287
func makeTaintSet(taints []apiv1.Taint) map[apiv1.Taint]bool {
227288
set := make(map[apiv1.Taint]bool)

cluster-autoscaler/cloudprovider/azure/azure_vms_pool.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -460,7 +460,9 @@ func (vmPool *VMPool) TemplateNodeInfo() (*schedulerframework.NodeInfo, error) {
460460
return nil, err
461461
}
462462

463-
template, err := buildNodeTemplateFromVMPool(ap, vmPool.manager.config.Location, vmPool.sku)
463+
inputLabels := map[string]string{}
464+
inputTaints := ""
465+
template, err := buildNodeTemplateFromVMPool(ap, vmPool.manager.config.Location, vmPool.sku, inputLabels, inputTaints)
464466
if err != nil {
465467
return nil, err
466468
}

0 commit comments

Comments
 (0)