在 Azure Kubernetes Service (AKS) 中启用或禁用节点自动预配(NAP)

本文介绍如何使用 Azure CLI 或 Azure 资源管理器 (ARM) 模板在 Azure Kubernetes Service(AKS)中启用或禁用节点自动预配(NAP)。

如果要使用自定义虚拟网络(VNet)和子网创建启用 NAP 的 AKS 群集,请参阅在自定义虚拟网络中创建节点自动配置(NAP)群集

在您开始之前

在开始之前,请查看 AKS 文章中的节点自动预配(NAP)概述 ,其中详细介绍 了 NAP 的工作原理先决条件限制

在 AKS 群集上启用节点自动预配(NAP)

以下部分介绍如何在新的或现有的 AKS 群集上启用 NAP:

在新群集上启用 NAP

  • 使用 az aks create 命令在新群集上启用节点自动预配,并将 --node-provisioning-mode 标志设置为 Auto。 以下命令还将 --network-plugin 设置为 azure,将 --network-plugin-mode 设置为 overlay,并将 --network-dataplane 设置为 cilium

    az aks create \
        --name $CLUSTER_NAME \
        --resource-group $RESOURCE_GROUP \
        --node-provisioning-mode Auto \
        --network-plugin azure \
        --network-plugin-mode overlay \
        --network-dataplane cilium \
        --generate-ssh-keys
    
  1. 创建一个名为 nap.json 的文件,并在其中添加以下 ARM 模板配置,将 properties.nodeProvisioningProfile.mode 字段设置为 Auto,从而启用 NAP。 (默认设置为 Manual.)

    {
      "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
      "contentVersion": "1.0.0.0",
      "metadata": {},
      "parameters": {},
      "resources": [
        {
          "type": "Microsoft.ContainerService/managedClusters",
          "apiVersion": "2025-05-01",
          "sku": {
            "name": "Base",
            "tier": "Standard"
          },
          "name": "napcluster",
          "location": "chinanorth3",
          "identity": {
            "type": "SystemAssigned"
          },
          "properties": {
            "networkProfile": {
                "networkPlugin": "azure",
                "networkPluginMode": "overlay",
                "networkPolicy": "cilium",
                "networkDataplane":"cilium",
                "loadBalancerSku": "Standard"
            },
            "dnsPrefix": "napcluster",
            "agentPoolProfiles": [
              {
                "name": "agentpool",
                "count": 3,
                "vmSize": "standard_d2s_v3",
                "osType": "Linux",
                "mode": "System"
              }
            ],
            "nodeProvisioningProfile": {
              "mode": "Auto"
            }
          }
        }
      ]
    }
    
  2. 使用 az deployment group create 命令在新群集上启用节点自动预配,并将 --template-file 标志设置为 ARM 模板文件的路径。

    az deployment group create --resource-group $RESOURCE_GROUP --template-file ./nap.json
    

在现有群集上启用 NAP

  • 使用 az aks update 命令在现有群集上启用节点自动预配,并将 --node-provisioning-mode 标志设置为 Auto

    az aks update --name $CLUSTER_NAME --resource-group $RESOURCE_GROUP --node-provisioning-mode Auto
    

在 AKS 集群上禁用节点自动预配(NAP)

重要

只有满足以下条件,才能在群集上禁用 NAP:

  • 没有现有的 NAP 节点。 可以使用 kubectl get nodes -l karpenter.sh/nodepool 命令检查现有的 NAP 托管节点。
  • 所有现有的卡彭特 NodePools 都将其 spec.limits.cpu 字段设置为 0。 此作可防止创建新节点,但不会中断当前正在运行的节点。
  1. spec.limits.cpu 字段设置为 0 来应用于每个现有的 Karpenter NodePool。 例如:

    apiVersion: karpenter.sh/v1
    kind: NodePool
    metadata:
      name: default
    spec:
      limits:
        cpu: 0
    

    重要

    如果不想确保以前在 NAP 节点上运行的每个 Pod 在禁用 NAP 之前安全迁移到非 NAP 节点,则可以跳过步骤 2 和步骤 3,而是对每个 NAP 托管节点使用 kubectl delete node 该命令。 但是,我们不建议跳过这些步骤,因为这可能会导致一些 Pod 处于挂起状态,而且不遵循 Pod Disruption Budgets(PDB)。

    使用 kubectl delete node 此命令时,请注意仅删除 NAP 托管节点。 可以使用命令标识 NAP 托管节点 kubectl get nodes -l karpenter.sh/nodepool

  2. karpenter.azure.com/disable:NoSchedule污点标记应用于每个 Karpenter NodePool。 例如:

    apiVersion: karpenter.sh/v1
    kind: NodePool
    metadata:
      name: default
    spec:
      template:
        spec:
          ...
          taints:
            - key: karpenter.azure.com/disable
              effect: NoSchedule
    

    该操作将启动将工作负载从 NAP 托管节点迁移到非 NAP 节点的过程,并遵循 PDB 和中断限制。 如果可以容纳,Pods 会迁移到非 NAP 节点。 如果固定大小的容量不足,某些 NAP 管理的节点将继续存在。

  3. 扩展现有的固定大小ManagedClusterAgentPools 或创建新的固定大小AgentPools,以分担节点 NAP 托管节点的负载。 当这些节点被添加到集群时,节点 NAP-管理的节点被清空,工作将迁移到固定大小的节点。

  4. 使用 kubectl get nodes -l karpenter.sh/nodepool 命令删除所有 NAP 托管节点。 如果 NAP 托管节点仍然存在,群集可能缺少固定大小的容量。 在这种情况下,应添加更多节点,以便迁移剩余的工作负荷。

  1. 使用 Manual Azure CLI 命令将 NAP 模式更新为 az aks update,并将 --node-provisioning-mode 标志设置为 Manual

    az aks update \
        --name $CLUSTER_NAME \
        --resource-group $RESOURCE_GROUP \
        --node-provisioning-mode Manual
    
  1. properties.nodeProvisioningProfile.mode 字段更新到 Manual ARM 模板中,然后重新部署。

    {
      "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
      "contentVersion": "1.0.0.0",
      "metadata": {},
      "parameters": {},
      "resources": [
        {
          "type": "Microsoft.ContainerService/managedClusters",
          "apiVersion": "2025-05-01",
          "sku": {
            "name": "Base",
            "tier": "Standard"
          },
          "name": "napcluster",
          "location": "chinanorth3",
          "identity": {
            "type": "SystemAssigned"
          },
          "properties": {
            "networkProfile": {
                "networkPlugin": "azure",
                "networkPluginMode": "overlay",
                "networkPolicy": "cilium",
                "networkDataplane":"cilium",
                "loadBalancerSku": "Standard"
            },
            "dnsPrefix": "napcluster",
            "agentPoolProfiles": [
              {
                "name": "agentpool",
                "count": 3,
                "vmSize": "standard_d2s_v3",
                "osType": "Linux",
                "mode": "System"
              }
            ],
            "nodeProvisioningProfile": {
              "mode": "Manual"
            }
          }
        }
      ]
    }
    

