Leer en inglés

Compartir a través de

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

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

  • 哪些 Pod 可以在某些节点上被调度。
  • 如何在群集中合理分配多 Pod 的应用程序。

本最佳做法文章重点介绍群集作员的高级 Kubernetes 计划功能。 在这篇文章中,你将学会如何:

  • 使用 Taints 和 Tolerations 限制哪些 Pod 可以调度到节点上。
  • 优先让 Pod 利用节点选择器或节点亲和性,在特定节点上运行。
  • 拆分或组合在一起具有 Pod 间相关性或反相关性的 Pod。
  • 限制需要 GPU 的工作负载仅调度到具有可调度 GPU 的节点上。

使用污点和容忍机制来配置专属节点

最佳做法指南:

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

创建 AKS 群集时,可以部署支持 GPU 的节点或大量高性能 CPU 的节点。 有关详细信息,请参阅 在 AKS 上使用 GPU。 可以将这些节点用于大型数据处理工作负载,例如机器学习(ML)或人工智能(AI)。

由于此节点资源硬件通常很昂贵,因此限制可在这些节点上计划的工作负荷。 相反,将群集中的某些节点专用于运行入口服务并阻止其他工作负荷。

此对不同节点的支持是使用多个节点池提供的。 AKS 群集支持一个或多个节点池。

Kubernetes 计划程序使用污点和容忍度来限制可以在节点上运行的工作负载。

  • 污点 应用于节点,以指示只有特定的 Pod 能够被调度到这些节点上。
  • 然后将 容忍 应用于 Pod,使其能够 容忍 节点的污点。

在将 Pod 部署到 AKS 群集时,Kubernetes 只会将 Pod 调度到与污点符合的节点上,这些节点具备相应的容忍度。 排斥和容忍协同工作,以确保 Pod 不会被安排到不适当的节点上。 一个或多个污点被应用于节点,从而标记节点,使其不接受任何不容忍这些污点的 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: app
spec:
  containers:
  - name: app
    image: <your-workload>: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 中升级节点池时,污点和容忍遵循固定模式,因为它们应用于新节点:

使用 Azure 虚拟机规模集的默认群集

可以通过 AKS API 给节点池添加污点,使新扩展的节点接收 API 指定的节点污点。

假设:

  1. 首先使用双节点群集: node1node2
  2. 升级节点池。
  3. 将创建另外两个节点: node3node4
  4. 污点被分别传递。
  5. 将删除原始 node1node2

缺乏虚拟机规模集支持的群集

同样,假设:

  1. 你有一个双节点群集: node1node2
  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: app
spec:
  containers:
  - name: app
    image: <your-workload>: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,可以将该值设置为 首选的 DuringSchedulingIgnoreDuringExecution

kind: Pod
apiVersion: v1
metadata:
  name: app
spec:
  containers:
  - name: app
    image: <your-workload>: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 的节点上被调度。 默认情况下,Kubernetes 调度器会尝试跨节点调度副本集中多个 Pod。 可以围绕此行为定义更具体的规则。

例如,你有一个 Web 应用程序,该应用程序还使用 Azure Redis 缓存。

  • 可以使用 Pod 反关联规则来请求 Kubernetes 计划程序跨节点分发副本。
  • 使用关联规则来确保每个 Web 应用组件都安排在与相应缓存相同的主机上。

节点之间的 Pod 分布如下示例所示:

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

与节点选择器或节点相关性相比,Pod 间相关性和反相关性提供更复杂的部署。 通过部署,您可以进行逻辑隔离资源,并控制 Kubernetes 如何在节点上调度 Pod。

有关此 Web 应用程序的完整示例和 Azure Redis 缓存示例,请参阅 在同一节点上共同定位 Pod

后续步骤

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