Skip to content

Commit 33bd5fc

Browse files
authored
Merge pull request kubernetes#3532 from DataDog/azure-allocatable-tags
Azure: support allocatable resources overrides via VMSS tags
2 parents 1e0b433 + 5982062 commit 33bd5fc

File tree

4 files changed

+53
-2
lines changed

4 files changed

+53
-2
lines changed

cluster-autoscaler/cloudprovider/azure/README.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,15 @@ To add the taint of `foo=bar:NoSchedule` to a node from a VMSS pool, you would a
4545

4646
You can also use forward slashes in taints by setting them as an underscore in the tag name. For example to add the taint of `k8s.io/foo=bar:NoSchedule` to a node from a VMSS pool, you would add the following tag to the VMSS `k8s.io_cluster-autoscaler_node-template_taint_k8s.io_foo: bar:NoSchedule`
4747

48+
#### Resources
49+
50+
When scaling from an empty VM Scale Set (0 instances), Cluster Autoscaler will evaluate the provided presources (cpu, memory, ephemeral-storage) based on that VM Scale Set's backing instance type.
51+
This can be overridden (for instance, to account for system reserved resources) by specifying capacities with VMSS tags, formated as: `k8s.io_cluster-autoscaler_node-template_resources_<resource name>: <resource value>`. For instance:
52+
```
53+
k8s.io_cluster-autoscaler_node-template_resources_cpu: 3800m
54+
k8s.io_cluster-autoscaler_node-template_resources_memory: 11Gi
55+
```
56+
4857
## Deployment manifests
4958

5059
Cluster autoscaler supports four Kubernetes cluster options on Azure:

cluster-autoscaler/cloudprovider/azure/azure_scale_set.go

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -601,6 +601,11 @@ func (scaleSet *ScaleSet) buildNodeFromTemplate(template compute.VirtualMachineS
601601
node.Status.Capacity[gpu.ResourceNvidiaGPU] = *resource.NewQuantity(vmssType.GPU, resource.DecimalSI)
602602
node.Status.Capacity[apiv1.ResourceMemory] = *resource.NewQuantity(vmssType.MemoryMb*1024*1024, resource.DecimalSI)
603603

604+
resourcesFromTags := extractAllocatableResourcesFromScaleSet(template.Tags)
605+
for resourceName, val := range resourcesFromTags {
606+
node.Status.Capacity[apiv1.ResourceName(resourceName)] = *val
607+
}
608+
604609
// TODO: set real allocatable.
605610
node.Status.Allocatable = node.Status.Capacity
606611

@@ -670,6 +675,25 @@ func extractTaintsFromScaleSet(tags map[string]*string) []apiv1.Taint {
670675
return taints
671676
}
672677

678+
func extractAllocatableResourcesFromScaleSet(tags map[string]*string) map[string]*resource.Quantity {
679+
resources := make(map[string]*resource.Quantity)
680+
681+
for tagName, tagValue := range tags {
682+
resourceName := strings.Split(tagName, nodeResourcesTagName)
683+
if len(resourceName) < 2 || resourceName[1] == "" {
684+
continue
685+
}
686+
687+
quantity, err := resource.ParseQuantity(*tagValue)
688+
if err != nil {
689+
continue
690+
}
691+
resources[resourceName[1]] = &quantity
692+
}
693+
694+
return resources
695+
}
696+
673697
// TemplateNodeInfo returns a node template for this scale set.
674698
func (scaleSet *ScaleSet) TemplateNodeInfo() (*schedulerframework.NodeInfo, error) {
675699
template, rerr := scaleSet.getVMSSInfo()

cluster-autoscaler/cloudprovider/azure/azure_scale_set_test.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import (
2323
"time"
2424

2525
apiv1 "k8s.io/api/core/v1"
26+
"k8s.io/apimachinery/pkg/api/resource"
2627
"k8s.io/autoscaler/cluster-autoscaler/cloudprovider"
2728
"k8s.io/legacy-cloud-providers/azure/clients/vmssclient/mockvmssclient"
2829
"k8s.io/legacy-cloud-providers/azure/clients/vmssvmclient/mockvmssvmclient"
@@ -533,6 +534,22 @@ func TestExtractTaintsFromScaleSet(t *testing.T) {
533534
assert.Equal(t, makeTaintSet(expectedTaints), makeTaintSet(taints))
534535
}
535536

537+
func TestExtractAllocatableResourcesFromScaleSet(t *testing.T) {
538+
tags := map[string]*string{
539+
fmt.Sprintf("%s%s", nodeResourcesTagName, "cpu"): to.StringPtr("100m"),
540+
fmt.Sprintf("%s%s", nodeResourcesTagName, "memory"): to.StringPtr("100M"),
541+
fmt.Sprintf("%s%s", nodeResourcesTagName, "ephemeral-storage"): to.StringPtr("20G"),
542+
}
543+
544+
labels := extractAllocatableResourcesFromScaleSet(tags)
545+
546+
assert.Equal(t, resource.NewMilliQuantity(100, resource.DecimalSI).String(), labels["cpu"].String())
547+
expectedMemory := resource.MustParse("100M")
548+
assert.Equal(t, (&expectedMemory).String(), labels["memory"].String())
549+
expectedEphemeralStorage := resource.MustParse("20G")
550+
assert.Equal(t, (&expectedEphemeralStorage).String(), labels["ephemeral-storage"].String())
551+
}
552+
536553
func makeTaintSet(taints []apiv1.Taint) map[apiv1.Taint]bool {
537554
set := make(map[apiv1.Taint]bool)
538555
for _, taint := range taints {

cluster-autoscaler/cloudprovider/azure/azure_util.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -78,8 +78,9 @@ const (
7878
k8sWindowsVMAgentOrchestratorNameIndex = 2
7979
k8sWindowsVMAgentPoolInfoIndex = 3
8080

81-
nodeLabelTagName = "k8s.io_cluster-autoscaler_node-template_label_"
82-
nodeTaintTagName = "k8s.io_cluster-autoscaler_node-template_taint_"
81+
nodeLabelTagName = "k8s.io_cluster-autoscaler_node-template_label_"
82+
nodeTaintTagName = "k8s.io_cluster-autoscaler_node-template_taint_"
83+
nodeResourcesTagName = "k8s.io_cluster-autoscaler_node-template_resources_"
8384
)
8485

8586
var (

0 commit comments

Comments
 (0)