Skip to content

Commit cb14a97

Browse files
[AKS] az aks nodepool add/update/upgrade: Add --max-unavailable to specify he maximum number or percentage of nodes that can be simultaneously unavailable during upgrade (#31510)
1 parent d728d86 commit cb14a97

File tree

8 files changed

+1974
-4
lines changed

8 files changed

+1974
-4
lines changed

src/azure-cli/azure/cli/command_modules/acs/_help.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1629,6 +1629,9 @@
16291629
- name: --max-surge
16301630
type: string
16311631
short-summary: Extra nodes used to speed upgrade. When specified, it represents the number or percent used, eg. 5 or 33%
1632+
- name: --max-unavailable
1633+
type: string
1634+
short-summary: The maximum number or percentage of nodes that can be simultaneously unavailable during upgrade. When specified, it represents the number or percent used, eg. 1 or 5%
16321635
- name: --drain-timeout
16331636
type: int
16341637
short-summary: When nodes are drain how many minutes to wait for all pods to be evicted
@@ -1790,6 +1793,9 @@
17901793
- name: --max-surge
17911794
type: string
17921795
short-summary: Extra nodes used to speed upgrade. When specified, it represents the number or percent used, eg. 5 or 33%
1796+
- name: --max-unavailable
1797+
type: string
1798+
short-summary: The maximum number or percentage of nodes that can be simultaneously unavailable during upgrade. When specified, it represents the number or percent used, eg. 1 or 5%
17931799
- name: --drain-timeout
17941800
type: int
17951801
short-summary: When nodes are drain how many minutes to wait for all pods to be evicted
@@ -1865,6 +1871,9 @@
18651871
- name: --max-surge
18661872
type: string
18671873
short-summary: Extra nodes used to speed upgrade. When specified, it represents the number or percent used, eg. 5 or 33% (mutually exclusive with "--node-image-only". See "az aks nodepool update --max-surge" to update max surge before upgrading with "--node-image-only")
1874+
- name: --max-unavailable
1875+
type: string
1876+
short-summary: The maximum number or percentage of nodes that can be simultaneously unavailable during upgrade. When specified, it represents the number or percent used, eg. 1 or 5%
18681877
- name: --drain-timeout
18691878
type: int
18701879
short-summary: When nodes are drain how long to wait for all pods to be evicted

src/azure-cli/azure/cli/command_modules/acs/_params.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@
9292
validate_linux_host_name, validate_load_balancer_idle_timeout,
9393
validate_load_balancer_outbound_ip_prefixes,
9494
validate_load_balancer_outbound_ips, validate_load_balancer_outbound_ports,
95-
validate_load_balancer_sku, validate_max_surge,
95+
validate_load_balancer_sku, validate_max_surge, validate_max_unavailable,
9696
validate_nat_gateway_idle_timeout,
9797
validate_nat_gateway_managed_outbound_ip_count, validate_network_policy,
9898
validate_nodepool_id, validate_nodepool_labels, validate_nodepool_name,
@@ -831,6 +831,7 @@ def load_arguments(self, _):
831831
c.argument('node_osdisk_type', arg_type=get_enum_type(node_os_disk_types))
832832
c.argument('node_osdisk_size', type=int)
833833
c.argument('max_surge', validator=validate_max_surge)
834+
c.argument("max_unavailable", validator=validate_max_unavailable)
834835
c.argument('drain_timeout', type=int)
835836
c.argument('node_soak_duration', type=int)
836837
c.argument("undrainable_node_behavior", default='Schedule')
@@ -872,6 +873,7 @@ def load_arguments(self, _):
872873
c.argument('tags', tags_type)
873874
c.argument('node_taints', validator=validate_nodepool_taints)
874875
c.argument('max_surge', validator=validate_max_surge)
876+
c.argument("max_unavailable", validator=validate_max_unavailable)
875877
c.argument('drain_timeout', type=int)
876878
c.argument('node_soak_duration', type=int)
877879
c.argument("undrainable_node_behavior")
@@ -891,6 +893,7 @@ def load_arguments(self, _):
891893

892894
with self.argument_context('aks nodepool upgrade') as c:
893895
c.argument('max_surge', validator=validate_max_surge)
896+
c.argument("max_unavailable", validator=validate_max_unavailable)
894897
c.argument('drain_timeout', type=int)
895898
c.argument('node_soak_duration', type=int)
896899
c.argument("undrainable_node_behavior")

src/azure-cli/azure/cli/command_modules/acs/_validators.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -476,6 +476,21 @@ def validate_max_surge(namespace):
476476
raise CLIError("--max-surge should be an int or percentage")
477477

478478

479+
def validate_max_unavailable(namespace):
480+
"""validates parameters max unavailable are positive integers or percents."""
481+
if namespace.max_unavailable is None:
482+
return
483+
int_or_percent = namespace.max_unavailable
484+
if int_or_percent.endswith('%'):
485+
int_or_percent = int_or_percent.rstrip('%')
486+
487+
try:
488+
if int(int_or_percent) < 0:
489+
raise InvalidArgumentValueError("--max-unavailable must be positive")
490+
except ValueError:
491+
raise InvalidArgumentValueError("--max-unavailable should be an int or percentage")
492+
493+
479494
def validate_assign_identity(namespace):
480495
if namespace.assign_identity is not None:
481496
if namespace.assign_identity == '':

src/azure-cli/azure/cli/command_modules/acs/agentpool_decorator.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1103,6 +1103,25 @@ def get_max_surge(self):
11031103
# this parameter does not need validation
11041104
return max_surge
11051105

1106+
def get_max_unavailable(self):
1107+
"""Obtain the value of max_unavailable.
1108+
:return: string
1109+
"""
1110+
# read the original value passed by the command
1111+
max_unavailable = self.raw_param.get("max_unavailable")
1112+
# In create mode, try to read the property value corresponding to the parameter from the `agentpool` object
1113+
if self.decorator_mode == DecoratorMode.CREATE:
1114+
if (
1115+
self.agentpool and
1116+
self.agentpool.upgrade_settings and
1117+
self.agentpool.upgrade_settings.max_unavailable is not None
1118+
):
1119+
max_unavailable = self.agentpool.upgrade_settings.max_unavailable
1120+
1121+
# this parameter does not need dynamic completion
1122+
# this parameter does not need validation
1123+
return max_unavailable
1124+
11061125
def get_drain_timeout(self):
11071126
"""Obtain the value of drain_timeout.
11081127
@@ -1833,6 +1852,10 @@ def set_up_upgrade_settings(self, agentpool: AgentPool) -> AgentPool:
18331852
if max_surge:
18341853
upgrade_settings.max_surge = max_surge
18351854

1855+
max_unavailable = self.context.get_max_unavailable()
1856+
if max_unavailable:
1857+
upgrade_settings.max_unavailable = max_unavailable
1858+
18361859
drain_timeout = self.context.get_drain_timeout()
18371860
if drain_timeout:
18381861
upgrade_settings.drain_timeout_in_minutes = drain_timeout
@@ -2224,6 +2247,10 @@ def update_upgrade_settings(self, agentpool: AgentPool) -> AgentPool:
22242247
# why not always set this? so we don't wipe out a preview feaure in upgrade settigns like NodeSoakDuration?
22252248
agentpool.upgrade_settings = upgrade_settings
22262249

2250+
max_unavailable = self.context.get_max_unavailable()
2251+
if max_unavailable:
2252+
upgrade_settings.max_unavailable = max_unavailable
2253+
22272254
drain_timeout = self.context.get_drain_timeout()
22282255
if drain_timeout:
22292256
upgrade_settings.drain_timeout_in_minutes = drain_timeout

src/azure-cli/azure/cli/command_modules/acs/custom.py

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2408,6 +2408,7 @@ def aks_agentpool_add(
24082408
node_osdisk_type=None,
24092409
node_osdisk_size=None,
24102410
max_surge=None,
2411+
max_unavailable=None,
24112412
drain_timeout=None,
24122413
node_soak_duration=None,
24132414
undrainable_node_behavior=None,
@@ -2477,6 +2478,7 @@ def aks_agentpool_update(
24772478
tags=None,
24782479
node_taints=None,
24792480
max_surge=None,
2481+
max_unavailable=None,
24802482
drain_timeout=None,
24812483
node_soak_duration=None,
24822484
undrainable_node_behavior=None,
@@ -2530,6 +2532,7 @@ def aks_agentpool_upgrade(cmd, client, resource_group_name, cluster_name,
25302532
kubernetes_version='',
25312533
node_image_only=False,
25322534
max_surge=None,
2535+
max_unavailable=None,
25332536
drain_timeout=None,
25342537
node_soak_duration=None,
25352538
undrainable_node_behavior=None,
@@ -2552,11 +2555,12 @@ def aks_agentpool_upgrade(cmd, client, resource_group_name, cluster_name,
25522555
)
25532556

25542557
# Note: we exclude this option because node image upgrade can't accept nodepool put fields like max surge
2555-
if (max_surge or drain_timeout or node_soak_duration or undrainable_node_behavior) and node_image_only:
2558+
hasUpgradeSetting = max_surge or drain_timeout or node_soak_duration or undrainable_node_behavior or max_unavailable
2559+
if hasUpgradeSetting and node_image_only:
25562560
raise MutuallyExclusiveArgumentError(
2557-
'Conflicting flags. Unable to specify max-surge/drain-timeout/node-soak-duration with node-image-only.'
2561+
'Conflicting flags. Unable to specify max-surge/drain-timeout/node-soak-duration/max-unavailable with node-image-only.'
25582562
'If you want to use max-surge/drain-timeout/node-soak-duration with a node image upgrade, please first '
2559-
'update max-surge/drain-timeout/node-soak-duration using "az aks nodepool update --max-surge/--drain-timeout/--node-soak-duration".'
2563+
'update max-surge/drain-timeout/node-soak-duration/max-unavailable using "az aks nodepool update --max-surge/--drain-timeout/--node-soak-duration/--max-unavailable".'
25602564
)
25612565

25622566
if node_image_only:

0 commit comments

Comments
 (0)