从自托管的开源 Karpenter 迁移到托管式节点自动预配(NAP)

如果从 开放源代码 Helm 图表中安装了 Karpenter,则仍然可以在群集上启用 NAP。 这些步骤假定已安装 Karpenter Helm 图表。

重要

在启动迁移之前,请确保您运行的是 Karpenter 的最新版本。 NAP 始终运行最新版本。

重要

在执行此迁移过程时,请注意不要删除 Karpenter CRD。 如果删除 CRD,也会删除底层的 NodeClaims,这可能导致您的工作负载中断。

  1. 为确保 Karpenter CRD 不会在步骤 2 中被卸载,请删除 managed-by=Helm 标签和注解。

    kubectl get crds -l app.kubernetes.io/managed-by=Helm -o name | grep karpenter.azure.com | xargs -I{} kubectl patch {} --type=json -p '
    [
      {"op":"remove","path":"/metadata/annotations/meta.helm.sh~1release-name"},
      {"op":"remove","path":"/metadata/annotations/meta.helm.sh~1release-namespace"},
      {"op":"remove","path":"/metadata/labels/app.kubernetes.io~1managed-by"}
    ]'
    
  2. 卸载 Helm 图表以删除 开放源代码 Karpenter 使用的部署、服务、角色和其他资源。 此时,Karpenter 不再对缩放事件做出反应,但现有节点继续正常运行。

    helm uninstall karpenter -n kube-system  # If you installed Karpenter into a different namespace than kube-system, specify that here instead of kube-system
    
  3. 在群集上启用 NAP:

    az aks update --name ${CLUSTER_NAME} --resource-group ${RESOURCE_GROUP} --node-provisioning-mode Auto --node-provisioning-default-pools None
    

    此命令会禁用默认的 NodePools,因为您已有 NodePools,并且希望继续使用它们。 如果您想启用节点自动预配的默认池,可以从 --node-provisioning-default-pools None 命令中省略 az aks update

  4. 确认迁移已完成:当步骤 3 中的 az aks update 成功完成时,则表示迁移已完成。 还可以通过检查 Karpenter CRD 上的批注来确认迁移已完成。 你应该会看到:

        meta.helm.sh/release-name: aks-managed-karpenter-overlay-base
        meta.helm.sh/release-namespace: kube-system
    

    此时,已启用 NAP,自动缩放应恢复。

监控节点自动预配

检索 Karpenter 日志和状态

可以从 Karpenter 检索日志和状态更新,以帮助诊断和调试 NAP 相关事件。 AKS 代表你管理节点自动预配,并在托管控制平面中运行它。 可以启用控制平面日志以查看 Karpenter 日志和节点自动预配的操作。 有关控制平面日志的详细信息,请参阅 AKS 控制平面日志文档

  1. 按照 此处的说明,为资源日志设置规则,将节点自动预配日志推送到 Log Analytics。 选择“日志”的选项时,请确保选中 node-auto-provisioning 对应的框。

  2. 选择群集上的“日志”部分。

  3. 在 Log Analytics 中输入以下示例查询:

    AKSControlPlane
    | where Category == "karpenter-events"
    
  4. 在 CLI 上查看节点自动预配事件:

    kubectl get events --field-selector source=karpenter-events
    

后续步骤

有关 AKS 中的节点自动预配的详细信息,请参阅以下文章: