在 Azure Kubernetes 服务 (AKS) 群集中使用节点污点

本文介绍如何在 Azure Kubernetes 服务 (AKS) 群集中使用节点污点。

概述

AKS 调度机制负责将 Pod 放置到节点上,它基于上游 Kubernetes 调度器kube-scheduler。 可以通过使用节点相关性将 Pod 附加到一组节点上,或指示节点使用节点污点来排斥某些 Pod(这与 AKS 调度器交互),以限制 Pod 在特定节点上运行。

节点污点的工作原理是通过标记节点,使调度器避免在这些被标记的节点上放置某些 Pod。 可以在 Pod 上放置容忍度,允许调度器将该 Pod 调度到具有匹配污点的节点上。 污点和容忍度协同工作,帮助你控制调度器如何将 Pod 放置到节点上。 有关详细信息,请参阅污点和容忍的示例用例

污点是键值对,具有效果。 使用节点污点时,效果字段有三个值:NoExecuteNoSchedulePreferNoSchedule

  • NoExecute:如果 Pod 没有匹配的容忍,则会立即逐出节点上运行的 Pod。 如果 Pod 具有匹配的容忍度,并且指定了 tolerationSeconds,则可能将其逐出。
  • NoSchedule:只有具有匹配容忍度的 Pod 才会被放置在此节点上。 现有的 Pod 未被驱逐。
  • PreferNoSchedule:调度程序会避免放置任何没有匹配容忍度的 Pod。

节点污点选项

有两种类型的节点污点可以应用于 AKS 节点:节点污点节点初始化污点

  • 节点污点旨在长期保留在节点上,以便调度具有节点相关性的 Pod。 只能使用 AKS API 完全添加、更新或删除节点污点。
  • 节点初始化污点是在节点启动时应用的,旨在用于临时使用,例如在您可能需要额外时间来配置节点的场景中。 可以使用 Kubernetes API 删除节点初始化污点,且在节点生命周期内初始化污点不被保证。 当节点纵向扩展时,它们将显示在新扩展的节点副本上;当节点升级时,它们将显示在所有副本上。 如果要彻底删除初始化污点,可以在使用 Kubernetes API 去除节点的污点后,利用 AKS API 删除它们。 使用 AKS API 从群集规格中删除初始化污点后,新创建的节点不会出现这些初始化污点。 如果现有节点上仍然存在初始化污点,可以通过执行节点映像升级操作来永久删除它。

注意

使用 AKS 节点池 API 应用的节点污点和标签无法通过 Kubernetes API 进行修改,AKS 节点池 API 也不能修改 Kubernetes API 应用的节点污点和标签。 不允许修改系统污点。

这不适用于节点初始化污点。

使用节点污点

先决条件

本文假定您已经有一个现有的 AKS 群集。 如果需要 AKS 群集,可以使用 Azure CLIAzure PowerShellAzure 门户 创建一个。

使用节点污点创建节点池

  1. 使用 az aks nodepool add 命令创建具有污点的节点池,并使用 --node-taints 参数为污点指定 sku=gpu:NoSchedule

    az aks nodepool add \
        --resource-group $RESOURCE_GROUP_NAME \
        --cluster-name $CLUSTER_NAME \
        --name $NODE_POOL_NAME \
        --node-count 1 \
        --node-taints "sku=gpu:NoSchedule" \
        --no-wait
    
  2. 检查节点池的状态

  3. 检查节点上是否已设置污点

更新节点池以添加节点污点

  1. 更新节点池以使用 az aks nodepool update 命令添加节点污点,并使用 --node-taints 参数为污点指定 sku=gpu:NoSchedule

    az aks nodepool update \
        --resource-group $RESOURCE_GROUP_NAME \
        --cluster-name $CLUSTER_NAME \
        --name $NODE_POOL_NAME \
        --node-taints "sku=gpu:NoSchedule" \
        --no-wait
    
  2. 检查节点池的状态

  3. 检查节点上是否已设置污点

使用节点初始化污点(预览)

重要

