原力注入

Kubernetes GPU 资源调度方案参考实现

Kubernetes 调度器扩展案例:GPU 资源调度

在现代云原生环境中,GPU 资源调度已成为支持机器学习、深度学习和高性能计算工作负载的关键需求。本文将通过一个完整的实际案例,展示如何扩展 Kubernetes 调度器来实现智能的 GPU 资源调度。

目录

  • • Kubernetes 调度器扩展案例:GPU 资源调度
    • • 目录
    • • 1 需求分析
      • • 1.1 业务需求
      • • 1.2 技术需求
      • • 1.3 性能需求
      • • 1.4 运维需求
      • • 1.5 安全需求
    • • 2 GPU 资源表示
      • • 2.1 扩展资源定义
      • • 2.2 Pod GPU 请求
      • • 2.3 GPU 资源约束
    • • 3 GPU 资源发现
      • • 3.1 Device Plugin 工作原理
      • • 3.2 NVIDIA GPU Device Plugin 部署
      • • 3.3 GPU 资源监控
    • • 4 GPU 调度器架构图
      • • 4.1 GPU 调度器整体架构
      • • 4.2 Device Plugin 工作流程
      • • 4.3 GPU 调度决策流程
      • • 4.4 GPU 资源管理架构
      • • 4.5 多租户 GPU 资源隔离架构
      • • 4.6 GPU 监控与运维架构
      • • 4.7 GPU 调度器插件架构
      • • 4.8 架构图说明
        • • 4.8.1 整体架构特点
        • • 4.8.2 关键组件说明
        • • 4.8.3 工作流程要点
        • • 4.8.4 扩展性考虑
      • • 4.9 实现路径
    • • 5 自定义调度器扩展
      • • 5.1 GPU Filter 插件实现
      • • 5.2 GPU Score 插件实现
      • • 5.3 调度器配置
    • • 6 GPU 工作负载示例
      • • 6.1 机器学习训练任务
      • • 6.2 推理服务
    • • 7 性能优化
      • • 7.1 调度性能优化
      • • 7.2 基础监控配置
      • • 7.3 简化监控部署
    • • 8 安全加固与访问控制
      • • 8.1 RBAC 配置
      • • 8.2 基础资源隔离
    • • 9 故障处理与恢复
      • • 9.1 基础健康检查
      • • 9.2 简化调度器部署
    • • 10 总结与最佳实践
      • • 10.1 需求实现总结
      • • 10.2 架构优势
      • • 10.3 最佳实践建议
      • • 10.4 扩展路线图
      • • 10.5 成功指标

1 需求分析

1.1 业务需求

场景描述:
某 AI 公司需要在 Kubernetes 集群中运行多种类型的 GPU 工作负载:

  • • 训练任务:需要高性能 GPU(如 V100、A100),通常需要多卡并行
  • • 推理服务:可以使用中等性能 GPU(如 T4、RTX 系列),延迟敏感
  • • 开发测试:可以使用入门级 GPU,资源需求灵活

挑战:

  1. 1. 资源异构性:集群中存在多种型号的 GPU
  2. 2. 调度复杂性:需要考虑 GPU 类型、拓扑结构、利用率等因素
  3. 3. 资源利用率:避免 GPU 资源浪费和碎片化
  4. 4. 性能优化:确保高优先级任务获得最佳资源
  5. 5. 可维护性:调度器需要与集群管理系统集成

1.2 技术需求

功能需求:

  • • GPU 资源发现和管理:自动发现集群中的 GPU 资源,实时监控 GPU 健康状态
  • • 基于 GPU 类型的智能调度:根据 GPU 性能等级和工作负载特征进行匹配调度
  • • GPU 拓扑感知调度:支持单节点多卡和多节点多卡的拓扑优化调度
  • • 资源利用率优化:通过智能算法减少 GPU 资源碎片化,提升整体利用率
  • • 多租户资源隔离:基于命名空间和用户组的细粒度资源隔离机制
  • • 资源配额管理:基于命名空间的 GPU 资源配额和限制机制
  • • 可扩展的自定义调度策略:提供插件化架构支持业务特定的调度需求

