Skip to content

[AKS] az aks nodepool add/update/upgrade: Add --max-blocked-nodes to specify maximum number or percentage of extra nodes that are allowed to be blocked in the agent pool during an upgrade #8787

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

Open
wants to merge 13 commits into
base: main
Choose a base branch
from
Open
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
4 changes: 4 additions & 0 deletions src/aks-preview/HISTORY.rst
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ To release a new version, please select a new version number (usually plus 1 to
Pending
+++++++

18.0.0b6
+++++++
* Add `--max-blocked-nodes` to the `az aks nodepool add/update/upgrade` commands.

18.0.0b5
+++++++
* Add option `Ubuntu2204` and `Ubuntu2404` to `--os-sku` for `az aks nodepool add` and `az aks nodepool update`.
Expand Down
9 changes: 9 additions & 0 deletions src/aks-preview/azext_aks_preview/_help.py
Original file line number Diff line number Diff line change
Expand Up @@ -1931,6 +1931,9 @@
- name: --max-unavailable
type: string
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%
- name: --max-blocked-nodes
type: string
short-summary: The maximum number or percentage of extra nodes that are allowed to be blocked in the agent pool during an upgrade when undrainable node behavior is Cordon. When specified, it represents the number or percent used, eg. 1 or 5%.
- name: --kubelet-config
type: string
short-summary: Kubelet configurations for agent nodes.
Expand Down Expand Up @@ -2073,6 +2076,9 @@
- name: --max-unavailable
type: string
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%
- name: --max-blocked-nodes
type: string
short-summary: The maximum number or percentage of extra nodes that are allowed to be blocked in the agent pool during an upgrade when undrainable node behavior is Cordon. When specified, it represents the number or percent used, eg. 1 or 5%.
- name: --aks-custom-headers
type: string
short-summary: Send custom headers. When specified, format should be Key1=Value1,Key2=Value2
Expand Down Expand Up @@ -2125,6 +2131,9 @@
- name: --max-unavailable
type: string
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%
- name: --max-blocked-nodes
type: string
short-summary: The maximum number or percentage of extra nodes that are allowed to be blocked in the agent pool during an upgrade when undrainable node behavior is Cordon. When specified, it represents the number or percent used, eg. 1 or 5%.
- name: --mode
type: string
short-summary: The mode for a node pool which defines a node pool's primary function. If set as "System", AKS prefers system pods scheduling to node pools with mode `System`. Learn more at https://aka.ms/aks/nodepool/mode.
Expand Down
4 changes: 4 additions & 0 deletions src/aks-preview/azext_aks_preview/_params.py
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,7 @@
validate_bootstrap_container_registry_resource_id,
validate_gateway_prefix_size,
validate_max_unavailable,
validate_max_blocked_nodes,
validate_location_cluster_name_resource_group_mutually_exclusive,
validate_resource_group_parameter,
)
Expand Down Expand Up @@ -1593,6 +1594,7 @@ def load_arguments(self, _):
c.argument("node_soak_duration", type=int)
c.argument("undrainable_node_behavior")
c.argument("max_unavailable", validator=validate_max_unavailable)
c.argument("max_blocked_nodes", validator=validate_max_blocked_nodes)
c.argument("mode", arg_type=get_enum_type(node_mode_types))
c.argument("scale_down_mode", arg_type=get_enum_type(scale_down_modes))
c.argument("max_pods", type=int, options_list=["--max-pods", "-m"])
Expand Down Expand Up @@ -1725,6 +1727,7 @@ def load_arguments(self, _):
c.argument("node_soak_duration", type=int)
c.argument("undrainable_node_behavior")
c.argument("max_unavailable", validator=validate_max_unavailable)
c.argument("max_blocked_nodes", validator=validate_max_blocked_nodes)
c.argument("mode", arg_type=get_enum_type(node_mode_types))
c.argument("scale_down_mode", arg_type=get_enum_type(scale_down_modes))
# extensions
Expand Down Expand Up @@ -1796,6 +1799,7 @@ def load_arguments(self, _):
c.argument("node_soak_duration", type=int)
c.argument("undrainable_node_behavior")
c.argument("max_unavailable", validator=validate_max_unavailable)
c.argument("max_blocked_nodes", validator=validate_max_blocked_nodes)
c.argument("snapshot_id", validator=validate_snapshot_id)
c.argument(
"yes",
Expand Down
16 changes: 16 additions & 0 deletions src/aks-preview/azext_aks_preview/_validators.py
Original file line number Diff line number Diff line change
Expand Up @@ -519,6 +519,22 @@ def validate_max_unavailable(namespace):
raise CLIError("--max-unavailable should be an int or percentage")


def validate_max_blocked_nodes(namespace):
"""validates parameters max blocked nodes is positive integers or percents."""
if namespace.max_blocked_nodes is None:
return
int_or_percent = namespace.max_blocked_nodes
if int_or_percent.endswith('%'):
int_or_percent = int_or_percent.rstrip('%s')

try:
if int(int_or_percent) < 0:
raise InvalidArgumentValueError('--max-blocked-nodes must be be positive')
except ValueError:
# pylint: disable=raise-missing-from
raise InvalidArgumentValueError('--max-blocked-nodes should be an int or percentage')


def validate_assign_identity(namespace):
if namespace.assign_identity is not None:
if namespace.assign_identity == '':
Expand Down
29 changes: 29 additions & 0 deletions src/aks-preview/azext_aks_preview/agentpool_decorator.py
Original file line number Diff line number Diff line change
Expand Up @@ -503,6 +503,26 @@ def get_max_unavailable(self) -> str:
# this parameter does not need validation
return max_unavailable

def get_max_blocked_nodes(self) -> str:
"""Obtain the value of max_blocked_nodes.

:return: string
"""
# read the original value passed by the command
max_blocked_nodes = self.raw_param.get("max_blocked_nodes")
# In create mode, try to read the property value corresponding to the parameter from the `agentpool` object
if self.decorator_mode == DecoratorMode.CREATE:
if (
self.agentpool and
self.agentpool.upgrade_settings and
self.agentpool.upgrade_settings.max_blocked_nodes is not None
):
max_blocked_nodes = self.agentpool.upgrade_settings.max_blocked_nodes

# this parameter does not need dynamic completion
# this parameter does not need validation
return max_blocked_nodes

def get_enable_artifact_streaming(self) -> bool:
"""Obtain the value of enable_artifact_streaming.
:return: bool
Expand Down Expand Up @@ -1127,6 +1147,10 @@ def set_up_upgrade_settings(self, agentpool: AgentPool) -> AgentPool:
if max_unavailable:
upgrade_settings.max_unavailable = max_unavailable

max_blocked_nodes = self.context.get_max_blocked_nodes()
if max_blocked_nodes:
upgrade_settings.max_blocked_nodes = max_blocked_nodes

agentpool.upgrade_settings = upgrade_settings
return agentpool

Expand Down Expand Up @@ -1352,6 +1376,11 @@ def update_upgrade_settings(self, agentpool: AgentPool) -> AgentPool:
upgrade_settings.undrainable_node_behavior = undrainable_node_behavior
agentpool.upgrade_settings = upgrade_settings

max_blocked_nodes = self.context.get_max_blocked_nodes()
if max_blocked_nodes:
upgrade_settings.max_blocked_nodes = max_blocked_nodes
agentpool.upgrade_settings = upgrade_settings

max_unavailable = self.context.get_max_unavailable()
if max_unavailable:
upgrade_settings.max_unavailable = max_unavailable
Expand Down
26 changes: 21 additions & 5 deletions src/aks-preview/azext_aks_preview/custom.py
Original file line number Diff line number Diff line change
Expand Up @@ -1357,6 +1357,7 @@ def aks_agentpool_add(
node_soak_duration=None,
undrainable_node_behavior=None,
max_unavailable=None,
max_blocked_nodes=None,
mode=CONST_NODEPOOL_MODE_USER,
scale_down_mode=CONST_SCALE_DOWN_MODE_DELETE,
max_pods=0,
Expand Down Expand Up @@ -1440,6 +1441,7 @@ def aks_agentpool_update(
node_soak_duration=None,
undrainable_node_behavior=None,
max_unavailable=None,
max_blocked_nodes=None,
mode=None,
scale_down_mode=None,
no_wait=False,
Expand Down Expand Up @@ -1532,6 +1534,7 @@ def aks_agentpool_upgrade(cmd,
node_soak_duration=None,
undrainable_node_behavior=None,
max_unavailable=None,
max_blocked_nodes=None,
snapshot_id=None,
no_wait=False,
aks_custom_headers=None,
Expand All @@ -1551,13 +1554,24 @@ def aks_agentpool_upgrade(cmd,
)

# Note: we exclude this option because node image upgrade can't accept nodepool put fields like max surge
hasUpgradeSetting = max_surge or drain_timeout or node_soak_duration or undrainable_node_behavior or max_unavailable
hasUpgradeSetting = (
max_surge or
drain_timeout or
node_soak_duration or
undrainable_node_behavior or
max_unavailable or
max_blocked_nodes)
if hasUpgradeSetting and node_image_only:
raise MutuallyExclusiveArgumentError(
"Conflicting flags. Unable to specify max-surge/drain-timeout/node-soak-duration with node-image-only."
"If you want to use max-surge/drain-timeout/node-soak-duration with a node image upgrade, please first "
"update max-surge/drain-timeout/node-soak-duration using "
'"az aks nodepool update --max-surge/--drain-timeout/--node-soak-duration".'
"Conflicting flags. Unable to specify "
"max-surge/drain-timeout/node-soak-duration/undrainable-node-behavior/max-unavailable/max-blocked-nodes"
" with node-image-only.If you want to use "
"max-surge/drain-timeout/node-soak-duration/undrainable-node-behavior/max-unavailable/max-blocked-nodes"
" with a node image upgrade, please first update "
"max-surge/drain-timeout/node-soak-duration/undrainable-node-behavior/max-unavailable/max-blocked-nodes"
" using 'az aks nodepool update "
"--max-surge/--drain-timeout/--node-soak-duration/"
"--undrainable-node-behavior/--max-unavailable/--max-blocked-nodes'."
)

if node_image_only:
Expand Down Expand Up @@ -1619,6 +1633,8 @@ def aks_agentpool_upgrade(cmd,
instance.upgrade_settings.undrainable_node_behavior = undrainable_node_behavior
if max_unavailable:
instance.upgrade_settings.max_unavailable = max_unavailable
if max_blocked_nodes:
instance.upgrade_settings.max_blocked_nodes = max_blocked_nodes

# custom headers
aks_custom_headers = extract_comma_separated_string(
Expand Down
Loading
Loading