将工作负荷部署到 AKS 时,需要就所需的虚拟机(VM)大小做出节点池配置决策。 随着工作负载变得更加复杂,并且需要不同的 CPU、内存和功能才能运行,为大量资源请求设计 VM 配置的开销变得困难。
节点自动预配(NAP)使用挂起的 Pod 资源要求来决定最佳虚拟机配置,以最高效且经济高效的方式运行这些工作负荷。
节点自动预配基于开源 Karpenter 项目, AKS Karpenter 提供程序也是开源的。 节点自动预配会自动在 AKS 群集上部署、配置和管理 Karpenter。
节点自动预配的工作原理
节点自动预配预配、缩放和管理群集中的虚拟机(节点),以响应挂起的 Pod 压力。 节点自动预配使用以下关键组件:
- NodePool 和 AKSNodeClass:你创建的自定义资源定义,用于定义工作负载的节点预配策略、VM 规范和约束。
- NodeClaims:由节点自动预配进行管理,以表示可以监视的预配节点的当前状态。
- 工作负荷资源要求:Pod、部署、作业和其他 Kubernetes 资源中的 CPU、内存和其他规范,这些资源驱动预配决策。
先决条件
先决条件 | 注释 |
---|---|
Azure 订阅 | 如果你没有 Azure 订阅,可以创建一个试用版订阅。 |
Azure CLI |
2.76.0 或更高版本。 若要查找版本,请运行 az --version 。 有关安装或升级 Azure CLI 的详细信息,请参阅 安装 Azure CLI。 |
限制
- 无法在启用了群集自动缩放程序的群集中启用节点自动预配
不支持的功能
- Windows 节点池
- IPv6 群集
-
服务主体
注意
可以使用系统分配的或用户分配的托管标识。
- 磁盘加密集
- 自定义CA信任证书
- 无法停止具有节点自动预配的群集
- HTTP 代理
- 支持所有群集出口 出站类型 ,但创建群集后无法更改该类型
网络配置
对于使用节点自动预配启用的群集,建议使用以下网络配置:
- 将 Azure CNI 与 Cilium 配合使用
- Azure CNI
有关详细的网络配置要求和建议,请参阅 Node 自动预配网络配置。
关键网络注意事项:
- 建议使用 Cilium 的 Azure CNI 覆盖
- 标准负载均衡器是必需的
- 当前不支持专用群集
启用节点自动预配
在新群集上启用节点自动预配
通过将字段设置为--node-provisioning-mode
”来启用节点自动预配,该字段将节点预配配置文件设置为“自动”。此字段的默认设置为 Manual
。
使用
az aks create
命令在新群集上启用节点自动预配,并将其设置为--node-provisioning-mode
Auto
。 还可以将 to、to--network-plugin
(可选)和azure
(可选)设置为--network-plugin-mode
(overlay
可选)。--network-dataplane
cilium
az aks create \ --name $CLUSTER_NAME \ --resource-group $RESOURCE_GROUP_NAME \ --node-provisioning-mode Auto \ --network-plugin azure \ --network-plugin-mode overlay \ --network-dataplane cilium \ --generate-ssh-keys
在现有群集上启用节点自动预配
使用
az aks update
命令在现有群集上启用节点自动预配,并将其设置为--node-provisioning-mode
Auto
。az aks update --name $CLUSTER_NAME --resource-group $RESOURCE_GROUP_NAME --node-provisioning-mode Auto
基本 NodePool 和 AKSNodeClass 示例
在群集上启用节点自动预配后,可以创建基本的 NodePool 和 AKSNodeClass 来启动预配节点。 下面是一个简单的示例:
apiVersion: karpenter.sh/v1
kind: NodePool
metadata:
name: default
spec:
template:
metadata:
labels:
intent: apps
spec:
requirements:
- key: karpenter.sh/capacity-type
operator: In
values: [spot, on-demand]
- key: karpenter.azure.com/sku-family
operator: In
values: [D]
expireAfter: Never
limits:
cpu: 100
disruption:
consolidationPolicy: WhenEmptyOrUnderutilized
consolidateAfter: 0s
---
apiVersion: karpenter.azure.com/v1beta1
kind: AKSNodeClass
metadata:
name: default
annotations:
kubernetes.io/description: "General purpose AKSNodeClass for running Ubuntu2204 nodes"
spec:
imageFamily: Ubuntu2204
此示例创建一个基本 NodePool,该节点池:
- 支持现成实例和按需实例
- 使用 D 系列 VM
- 设置 CPU 限制 100
- 当节点为空或未充分利用时启用合并
自定义虚拟网络和节点自动预配
使用 AKS,可以通过参数在自定义虚拟网络 --vnet-subnet-id
中添加启用了节点自动预配的群集。 以下部分详细介绍了如何:
- 创建虚拟网络
- 通过虚拟网络创建具有权限的托管标识
- 在自定义虚拟网络中创建启用了节点自动预配的群集
创建虚拟网络
使用 az network vnet create
命令创建虚拟网络。 使用 az network vnet subnet create
命令创建群集子网。
将自定义虚拟网络与节点自动预配配合使用时,必须创建 API 服务器子网并将其委托给 Microsoft.ContainerService/managedClusters
,该子网授予 AKS 服务权限,以将 API 服务器 Pod 和内部负载均衡器注入到该子网中。 不能将子网用于任何其他工作负荷,但可以将其用于位于同一虚拟网络中的多个 AKS 群集。 支持的 API 服务器子网大小最低为 /28。
az network vnet create --name ${VNET_NAME} \
--resource-group ${RG_NAME} \
--location ${LOCATION} \
--address-prefixes 172.19.0.0/16
az network vnet subnet create --resource-group ${RG_NAME} \
--vnet-name ${VNET_NAME} \
--name clusterSubnet \
--delegations Microsoft.ContainerService/managedClusters \
--address-prefixes 172.19.0.0/28
默认情况下,允许虚拟网络中的所有流量。 但是,如果添加了网络安全组(NSG)规则来限制不同子网之间的流量,请参阅网络安全 组文档 以了解适当的权限。
创建托管标识,并在虚拟网络上授予它权限
使用 az identity create
命令创建托管标识并检索主体 ID。 使用命令将虚拟网络上的az role assignment create
角色分配给托管标识。
az identity create --resource-group ${RG_NAME} \
--name ${IDENTITY_NAME} \
--location ${LOCATION}
IDENTITY_PRINCIPAL_ID=$(az identity show --resource-group ${RG_NAME} --name ${IDENTITY_NAME} \
--query principalId -o tsv)
az role assignment create --scope "/subscriptions/${SUBSCRIPTION_ID}/resourceGroups/${RG_NAME}/providers/Microsoft.Network/virtualNetworks/${VNET_NAME}" \
--role "Network Contributor" \
--assignee ${IDENTITY_PRINCIPAL_ID}
在自定义虚拟网络中创建 AKS 群集,并启用节点自动预配
在以下命令中,Azure Kubernetes 服务 (AKS) 群集是使用 az aks create 命令作为自定义虚拟网络的一部分创建的。 创建客户虚拟网络
az aks create --name $(AZURE_CLUSTER_NAME) --resource-group $(AZURE_RESOURCE_GROUP) \
--enable-managed-identity --generate-ssh-keys -o none --network-dataplane cilium --network-plugin azure --network-plugin-mode overlay \
--vnet-subnet-id "/subscriptions/$(AZURE_SUBSCRIPTION_ID)/resourceGroups/$(AZURE_RESOURCE_GROUP)/providers/Microsoft.Network/virtualNetworks/$(CUSTOM_VNET_NAME)/subnets/$(CUSTOM_SUBNET_NAME)" \
--node-provisioning-mode Auto
az aks create --resource-group ${RG_NAME} \
--name ${CLUSTER_NAME} \
--location ${LOCATION} \
--vnet-subnet-id "/subscriptions/${SUBSCRIPTION_ID}/resourceGroups/${RG_NAME}/providers/Microsoft.Network/virtualNetworks/${VNET_NAME}/subnets/clusterSubnet" \
--assign-identity "/subscriptions/${SUBSCRIPTION_ID}/resourcegroups/${RG_NAME}/providers/Microsoft.ManagedIdentity/userAssignedIdentities/${IDENTITY_NAME}" \
--node-provisioning-mode Auto
几分钟后,该命令完成并返回有关群集的 JSON 格式的信息。
配置 kubectl
以使用 az aks get-credentials 命令连接到 Kubernetes 群集。 此命令将下载凭据,并将 Kubernetes CLI 配置为使用这些凭据。
az aks get-credentials --resource-group ${RG_NAME} --name ${CLUSTER_NAME}
使用 kubectl get 命令验证与群集的连接。 此命令返回群集节点的列表。
kubectl get nodes
节点池
有关详细的节点池配置,包括 SKU 选择器、限制和权重,请参阅 节点自动预配节点池配置。
节点自动预配使用 VM SKU 要求来决定挂起工作负荷的最佳虚拟机。 可以配置:
- SKU 系列和特定实例类型
- 资源限制和优先级
- 现成实例与按需实例
- 体系结构和功能要求
节点中断
中断控制
节点中断(包括合并或偏移)可以使用不同的方法进行控制。
固结
当节点上的工作负荷纵向缩减时,节点自动预配会使用中断规则。 这些规则决定何时以及如何删除节点和重新计划工作负荷以提高效率。 节点自动预配主要使用 合并 来删除或替换节点以实现最佳 Pod 放置。 基于状态的注意事项使用 ConsolidationPolicy
,例如 WhenEmpty
,或 WhenEmptyOrUnderUtilized
触发合并。
consolidateAfter
是一个基于时间的条件,可以设置为允许作之间的缓冲时间。
可以使用手动 kubectl delete node
删除节点,但节点自动预配还可以控制节点何时应根据规范优化节点。
disruption:
# Describes which types of Nodes node autoprovisioning should consider for consolidation
consolidationPolicy: WhenEmptyorUnderutilized
# 'WhenEmptyorUnderutilized', node autoprovisioning will consider all nodes for consolidation and attempt to remove or replace Nodes when it discovers that the Node is empty or underutilized and could be changed to reduce cost
# `WhenEmpty`, node autoprovisioning will only consider nodes for consolidation that contain no workload pods
# The amount of time node autoprovisioning should wait after discovering a consolidation decision
# This value can currently only be set when the consolidationPolicy is 'WhenEmpty'
# You can choose to disable consolidation entirely by setting the string value 'Never'
consolidateAfter: 30s
中断控制
节点自动预配可通过以下方式优化群集:
- 删除或替换未充分利用的节点
- 合并工作负载以降低成本
- 尊重中断预算和维护时段
- 根据需要提供手动控制
有关节点中断策略、通过偏移、合并和中断预算升级机制的详细信息,请参阅 节点自动预配中断策略。
Kubernetes 升级
节点自动预配节点的 Kubernetes 升级遵循控制平面 Kubernetes 版本。 如果执行群集升级,则节点会自动更新,以遵循相同的版本控制。
AKS 建议将节点自动预配与群集的 Kubernetes 自动升级 通道耦合,该通道会自动处理群集的所有 Kubernetes 升级。 将自动升级通道与 aksManagedAutoUpgradeSchedule
计划内维护时段配对,可以在工作负荷的最佳时间内计划群集升级。 有关规划群集升级的详细信息,请访问有关 计划内维护的文档
节点映像更新
默认情况下,当新的映像可用时,会自动更新节点自动预配节点池虚拟机。 在节点映像更新发生时,有多种方法可用于调节节点映像更新,包括 Karpenter 或节点中断预算和 Pod 中断预算。
注意
自动升级的节点 OS 升级通道设置 不会影响节点自动预配托管节点。 节点自动预配具有自己的自动化方法来确保节点映像升级。
监视选择事件
节点自动预配生成可用于监视部署和计划决策的群集事件。 可通过 Kubernetes 事件流查看事件。
kubectl get events -A --field-selector source=karpenter -w
禁用节点自动预配
只能在以下情况下禁用节点自动预配:
- 没有现有的节点自动预配托管节点。 用于
kubectl get nodes -l karpenter.sh/nodepool
查看节点自动预配托管节点。 - 所有现有 karpenter.sh/NodePools 的
spec.limits.cpu
字段都设置为 0。
禁用节点自动预配的步骤
- 将所有 karpenter.sh/NodePools
spec.limits.cpu
字段设置为 0。 此作可防止创建新节点,但不会中断当前正在运行的节点。
注意
如果你不关心确保节点自动预配节点上运行的每个 Pod 安全地迁移到非节点自动预配节点,则可以跳过步骤 2 和 3,转而对每个节点自动预配托管节点使用 kubectl delete node
命令。
不建议跳过步骤 2 和步骤 3,因为它可能会使某些 Pod 挂起,并且不遵循 Pod 中断预算(PDB)。
不要在未由节点自动预配管理的任何节点上运行 kubectl delete node
。
将
karpenter.azure.com/disable:NoSchedule
污点添加到每个 karpenter.sh/NodePool。apiVersion: karpenter.sh/v1 kind: NodePool metadata: name: default spec: template: spec: ... taints: - key: karpenter.azure.com/disable, effect: NoSchedule
此作开始将节点上的工作负载自动预配托管节点迁移到非 NAP 节点、遵循 Pod 中断预算和中断限制的过程。 Pod 如果可以容纳,则迁移到非 NAP 节点。 如果没有足够的固定大小容量,则某些节点自动预配托管节点将保持不变。
纵向扩展现有固定大小的 ManagedCluster AgentPools,或创建新的固定大小的 AgentPools,从节点自动预配托管节点获取负载。 将这些节点添加到群集时,节点自动预配托管节点会耗尽,工作将迁移到固定缩放节点。
确认所有节点自动预配托管节点都已删除,使用
kubectl get nodes -l karpenter.sh/nodepool
。 如果节点自动预配托管节点仍然存在,群集可能缺少固定缩放容量。 添加更多节点,以便迁移剩余的工作负荷。将 ManagedCluster 的节点预配模式参数更新为
Manual
。