非功能需求:

  • • 系统规模:支持 1000+ GPU 节点的大规模集群
  • • 可用性:99.9% 系统可用性,支持故障自动恢复
  • • 监控运维:完整的性能监控、资源统计和智能告警体系
  • • 安全性:支持 RBAC 权限控制和多租户资源隔离
  • • 扩展性:插件化架构,支持自定义调度策略扩展

1.3 性能需求

调度性能指标:

# GPU 调度器性能目标配置
# 定义了调度器在生产环境中需要达到的各项性能指标
performance_targets:
# 调度延迟要求 - 衡量调度决策的响应时间
scheduling_latency:
simple_scheduling:"< 50ms"# 单 GPU 简单调度的延迟上限
complex_scheduling:"< 200ms"# 多 GPU 拓扑感知调度的延迟上限
p50:"< 50ms"# 50% 的调度请求在 50ms 内完成
p95:"< 100ms"# 95% 的调度请求在 100ms 内完成
p99:"< 200ms"# 99% 的调度请求在 200ms 内完成

# 调度吞吐量 - 衡量调度器的处理能力
throughput:
pods_per_second:"> 100"# 每秒处理的 Pod 调度请求数量
concurrent_scheduling:"> 50"# 并发处理的调度请求数量
scheduling_success_rate:"> 95%"# 调度成功率,避免调度失败导致的重试

# 资源利用率 - 衡量 GPU 资源的有效使用
resource_utilization:
gpu_utilization:"> 80%"# GPU 计算资源利用率目标
memory_utilization:"> 75%"# GPU 内存利用率目标
gpu_fragmentation_rate:"< 10%"# GPU 资源碎片化率,避免资源浪费

# 系统可用性 - 衡量调度器服务的稳定性
availability:
uptime:"99.9%"# 系统正常运行时间百分比
mttr:"< 5min"# 平均故障恢复时间(Mean Time To Recovery)
mtbf:"> 720h"# 平均故障间隔时间(Mean Time Between Failures)

1.4 运维需求

监控需求:

  • • GPU 资源监控:GPU 利用率、内存使用率、温度等核心指标
  • • 调度性能监控:调度延迟、成功率、队列长度等关键指标
  • • 告警机制:GPU 故障、调度异常、资源不足的自动告警
  • • 可视化展示:Grafana 仪表板展示 GPU 集群状态

运维需求:

  • • 部署管理:
    • • Helm Chart 标准化部署
    • • 配置文件模板化管理
    • • 滚动更新和回滚策略
  • • 故障处理:
    • • GPU 节点健康检查
    • • 自动故障节点隔离
    • • 调度器重启和恢复机制
  • • 日志管理:
    • • 结构化日志输出
    • • 集中式日志收集
    • • 问题排查工具和流程

1.5 安全需求

访问控制:

  • • RBAC 权限管理:细粒度的角色和权限定义
  • • 服务账户隔离:调度器专用服务账户和最小权限原则
  • • API 访问控制:限制调度器 API 的访问范围

资源安全:

  • • 网络策略:Pod 间通信的网络隔离规则
  • • 镜像安全:使用可信镜像仓库和镜像签名验证

2 GPU 资源表示

2.1 扩展资源定义

Kubernetes 使用扩展资源(Extended Resources)来表示 GPU:

# 节点 GPU 资源定义示例
# 展示了 Kubernetes 节点如何声明和管理 GPU 资源
apiVersion:v1
kind:Node
metadata:
name:gpu-node-1# 节点名称,用于标识具体的 GPU 节点
labels:
accelerator:nvidia-tesla-v100# GPU 型号标签,用于调度时的 GPU 类型匹配
gpu-count:"8"# GPU 数量标签,便于调度器快速筛选
gpu-memory:"32Gi"# 单卡 GPU 内存大小标签
status:
capacity:# 节点总容量,包含所有可用的 GPU 资源
nvidia.com/gpu:"8"# 节点上 GPU 卡的总数量
nvidia.com/gpu-memory:"256Gi"# 节点上 GPU 内存总容量(8 * 32Gi)
allocatable:# 可分配容量,扣除系统保留后的可用资源
nvidia.com/gpu:"8"# 可分配的 GPU 卡数量
nvidia.com/gpu-memory:"256Gi"# 可分配的 GPU 内存总量

