有关 Azure Kubernetes 服务 (AKS) 中的高级计划程序功能的最佳做法

在 Azure Kubernetes 服务 (AKS) 中管理群集时,通常需要隔离团队和工作负荷。 Kubernetes 计划程序提供的高级功能使你可以控制:

  • 可以在某些节点上计划哪些 Pod。
  • 如何将多 Pod 应用程序适当地分布到群集中。

本最佳做法文章重点介绍面向群集操作员的高级 Kubernetes 计划功能。 在本文中,学习如何:

  • 使用排斥和容许来限制可在节点上计划的 pod。
  • 使用节点选择器或节点关联为特定节点上运行的 pod 分配优先顺序。
  • 使用 pod 间关联或反关联来拆离或组合 pod。

使用排斥和容许提供专用节点

最佳做法指导:

限制资源密集型应用程序(例如入口控制器)对特定节点的访问。 将节点资源保留给需要它们的工作负荷使用,但不允许在节点上计划其他工作负荷。

创建 AKS 群集时,可以部署支持 GPU 的节点或具有大量强大 CPU 的节点。 可以将这些节点用于大数据处理工作负荷,例如机器学习 (ML) 或人工智能 (AI)。

由于此节点资源硬件的部署成本通常比较高昂,因此需要限制可在这些节点上计划的工作负荷。 而是专门使用群集中的某些节点来运行入口服务,并阻止其他工作负荷。

这种对不同节点的支持通过使用多个节点池来提供。 AKS 群集提供一个或多个节点池。

Kubernetes 计划程序使用排斥和容许来限制可在节点上运行的工作负荷。

  • 将排斥应用于节点,以指示只能对它们计划特定 pod。
  • 然后,将容许应用于 pod,使得可以容许节点排斥的 pod。

将 pod 部署到 AKS 群集时,Kubernetes 只会在排斥与容许相符的节点上计划 pod。 例如,假设你在 AKS 群集中为支持 GPU 的节点创建了一个节点池。 你定义了名称(例如 gpu),然后定义了计划值。 将此值设置为 NoSchedule 会限制 Kubernetes 计划程序在节点上计划具有未定义容许的 pod。

az aks nodepool add \
    --resource-group myResourceGroup \
    --cluster-name myAKSCluster \
    --name taintnp \
    --node-taints sku=gpu:NoSchedule \
    --no-wait

将排斥应用到节点池中的节点后,在 pod 规范中定义一个允许对节点进行调度的容忍度。 以下示例定义了 sku: gpueffect: NoSchedule,以容许在上一步应用到节点的排斥:

kind: Pod
apiVersion: v1
metadata:
  name: tf-mnist
spec:
  containers:
  - name: tf-mnist
    image: mcr.microsoft.com/azuredocs/samples-tf-mnist-demo:gpu
    resources:
      requests:
        cpu: 0.5
        memory: 2Gi
      limits:
        cpu: 4.0
        memory: 16Gi
  tolerations:
  - key: "sku"
    operator: "Equal"
    value: "gpu"
    effect: "NoSchedule"

使用 kubectl apply -f gpu-toleration.yaml 部署此 pod 后,Kubernetes 可以成功地在应用了排斥的节点上计划 pod。 通过这种逻辑隔离,可以控制对群集中资源的访问。

应用排斥时,请与应用程序开发人员和所有者协作,让他们在其部署中定义所需的容许。

若要详细了解如何在 AKS 中使用多个节点池,请参阅为 AKS 中的群集创建和管理多个节点池

AKS 中的排斥和容许的行为

升级 AKS 中的节点池时,排斥和容许在应用于新节点时遵循一个设定的模式:

使用 VM 规模集的默认群集

可以从 AKS API 排斥节点池,以使新横向扩展的节点接收 API 指定的节点排斥。

我们假设:

  1. 你开始时有一个双节点群集:node1 和 node2。
  2. 升级节点池。
  3. 创建了两个额外节点:node3 和 node4。
  4. 排斥分别进行传递。
  5. 原始 node1 和 node2 将被删除。

没有 VM 规模集支持的群集

我们再次假设:

  1. 你有一个双节点群集:node1 和 node2。
  2. 随后升级节点池。
  3. 创建一个额外节点:node3。
  4. 来自 node1 的排斥会应用于 node3 。
  5. 删除 node1。
  6. 创建新的 node1 以替换为原始 node1 。
  7. node2 排斥会应用于新的 node1 。
  8. 删除 node2。

实际上,node1 变成了 node3,node2 变成了新的 node1 。

缩放 AKS 中的节点池时,排斥和容许不会转移,这是设计使然。

使用节点选择器和关联控制 pod 计划

最佳实践指南

