Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cherry-pick #3532 onto 1.19: Azure: support allocatable resources overrides via VMSS tags #3627

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions cluster-autoscaler/cloudprovider/azure/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,15 @@ To add the taint of `foo=bar:NoSchedule` to a node from a VMSS pool, you would a

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`

#### Resources

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.
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:
```
k8s.io_cluster-autoscaler_node-template_resources_cpu: 3800m
k8s.io_cluster-autoscaler_node-template_resources_memory: 11Gi
```

## Deployment manifests

Cluster autoscaler supports four Kubernetes cluster options on Azure:
Expand Down
17 changes: 17 additions & 0 deletions cluster-autoscaler/cloudprovider/azure/azure_scale_set_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import (
"time"

apiv1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/resource"
"k8s.io/autoscaler/cluster-autoscaler/cloudprovider"
"k8s.io/legacy-cloud-providers/azure/clients/vmssclient/mockvmssclient"
"k8s.io/legacy-cloud-providers/azure/clients/vmssvmclient/mockvmssvmclient"
Expand Down Expand Up @@ -470,3 +471,19 @@ func TestTemplateNodeInfo(t *testing.T) {
assert.NotNil(t, nodeInfo)
assert.NotEmpty(t, nodeInfo.Pods)
}

func TestExtractAllocatableResourcesFromScaleSet(t *testing.T) {
tags := map[string]*string{
fmt.Sprintf("%s%s", nodeResourcesTagName, "cpu"): to.StringPtr("100m"),
fmt.Sprintf("%s%s", nodeResourcesTagName, "memory"): to.StringPtr("100M"),
fmt.Sprintf("%s%s", nodeResourcesTagName, "ephemeral-storage"): to.StringPtr("20G"),
}

labels := extractAllocatableResourcesFromScaleSet(tags)

assert.Equal(t, resource.NewMilliQuantity(100, resource.DecimalSI).String(), labels["cpu"].String())
expectedMemory := resource.MustParse("100M")
assert.Equal(t, (&expectedMemory).String(), labels["memory"].String())
expectedEphemeralStorage := resource.MustParse("20G")
assert.Equal(t, (&expectedEphemeralStorage).String(), labels["ephemeral-storage"].String())
}
24 changes: 24 additions & 0 deletions cluster-autoscaler/cloudprovider/azure/azure_template.go
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,11 @@ func buildNodeFromTemplate(scaleSetName string, template compute.VirtualMachineS
node.Status.Capacity[gpu.ResourceNvidiaGPU] = *resource.NewQuantity(vmssType.GPU, resource.DecimalSI)
node.Status.Capacity[apiv1.ResourceMemory] = *resource.NewQuantity(vmssType.MemoryMb*1024*1024, resource.DecimalSI)

resourcesFromTags := extractAllocatableResourcesFromScaleSet(template.Tags)
for resourceName, val := range resourcesFromTags {
node.Status.Capacity[apiv1.ResourceName(resourceName)] = *val
}

// TODO: set real allocatable.
node.Status.Allocatable = node.Status.Capacity

Expand Down Expand Up @@ -140,6 +145,25 @@ func buildNodeFromTemplate(scaleSetName string, template compute.VirtualMachineS
return &node, nil
}

func extractAllocatableResourcesFromScaleSet(tags map[string]*string) map[string]*resource.Quantity {
resources := make(map[string]*resource.Quantity)

for tagName, tagValue := range tags {
resourceName := strings.Split(tagName, nodeResourcesTagName)
if len(resourceName) < 2 || resourceName[1] == "" {
continue
}

quantity, err := resource.ParseQuantity(*tagValue)
if err != nil {
continue
}
resources[resourceName[1]] = &quantity
}

return resources
}

func extractLabelsFromScaleSet(tags map[string]*string) map[string]string {
result := make(map[string]string)

Expand Down
5 changes: 3 additions & 2 deletions cluster-autoscaler/cloudprovider/azure/azure_util.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,8 +78,9 @@ const (
k8sWindowsVMAgentOrchestratorNameIndex = 2
k8sWindowsVMAgentPoolInfoIndex = 3

nodeLabelTagName = "k8s.io_cluster-autoscaler_node-template_label_"
nodeTaintTagName = "k8s.io_cluster-autoscaler_node-template_taint_"
nodeLabelTagName = "k8s.io_cluster-autoscaler_node-template_label_"
nodeTaintTagName = "k8s.io_cluster-autoscaler_node-template_taint_"
nodeResourcesTagName = "k8s.io_cluster-autoscaler_node-template_resources_"
)

var (
Expand Down