AKS 预览功能可通过自助方式选择启用。 预览功能是“按现状”和“按可用”提供的,不包括在服务级别协议和有限保证中。 AKS 预览功能仅在尽最大努力的基础上由客户支持部分覆盖。 因此,这些功能并不适合用于生产。 有关详细信息,请参阅以下支持文章:

先决条件和限制

  • 需要安装并配置 3.0.0b3 或更高版本的 Azure CLI 版本。 运行 az --version 即可查找版本。 如果需要进行安装或升级,请参阅安装 Azure CLI
  • 在使用 AKS API 时,只能通过群集创建或升级来应用初始化污点。 如果使用将导致托管群集级操作的 ARM 模板,则可以在节点池创建和更新期间指定节点初始化污点。 当请求正文中存在NodeInitializationTaints时,会阻止代理池级别的操作。
  • 无法使用 Azure CLI 将初始化污点应用到 Windows 节点池。

获取集群的凭据

  • 使用 az aks get-credentials 命令获取 AKS 群集的凭据。

    az aks get-credentials --resource-group $RESOURCE_GROUP_NAME --name $CLUSTER_NAME
    

安装 aks-preview Azure CLI 扩展

  • 使用 az extension addaz extension update 命令注册或更新 aks-preview 扩展。

    # Register the aks-preview extension
    az extension add --name aks-preview
    
    # Update the aks-preview extension
    az extension update --name aks-preview
    

注册 NodeInitializationTaintsPreview 功能标志

  1. 使用 NodeInitializationTaintsPreview 命令注册 az feature register 功能标志。

    az feature register --namespace "Microsoft.ContainerService" --name "NodeInitializationTaintsPreview"
    

    状态需要几分钟时间才能显示为已注册

  2. 使用 az feature show 命令验证注册状态。

    az feature show --namespace "Microsoft.ContainerService" --name "NodeInitializationTaintsPreview"
    
  3. 当状态反映为已注册时,使用命令刷新Microsoft.ContainerService资源提供程序的注册。

    az provider register --namespace Microsoft.ContainerService
    

创建具有节点初始化污点的群集

  1. 使用 az aks create 命令和 --node-init-taints 参数为污点指定 sku=gpu:NoSchedule,创建具有节点初始化污点的群集。

    重要

    指定的节点初始化污点适用于群集中的所有节点池。 若要将初始化污点应用到特定节点,可以使用 ARM 模板而不是 CLI。

    az aks create \
        --resource-group $RESOURCE_GROUP_NAME \
        --name $CLUSTER_NAME \
        --node-count 1 \
        --node-init-taints "sku=gpu:NoSchedule" \
        --generate-ssh-keys
    
  2. 检查节点池的状态

  3. 检查节点上是否已设置污点

更新群集以添加节点初始化污点

  1. 使用 az aks update 命令和 --node-init-taints 参数指定污点 sku=gpu:NoSchedule,以更新群集并添加节点初始化污点。

    重要

    使用节点初始化污点更新群集时,污点将应用于群集中的所有节点池。 如果您的节点正在使用 VMSS,则可以在节点的 VMSS 模型更新之后(例如,节点映像版本升级操作之后)查看节点初始化污点的更新。 在触发更新 VMSS 模型的操作发生之前,节点上不会出现初始化标记。

    az aks update \
    --resource-group $RESOURCE_GROUP_NAME \
    --name $CLUSTER_NAME \
    --node-init-taints "sku=gpu:NoSchedule"
    
  2. 检查节点池的状态

  3. 检查节点上是否已设置污点

检查节点池的状态

  • 应用节点排斥或初始化污点后,请使用 az aks nodepool list 命令检查节点池的状态。

    az aks nodepool list --resource-group $RESOURCE_GROUP_NAME --cluster-name $CLUSTER_NAME
    

    如果您应用了节点污点,以下示例输出显示 <node-pool-name> 节点池中包含具有指定 nodeTaintsCreating 节点:

    [
      {
        ...
        "count": 1,
        ...
        "name": "<node-pool-name>",
        "orchestratorVersion": "1.15.7",
        ...
        "provisioningState": "Creating",
        ...
        "nodeTaints":  [
          "sku=gpu:NoSchedule"
        ],
        ...
      },
     ...
    ]
    

    如果应用了节点初始化污点,以下示例输出显示 <node-pool-name> 节点池是具有指定 CreatingnodeInitializationTaints 节点池:

    [
      {
        ...
        "count": 1,
        ...
        "name": "<node-pool-name>",
        "orchestratorVersion": "1.15.7",
        ...
        "provisioningState": "Creating",
        ...
        "nodeInitializationTaints":  [
          "sku=gpu:NoSchedule"
        ],
        ...
      },
     ...
    ]
    

检查节点上是否已设置污点

  • 使用 kubectl describe node 命令检查节点配置中的节点污点和节点初始化污点。

    kubectl describe node $NODE_NAME
    

    如果您应用了节点污点,以下示例输出显示节点池 <node-pool-name> 具有指定的 Taints

    [
        ...
        Name: <node-pool-name>
        ...
        Taints: sku=gpu:NoSchedule
        ...
        ],
        ...
     ...
    ]
    

重要

如果节点正在使用 VMSS,则在发生触发 VMSS 模型更新的操作(例如 Kubernetes 版本升级或节点映像版本升级)之前,群集中的实际节点上不会显示节点初始化污点。

删除节点污点

删除特定节点污点

  • 使用 az aks nodepool update 命令删除节点污点。 以下示例命令从节点池中删除 "sku=gpu:NoSchedule" 节点污点。

    az aks nodepool update \
    --cluster-name $CLUSTER_NAME \
    --name $NODE_POOL_NAME \
    --resource-group $RESOURCE_GROUP_NAME \
    --node-taints ""
    

删除所有节点污点

  • 使用 az aks nodepool update 命令从节点池中删除所有节点污点。 以下示例命令从节点池中删除所有节点污点。

    az aks nodepool update \
    --cluster-name $CLUSTER_NAME \
    --resource-group $RESOURCE_GROUP_NAME \
    --name $NODE_POOL_NAME \
    --node-taints ""
    

删除节点初始化污点

可以使用以下选项从节点中删除节点初始化污点:

  • 使用 Kubernetes API 暂时删除节点初始化污点。 如果以这种方式删除它们,则会在节点缩放或升级后重新出现污点。 新节点在缩放后仍具有节点初始化污点。 升级后,节点初始化污点将显示在所有节点上。
  • 使用 Kubernetes API 对节点进行去污处理,然后使用 AKS API 删除污点,从而永久删除节点初始化污点。 使用 AKS API 从群集规范中删除初始化污点后,重新映像操作后新建的节点不再具有初始化污点。

从节点池副本中删除所有初始化污点后,如果有新的初始化污点出现,现有的初始化污点可能会在升级后重新出现。

暂时删除节点初始化污点

  • 使用 kubectl taint nodes 命令暂时删除节点初始化污点。

    此命令仅从指定的节点中删除污点。 如果要从节点池中的每个节点中删除污点,则需要针对要从中删除污点的每个节点运行该命令。

    kubectl taint nodes $NODE_POOL_NAME sku=gpu:NoSchedule-
    

    删除后,节点初始化污点会在节点缩放或升级后重新出现。

永久删除节点初始化污点

  1. 按照暂时删除节点初始化污点中的步骤,使用 Kubernetes API 删除节点初始化污点。

  2. 使用 az aks update 命令使用 AKS API 从节点中删除污点。 此命令从群集中的每个节点中删除节点初始化污点。

    az aks update \
    --resource-group $RESOURCE_GROUP_NAME \
    --name $CLUSTER_NAME \
    --node-init-taints ""
    

检查是否已从节点中删除污点

  • 使用 kubectl describe node 命令检查节点配置中的节点污点和节点初始化污点。

    kubectl describe node $NODE_NAME
    

    如果删除了节点污点,以下示例输出显示 <node-pool-name> 节点池在 Taints 下已没有删除后的污点:

    [
        ...
        Name: <node-pool-name>
        ...
        Taints: 
        ...
        ],
        ...
     ...
    ]
    

后续步骤