使用节点选择器、节点关联或 pod 间关联来控制节点上的 pod 计划。 这些设置可让 Kubernetes 计划程序以逻辑方式(例如,按节点中的硬件)隔离工作负荷。

排斥和容许使用硬截断,以逻辑方式隔离资源。 如果 pod 不容许节点的排斥,则不会在节点上进行计划。

或者,可以使用节点选择器。 可标记节点来指示本地附加的 SSD 存储或大量内存,并在 pod 规范中定义节点选择器。 Kubernetes 会在匹配的节点上计划这些 pod。

与容许不同,没有匹配的节点选择器的 pod 仍可在标记的节点上计划。 通过这种行为可以使用节点上未用的资源,但会使定义匹配节点选择器的 pod 优先。

让我们查看具有大量内存的节点示例。 这些节点会使请求大量内存的 pod 优先。 为确保资源不会闲置,它们还允许运行其他 pod。 下方示例命令可将含有标签“hardware=highmem”的节点池添加到 myResourceGroup 的 myAKSCluster 中 。 该节点池中的所有节点都将含有此标签。

az aks nodepool add \
    --resource-group myResourceGroup \
    --cluster-name myAKSCluster \
    --name labelnp \
    --node-count 1 \
    --labels hardware=highmem \
    --no-wait

然后,pod 规范添加 nodeSelector 属性,以定义与节点上设置的标签匹配的节点选择器:

kind: Pod
apiVersion: v1
metadata:
  name: tf-mnist
spec:
  containers:
  - name: tf-mnist
    image: mcr.microsoft.com/azuredocs/samples-tf-mnist-demo:gpu
    resources:
      requests:
        cpu: 0.5
        memory: 2Gi
      limits:
        cpu: 4.0
        memory: 16Gi
    nodeSelector:
      hardware: highmem

使用这些计划程序选项时,请与应用程序开发人员和所有者协作,让他们正确定义其 pod 规范。

有关使用节点选择器的详细信息,请参阅将 Pod 分配到节点

节点关联

节点选择器是将 pod 分配到给定节点的基本解决方案。 节点相关性可提供更高的灵活性,使你可以定义在 pod 无法与节点匹配时所发生的情况。 你可以:

  • 要求 Kubernetes 计划程序与包含标记主机的 pod 相匹配。 或者,
  • 优先选择匹配,如果没有可用匹配,则允许在其他主机上计划 pod。

以下示例将节点关联设置为 requiredDuringSchedulingIgnoredDuringExecution。 这种关联要求 Kubernetes 计划使用具有匹配标签的节点。 如果没有可用的节点,则 pod 必须等待计划继续。 若要允许在其他节点上计划 pod,可改为将值设置为 preferredDuringSchedulingIgnoreDuringExecution:

kind: Pod
apiVersion: v1
metadata:
  name: tf-mnist
spec:
  containers:
  - name: tf-mnist
    image: mcr.microsoft.com/azuredocs/samples-tf-mnist-demo:gpu
    resources:
      requests:
        cpu: 0.5
        memory: 2Gi
      limits:
        cpu: 4.0
        memory: 16Gi
  affinity:
    nodeAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
        nodeSelectorTerms:
        - matchExpressions:
          - key: hardware
            operator: In
            values: highmem

该设置的 IgnoredDuringExecution 部分表示当节点标签更改时,不应从节点中逐出 pod。 Kubernetes 计划程序仅对所要计划的新 pod 使用更新的节点标签,对于已在节点上计划的 pod 则不使用。

有关详细信息,请参阅关联和反关联

pod 间关联和反关联

Kubernetes 计划程序逻辑隔离工作负荷的最终方法之一是使用 pod 间关联或反关联。 这些设置定义不应在具有现有匹配 pod 的节点上计划 pod,或者应该计划 pod。 默认情况下,Kubernetes 计划程序会尝试在跨节点的副本集3中计划多个 pod。 可围绕此行为定义更具体的规则。

例如,你具有一个还使用 Azure Cache for Redis 的 Web 应用程序。

  1. 使用 pod 反关联规则来请求 Kubernetes 计划程序跨节点分配副本。
  2. 使用关联规则来确保在相应缓存所在的同一主机上计划每个 Web 应用组件。

跨节点的 pod 分配如以下示例所示:

节点 1 节点 2 节点 3
webapp-1 webapp-2 webapp-3
cache-1 cache-2 cache-3

pod 间关联与反关联可提供比节点选择器或节点关联更复杂的部署。 进行部署后,你可以逻辑方式隔离资源,并控制 Kubernetes 如何在节点上计划 pod。

有关这个使用 Azure Cache for Redis 的 Web 应用程序的完整示例,请参阅在同一节点上共置 Pod

后续步骤

本文重点介绍了高级 Kubernetes 计划程序功能。 有关 AKS 中的群集操作的详细信息,请参阅以下最佳做法: