Skip to content

Commit 4bf83f1

Browse files
authored
Merge pull request #6447 from Jont828/edge-zone
Azure: add support for edge zones
2 parents 109998d + e8ca5fd commit 4bf83f1

File tree

8 files changed

+217
-25
lines changed

8 files changed

+217
-25
lines changed

charts/cluster-autoscaler/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -382,6 +382,7 @@ vpa:
382382
| awsSecretAccessKey | string | `""` | AWS access secret key ([if AWS user keys used](https://github.com/kubernetes/autoscaler/blob/master/cluster-autoscaler/cloudprovider/aws/README.md#using-aws-credentials)) |
383383
| azureClientID | string | `""` | Service Principal ClientID with contributor permission to Cluster and Node ResourceGroup. Required if `cloudProvider=azure` |
384384
| azureClientSecret | string | `""` | Service Principal ClientSecret with contributor permission to Cluster and Node ResourceGroup. Required if `cloudProvider=azure` |
385+
| azureEnableForceDelete | bool | `false` | Whether to force delete VMs or VMSS instances when scaling down. |
385386
| azureResourceGroup | string | `""` | Azure resource group that the cluster is located. Required if `cloudProvider=azure` |
386387
| azureSubscriptionID | string | `""` | Azure subscription where the resources are located. Required if `cloudProvider=azure` |
387388
| azureTenantID | string | `""` | Azure tenant where the resources are located. Required if `cloudProvider=azure` |

charts/cluster-autoscaler/templates/deployment.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,8 @@ spec:
166166
secretKeyRef:
167167
key: VMType
168168
name: {{ default (include "cluster-autoscaler.fullname" .) .Values.secretKeyRefNameOverride }}
169+
- name: AZURE_ENABLE_FORCE_DELETE
170+
value: "{{ .Values.azureEnableForceDelete }}"
169171
{{- if .Values.azureUseWorkloadIdentityExtension }}
170172
- name: ARM_USE_WORKLOAD_IDENTITY_EXTENSION
171173
value: "true"

charts/cluster-autoscaler/values.yaml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,9 @@ azureUseWorkloadIdentityExtension: false
9696
# azureVMType -- Azure VM type.
9797
azureVMType: "vmss"
9898

99+
# azureEnableForceDelete -- Whether to force delete VMs or VMSS instances when scaling down.
100+
azureEnableForceDelete: false
101+
99102
# cloudConfigPath -- Configuration file for cloud provider.
100103
cloudConfigPath: ""
101104

cluster-autoscaler/cloudprovider/azure/azure_cloud_provider_test.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ func newTestAzureManager(t *testing.T) *AzureManager {
5353
VMType: vmTypeVMSS,
5454
MaxDeploymentsCount: 2,
5555
Deployment: "deployment",
56+
EnableForceDelete: true,
5657
},
5758
azClient: &azClient{
5859
virtualMachineScaleSetsClient: mockVMSSClient,

cluster-autoscaler/cloudprovider/azure/azure_config.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,9 @@ type Config struct {
130130
CloudProviderBackoffDuration int `json:"cloudProviderBackoffDuration,omitempty" yaml:"cloudProviderBackoffDuration,omitempty"`
131131
CloudProviderBackoffJitter float64 `json:"cloudProviderBackoffJitter,omitempty" yaml:"cloudProviderBackoffJitter,omitempty"`
132132

133+
// EnableForceDelete defines whether to enable force deletion on the APIs
134+
EnableForceDelete bool `json:"enableForceDelete,omitempty" yaml:"enableForceDelete,omitempty"`
135+
133136
// EnableDynamicInstanceList defines whether to enable dynamic instance workflow for instance information check
134137
EnableDynamicInstanceList bool `json:"enableDynamicInstanceList,omitempty" yaml:"enableDynamicInstanceList,omitempty"`
135138

@@ -303,6 +306,13 @@ func BuildAzureConfig(configReader io.Reader) (*Config, error) {
303306
}
304307
}
305308

309+
if enableForceDelete := os.Getenv("AZURE_ENABLE_FORCE_DELETE"); enableForceDelete != "" {
310+
cfg.EnableForceDelete, err = strconv.ParseBool(enableForceDelete)
311+
if err != nil {
312+
return nil, fmt.Errorf("failed to parse AZURE_ENABLE_FORCE_DELETE: %q, %v", enableForceDelete, err)
313+
}
314+
}
315+
306316
err = initializeCloudProviderRateLimitConfig(&cfg.CloudProviderRateLimitConfig)
307317
if err != nil {
308318
return nil, err

cluster-autoscaler/cloudprovider/azure/azure_manager_test.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -679,6 +679,7 @@ func TestGetFilteredAutoscalingGroupsVmss(t *testing.T) {
679679
minSize: minVal,
680680
maxSize: maxVal,
681681
manager: manager,
682+
enableForceDelete: manager.config.EnableForceDelete,
682683
curSize: 3,
683684
sizeRefreshPeriod: manager.azureCache.refreshInterval,
684685
instancesRefreshPeriod: defaultVmssInstancesRefreshPeriod,

cluster-autoscaler/cloudprovider/azure/azure_scale_set.go

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,8 @@ type ScaleSet struct {
5858
minSize int
5959
maxSize int
6060

61+
enableForceDelete bool
62+
6163
sizeMutex sync.Mutex
6264
curSize int64
6365

@@ -87,6 +89,7 @@ func NewScaleSet(spec *dynamic.NodeGroupSpec, az *AzureManager, curSize int64) (
8789
sizeRefreshPeriod: az.azureCache.refreshInterval,
8890
enableDynamicInstanceList: az.config.EnableDynamicInstanceList,
8991
instancesRefreshJitter: az.config.VmssVmsCacheJitter,
92+
enableForceDelete: az.config.EnableForceDelete,
9093
}
9194

9295
if az.config.VmssVmsCacheTTL != 0 {
@@ -251,6 +254,16 @@ func (scaleSet *ScaleSet) SetScaleSetSize(size int64) error {
251254
Sku: vmssInfo.Sku,
252255
Location: vmssInfo.Location,
253256
}
257+
258+
if vmssInfo.ExtendedLocation != nil {
259+
op.ExtendedLocation = &compute.ExtendedLocation{
260+
Name: vmssInfo.ExtendedLocation.Name,
261+
Type: vmssInfo.ExtendedLocation.Type,
262+
}
263+
264+
klog.V(3).Infof("Passing ExtendedLocation information if it is not nil, with Edge Zone name:(%s)", *op.ExtendedLocation.Name)
265+
}
266+
254267
ctx, cancel := getContextWithTimeout(vmssContextTimeout)
255268
defer cancel()
256269
klog.V(3).Infof("Waiting for virtualMachineScaleSetsClient.CreateOrUpdateAsync(%s)", scaleSet.Name)
@@ -437,8 +450,15 @@ func (scaleSet *ScaleSet) DeleteInstances(instances []*azureRef, hasUnregistered
437450
resourceGroup := scaleSet.manager.config.ResourceGroup
438451

439452
scaleSet.instanceMutex.Lock()
440-
klog.V(3).Infof("Calling virtualMachineScaleSetsClient.DeleteInstancesAsync(%v)", requiredIds.InstanceIds)
441-
future, rerr := scaleSet.manager.azClient.virtualMachineScaleSetsClient.DeleteInstancesAsync(ctx, resourceGroup, commonAsg.Id(), *requiredIds, false)
453+
klog.V(3).Infof("Calling virtualMachineScaleSetsClient.DeleteInstancesAsync(%v), force delete set to %v", requiredIds.InstanceIds, scaleSet.enableForceDelete)
454+
future, rerr := scaleSet.manager.azClient.virtualMachineScaleSetsClient.DeleteInstancesAsync(ctx, resourceGroup, commonAsg.Id(), *requiredIds, scaleSet.enableForceDelete)
455+
456+
if scaleSet.enableForceDelete && isOperationNotAllowed(rerr) {
457+
klog.Infof("falling back to normal delete for instances %v for %s", requiredIds.InstanceIds, scaleSet.Name)
458+
future, rerr = scaleSet.manager.azClient.virtualMachineScaleSetsClient.DeleteInstancesAsync(ctx, resourceGroup,
459+
commonAsg.Id(), *requiredIds, false)
460+
}
461+
442462
scaleSet.instanceMutex.Unlock()
443463
if rerr != nil {
444464
klog.Errorf("virtualMachineScaleSetsClient.DeleteInstancesAsync for instances %v failed: %v", requiredIds.InstanceIds, rerr)
@@ -746,3 +766,7 @@ func (scaleSet *ScaleSet) getOrchestrationMode() (compute.OrchestrationMode, err
746766
}
747767
return vmss.OrchestrationMode, nil
748768
}
769+
770+
func isOperationNotAllowed(rerr *retry.Error) bool {
771+
return rerr != nil && rerr.ServiceErrorCode() == retry.OperationNotAllowed
772+
}

0 commit comments

Comments
 (0)