2.2 Pod GPU 请求

# Pod GPU 资源请求示例
# 展示了如何在 Pod 中请求特定数量和类型的 GPU 资源
apiVersion:v1
kind:Pod
metadata:
name:gpu-training-job# Pod 名称,通常用于机器学习训练任务
spec:
containers:
-name:tensorflow# 容器名称
image:tensorflow/tensorflow:2.8.0-gpu# 支持 GPU 的 TensorFlow 镜像
resources:
requests:# 资源请求,调度器据此进行节点选择
nvidia.com/gpu:"4"# 请求 4 块 GPU 卡用于并行训练
nvidia.com/gpu-memory:"128Gi"# 请求 128GB GPU 内存(4 * 32GB)
limits:# 资源限制,防止容器超量使用资源
nvidia.com/gpu:"4"# 限制最多使用 4 块 GPU
nvidia.com/gpu-memory:"128Gi"# 限制最多使用 128GB GPU 内存
nodeSelector:# 节点选择器,确保调度到合适的 GPU 节点
accelerator:nvidia-tesla-v100# 指定 GPU 类型为 V100,适合高性能训练

2.3 GPU 资源约束

# GPU 亲和性和约束配置示例
# 展示了如何使用节点亲和性来精确控制 Pod 的 GPU 调度
apiVersion:v1
kind:Pod
metadata:
name:multi-gpu-job# 多 GPU 训练任务 Pod
spec:
affinity:# 亲和性配置,用于精确控制调度行为
nodeAffinity:# 节点亲和性,基于节点标签进行调度
requiredDuringSchedulingIgnoredDuringExecution:# 硬性要求,调度时必须满足
nodeSelectorTerms:# 节点选择条件列表
-matchExpressions:# 匹配表达式,支持多种操作符
-key:accelerator# 基于 GPU 型号标签进行筛选
operator:In# 操作符:包含于指定值列表中
values: ["nvidia-tesla-v100", "nvidia-tesla-a100"]  # 支持的高性能 GPU 型号
-key:gpu-count# 基于 GPU 数量标签进行筛选
operator:Gt# 操作符:大于指定值
values: ["4"]             # 要求节点至少有 5 块 GPU(大于4)
containers:
-name:training# 训练容器
image:pytorch/pytorch:1.12.0-cuda11.3-cudnn8-runtime# PyTorch GPU 运行时镜像
resources:
requests:
nvidia.com/gpu:"8"# 请求 8 块 GPU 进行大规模并行训练

3 GPU 资源发现

3.1 Device Plugin 工作原理

Kubernetes Device Plugin 框架负责 GPU 资源的发现和管理:

3.2 NVIDIA GPU Device Plugin 部署

# NVIDIA Device Plugin DaemonSet 配置
# 负责在每个 GPU 节点上运行 Device Plugin,实现 GPU 资源的发现和管理
apiVersion:apps/v1
kind:DaemonSet
metadata:
name:nvidia-device-plugin-daemonset# DaemonSet 名称
namespace:kube-system# 部署在系统命名空间
spec:
selector:
matchLabels:
name:nvidia-device-plugin-ds# 用于选择 Pod 的标签
updateStrategy:
type:RollingUpdate# 滚动更新策略,确保服务连续性
template:
metadata:
labels:
name:nvidia-device-plugin-ds# Pod 标签,与 selector 匹配
spec:
tolerations:# 容忍配置,允许在有 GPU 污点的节点上运行
-key:nvidia.com/gpu# 容忍 GPU 相关的污点
operator:Exists# 只要污点存在就容忍
effect:NoSchedule# 容忍 NoSchedule 效果的污点
priorityClassName:system-node-critical# 高优先级,确保系统关键组件优先调度
containers:
-image:nvcr.io/nvidia/k8s-device-plugin:v0.12.0# NVIDIA 官方 Device Plugin 镜像
name:nvidia-device-plugin-ctr# 容器名称
args: ["--fail-on-init-error=false"]  # 启动参数,初始化失败时不退出
securityContext:# 安全上下文配置
allowPrivilegeEscalation:false# 禁止权限提升
capabilities:
drop: ["ALL"]                # 移除所有 Linux capabilities
volumeMounts:
-name:device-plugin# 挂载 Device Plugin 套接字目录
mountPath:/var/lib/kubelet/device-plugins# kubelet Device Plugin 通信目录
volumes:
-name:device-plugin# 定义 hostPath 卷
hostPath:
path:/var/lib/kubelet/device-plugins# 主机上的 Device Plugin 目录
nodeSelector:# 节点选择器,只在 NVIDIA GPU 节点上运行
accelerator:nvidia# 选择带有 nvidia 标签的节点

3.3 GPU 资源监控

#!/bin/bash
# GPU 资源监控和查看命令集合
# 提供了一系列用于监控和管理 GPU 资源的 kubectl 命令

# 1. 查看集群中所有节点的 GPU 资源配置
# 显示每个节点的 GPU 容量和可分配数量
kubectl describe nodes | grep -A 5 "nvidia.com/gpu"

# 2. 查看 GPU 节点的资源使用情况
# 显示 GPU 节点的 CPU、内存等资源使用率
kubectl top nodes --selector=accelerator=nvidia

# 3. 查看特定 GPU 节点上运行的 Pod 分布
# 了解 GPU 资源的实际分配和使用情况
kubectl get pods --all-namespaces -o wide \
  --field-selector spec.nodeName=gpu-node-1

# 4. 查看所有 GPU 相关的 Pod 及其资源请求
kubectl get pods --all-namespaces -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.spec.containers[*].resources.requests.nvidia\.com/gpu}{"\n"}{end}' | grep -v "^.*\t$"

# 5. 查看 GPU Device Plugin 的运行状态
kubectl get pods -n kube-system -l name=nvidia-device-plugin-ds

# 6. 查看 GPU 节点的详细标签信息
kubectl get nodes -l accelerator=nvidia --show-labels

4 GPU 调度器架构图

本章节提供 Kubernetes GPU 调度器相关的架构图,展示了 GPU 资源调度的完整技术架构和工作流程。

4.1 GPU 调度器整体架构

本架构图展示了 Kubernetes GPU 调度器的完整系统架构,包括控制平面、工作节点、监控系统和工作负载的交互关系。

架构核心组件:

  • • 控制平面:包含 API Server、etcd、Controller Manager 和自定义 GPU 调度器
  • • GPU 调度器组件:GPUFilter 插件、GPUScore 插件和调度器配置
  • • 工作节点:配备不同类型 GPU 的节点,运行 kubelet、Device Plugin 和各类工作负载
  • • 监控运维:Prometheus、Grafana 和 AlertManager 组成的可观测性体系

关键特性:

  1. 1. 异构 GPU 支持:支持 V100、T4、A100 等不同性能等级的 GPU
  2. 2. 智能调度:基于 GPU 类型、利用率、拓扑等多维度进行调度决策
  3. 3. 工作负载感知:针对训练、推理、开发等不同场景优化调度策略
  4. 4. 全面监控:实时监控 GPU 使用情况,及时发现性能瓶颈和异常

4.2 Device Plugin 工作流程

本序列图详细展示了 NVIDIA Device Plugin 与 Kubernetes 系统各组件的交互流程,这是 GPU 资源管理的核心机制。

工作流程阶段:

  1. 1. 注册阶段:Device Plugin 向 kubelet 注册,声明管理的资源类型(如 nvidia.com/gpu)
  2. 2. 资源发现阶段:持续扫描和上报 GPU 设备信息,更新节点资源状态
  3. 3. 调度阶段:GPU 调度器根据资源信息进行智能调度决策
  4. 4. 资源分配阶段:为容器分配具体的 GPU 设备,配置设备路径和环境变量
  5. 5. 运行时监控:持续监控 GPU 设备健康状态,及时上报异常
  6. 6. 资源释放:Pod 终止时释放 GPU 资源,供其他工作负载使用

关键技术点:

  • • gRPC 通信:Device Plugin 与 kubelet 通过 gRPC 协议通信
  • • 设备隔离:通过 cgroups 和设备文件实现 GPU 设备隔离
  • • 健康检查:定期检查 GPU 设备状态,确保资源可用性
  • • 动态发现:支持热插拔,动态发现新增或移除的 GPU 设备

4.3 GPU 调度决策流程