Azure Kubernetes 服务的 GPU 最佳做法(AKS)

在 AKS 上运行 GPU 工作负荷需要正确设置和持续验证,以确保计算资源可访问、安全且充分利用。 本文概述了管理启用了 GPU 的节点、验证配置和减少工作负荷中断的最佳做法。

GPU 工作负载(如 AI 模型训练、实时推理、模拟和视频处理)通常取决于:

  • 修正 GPU 驱动程序与运行时的兼容性问题。
  • GPU 资源的精确调度。
  • 访问容器内的 GPU 硬件设备。

配置不当可能会导致高成本、意外的作业失败或 GPU 使用不足。

强制 GPU 工作负载部署

默认情况下,AKS 计划程序将 Pod 放置在具有足够 CPU 和内存的任何可用节点上。 如果没有工作负载放置控制,可能会出现两个问题:

  • 计划程序可能会在没有 GPU 的节点上放置 GPU 工作负载,从而导致工作负荷无法启动。
  • 常规用途工作负载可能会占用 GPU 节点,浪费昂贵的资源。

若要确保放置正确,请执行:

  • 使用类似于 [gpu-vendor].com/gpu: NoSchedule (例如, nvidia.com/gpu: NoSchedule)的密钥来排斥 GPU 节点。 此污点会阻止非 GPU 工作负载被调度到这些节点上。

  • 在 GPU 工作负载的 Pod 规范中添加匹配的容忍度,以便将其调度到带有污点的 GPU 节点上。

  • 在 Pod 中定义 GPU 资源请求和限制,以确保计划程序保留 GPU 容量。 例如:

    resources:
      limits:
        [gpu-vendor].com/gpu: 1
    
  • 使用验证策略或准入控制器,强制要求 GPU 工作负载包含所需的容忍度和资源限制。

这种方法可确保只有适合在 GPU 上运行的工作负载才会被调度到 GPU 节点上,并能够访问其所需的专用计算资源。

在部署生产 GPU 工作负载之前,请始终验证 GPU 节点池是否为:

  • 配备兼容的 GPU 驱动程序。
  • 托管正常的 Kubernetes 设备插件 DaemonSet。
  • [gpu-vendor].com/gpu 公开为可调度资源。

可以使用与 GPU 供应商关联的系统管理接口(SMI)确认 GPU 节点池上运行的当前驱动程序版本。

以下命令从 GPU 设备插件部署 Pod 内部执行 nvidia-smi ,以验证已启用 NVIDIA GPU 的节点池上的驱动程序安装和运行时就绪情况:

kubectl exec -it $"{GPU_DEVICE_PLUGIN_POD}" -n {GPU_NAMESPACE} -- nvidia-smi

输出应类似于以下示例输出:

+-----------------------------------------------------------------------------+
|NVIDIA-SMI 570.xx.xx    Driver Version: 570.xx.xx    CUDA Version: 12.x|
...
...

kubectl exec对每个 GPU 节点池重复该命令,确认节点上安装的驱动程序版本。

在启用了 AMD GPU 的节点池上,或者 部署 AMD GPU 组件 ,并在 ROCm 设备插件 Pod 中执行 amd-smi 命令,以确认已安装的驱动程序版本。

将启用了 GPU 的节点更新到最新的节点操作系统映像

为了确保 AKS 上的 GPU 工作负载的性能、安全性和兼容性,必须使 GPU 节点池与最新的推荐节点 OS 映像保持最新。 这些更新至关重要,因为它们:

  • 包括最新的生产级 GPU 驱动程序,替换任何已弃用或生命周期结束(EOL)版本。
  • 经过全面测试,以便与当前的 Kubernetes 版本兼容。
  • 解决 GPU 供应商标识的已知漏洞。
  • 合并最新的 OS 和容器运行时改进,以提高稳定性和效率。

通过设置 自动升级通道 或通过 手动升级将 GPU 节点池升级到 AKS 发布的最新推荐节点 OS 映像。 可以使用 AKS 发布跟踪器监视和跟踪最新的节点映像版本。

使用共享群集时分离 GPU 工作负荷

如果具有 GPU 节点池的单个 AKS 群集运行的是多种类型的 GPU 工作负荷,例如模型训练、实时推理或批处理,请务必将这些工作负荷分开以:

  • 避免不同工作负荷类型之间的意外干扰或资源争用。
  • 提高安全性并维护合规性边界。
  • 简化对每个工作负荷类别的 GPU 资源使用情况的管理和监视。

可以使用命名空间和网络策略在单个 AKS 群集中隔离 GPU 工作负荷。 这样就可以通过特定于工作负荷的配额、限制和日志记录配置进行更清晰的治理。

示例方案

请考虑托管两种不同的 GPU 工作负荷类型的 AKS 群集,这些类型不需要相互通信:

  • 训练工作负荷:资源密集型 AI 模型训练作业。
  • 推理工作负荷:延迟敏感的实时推理服务。

可以使用以下步骤分隔两个工作负荷:

  1. 使用 kubectl create namespace 命令为每个工作负荷类型创建专用命名空间。

    kubectl create namespace gpu-training
    kubectl create namespace gpu-inference
    
  2. 按类型为 GPU 工作负载 Pod 添加标签,如下例所示:

    metadata:
      namespace: gpu-training
      labels:
        workload: training
    
  3. 应用网络策略以隔离工作负荷类型之间的流量。 以下清单会阻止 gpu-training 命名空间的所有入站和出站流量(除非显式允许):

    apiVersion: networking.k8s.io/v1
    kind: NetworkPolicy
    metadata:
      name: deny-cross-namespace
      namespace: gpu-training
    spec:
      podSelector: {}
      policyTypes:
      - Ingress
      - Egress
      ingress: []
      egress: []
    

此策略:

  • 适用于 gpu-training 命名空间中的所有 Pod。
  • 默认情况下,拒绝所有传入和传出流量,支持强隔离。

此模型增强了共享 GPU 环境中的清晰度、控制和安全性,尤其是在工作负荷类型具有不同的运行时配置文件、风险级别或作要求时。

若要详细了解 AKS 和 GPU 工作负载,请参阅以下文章: