2. K8s GPU基础架构
在Kubernetes集群中调度GPU资源,核心挑战在于如何让kubelet感知到节点上的GPU设备,并将这些设备以标准化资源(如 nvidia.com/gpu)的形式暴露给调度器。本章将深入剖析支撑这一能力的三大基础组件:Device Plugin机制、NVIDIA GPU Operator以及GPU节点标签与污点。
2.1 Device Plugin机制:GPU资源的标准接入点
Kubernetes从1.8版本引入了Device Plugin框架,允许第三方厂商通过插件形式将硬件设备(如GPU、FPGA、InfiniBand)注册到kubelet,并实现设备健康检查与分配。NVIDIA的GPU Device Plugin正是这一框架的标准实现。
2.1.1 工作流程
- 注册:Device Plugin启动后,通过gRPC向kubelet注册自身,并上报设备ID、数量及健康状态。
- ListAndWatch:kubelet定期调用该接口,获取当前可用的GPU设备列表。若设备故障,插件会将其从列表中移除。
- Allocate:当Pod请求
nvidia.com/gpu资源时,kubelet调用此接口。插件返回设备ID、环境变量(如NVIDIA_VISIBLE_DEVICES)、卷挂载(如/usr/local/nvidia)等分配信息。 - Pod启动:kubelet根据Allocate返回的信息,设置容器运行时环境,确保容器只能访问被分配的GPU。
关键点:Device Plugin只负责“设备发现与分配”,不参与调度决策。调度器仅根据节点上
nvidia.com/gpu 的剩余容量进行调度。
2.1.2 部署示例
使用DaemonSet部署NVIDIA Device Plugin是最常见的做法:
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: nvidia-device-plugin-daemonset
namespace: kube-system
spec:
selector:
matchLabels:
name: nvidia-device-plugin-ds
template:
metadata:
labels:
name: nvidia-device-plugin-ds
spec:
containers:
- image: nvidia/k8s-device-plugin:v0.14.0
name: nvidia-device-plugin-ctr
securityContext:
privileged: true
volumeMounts:
- mountPath: /var/lib/kubelet/device-plugins
name: device-plugin
volumes:
- hostPath:
path: /var/lib/kubelet/device-plugins
type: DirectoryOrCreate
name: device-plugin
2.2 NVIDIA GPU Operator:自动化运维的基石
手动部署Device Plugin、驱动、容器运行时、监控组件等步骤繁琐且易出错。NVIDIA GPU Operator通过Operator模式,将GPU集群的运维工作自动化,实现“一键部署、自动升级、健康巡检”。
2.2.1 组件架构
GPU Operator并非单一组件,而是一组协同工作的控制器与DaemonSet:
| 组件 | 功能 | 部署方式 |
|---|---|---|
| nvidia-driver-daemonset | 在GPU节点上安装/升级NVIDIA驱动 | DaemonSet |
| nvidia-container-toolkit-daemonset | 配置容器运行时(containerd/Docker)以支持GPU | DaemonSet |
| nvidia-device-plugin-daemonset | 注册GPU设备到kubelet | DaemonSet |
| nvidia-dcgm-exporter | 暴露GPU指标(温度、显存、利用率)给Prometheus | DaemonSet |
| gpu-feature-discovery | 自动检测GPU型号、显存、拓扑,并打上节点标签 | DaemonSet |
| node-feature-discovery | 检测节点通用硬件特性(如PCIe、CPU指令集) | DaemonSet |
最佳实践:在生产环境中,强烈建议使用GPU Operator而非手动部署。Operator会自动处理驱动版本兼容性、节点重启后的组件恢复、以及证书轮换等运维难题。
2.2.2 部署命令
# 使用Helm安装GPU Operator
helm repo add nvidia https://helm.ngc.nvidia.com/nvidia
helm repo update
helm install gpu-operator nvidia/gpu-operator \
--namespace gpu-operator \
--create-namespace \
--set driver.enabled=true \
--set driver.version="535.154.05"
2.3 GPU节点标签与污点:精细化调度控制
仅有Device Plugin和Operator还不够——调度器需要知道哪些节点有GPU、GPU的型号和显存大小,以及哪些节点应该被预留用于特定工作负载。标签(Labels)和污点(Taints)正是实现这一目标的关键机制。
2.3.1 自动标签:GPU Feature Discovery
GPU Operator中的 gpu-feature-discovery 组件会自动为GPU节点添加以下标签:
| 标签键 | 示例值 | 说明 |
|---|---|---|
nvidia.com/gpu.product |
NVIDIA-A100-SXM4-80GB |
GPU产品型号 |
nvidia.com/gpu.memory |
81920 |
显存大小(MiB) |
nvidia.com/gpu.count |
8 |
节点上GPU数量 |
nvidia.com/gpu.compute-capability |
8.0 |
CUDA计算能力 |
nvidia.com/gpu.family |
ampere |
GPU架构家族 |
2.3.2 污点:隔离GPU节点
默认情况下,非GPU工作负载也可能被调度到GPU节点上,造成资源浪费。通过为GPU节点添加污点,可以确保只有显式容忍该污点的Pod才能运行:
# 为GPU节点添加污点
kubectl taint nodes gpu-node-1 nvidia.com/gpu=present:NoSchedule
# Pod中通过toleration容忍
spec:
tolerations:
- key: "nvidia.com/gpu"
operator: "Equal"
value: "present"
effect: "NoSchedule"
注意:如果集群中同时存在不同型号的GPU(如A100与V100),务必使用节点亲和性(nodeAffinity)结合
nvidia.com/gpu.product 标签,将特定工作负载调度到正确的GPU型号上,避免因驱动或CUDA版本不兼容导致Pod启动失败。
2.4 架构总览:从设备到调度
下图展示了GPU资源从物理设备到Pod调度的完整链路:
2.5 本章小结
- Device Plugin 是GPU资源接入K8s的标准接口,负责设备注册与分配。
- NVIDIA GPU Operator 将驱动、运行时、Device Plugin、监控、标签发现等组件自动化,大幅降低运维复杂度。
- 节点标签与污点 提供了精细化调度控制手段:标签用于识别GPU型号与容量,污点用于隔离GPU节点,防止非GPU工作负载抢占资源。