4. Kubernetes GPU管理:NVIDIA GPU Operator、k8s设备插件机制、MIG的配置与使用
聊到Kubernetes里的GPU管理,很多人第一反应就是“装个驱动,挂个设备插件就完事了”。嗯,早期确实是这样。但等你真正管理过几十台、上百台GPU节点,你就会发现——事情没那么简单。
我个人习惯把GPU管理分成三个层次:设备发现、资源调度、资源切分。设备插件解决的是“让K8s知道节点上有GPU”;GPU Operator解决的是“让整个集群的GPU环境自动化”;而MIG解决的是“怎么把一块大GPU掰成几块用”。
咱们一个一个来聊。
4.1 设备插件机制:K8s怎么“看见”GPU的?
Kubernetes本身不认识GPU。它只知道CPU、内存这些通用资源。要让K8s知道节点上有GPU,就得靠设备插件(Device Plugin)。
设备插件是K8s的一种扩展机制。它运行在Pod里,通过gRPC和kubelet通信。说白了,就是设备插件告诉kubelet:“嘿,我这有4块GPU,你看着分配吧。”
NVIDIA官方提供的设备插件叫nvidia-device-plugin。它的工作流程很简单:
- 扫描节点上的NVIDIA GPU
- 向kubelet注册这些GPU资源(资源名是
nvidia.com/gpu) - 当Pod申请
nvidia.com/gpu时,kubelet把对应的GPU设备挂载进容器
来看一个典型的部署方式:
kubectl create -f https://raw.githubusercontent.com/NVIDIA/k8s-device-plugin/v0.14.0/nvidia-device-plugin.yml
部署完之后,你可以在节点上看到:
kubectl describe node <node-name> | grep nvidia.com/gpu
如果显示有数量,说明设备插件工作正常了。
nvidia-container-toolkit,并配置好Docker或containerd的运行时。
4.2 NVIDIA GPU Operator:把“手工活”变成“自动化”
设备插件解决了资源注册的问题。但GPU节点的运维远不止这些——驱动要装、容器运行时要配、监控要部署、MIG要配置……每个节点手动搞一遍?那运维同学怕是要骂娘了。
这就是NVIDIA GPU Operator的价值。它把GPU相关的所有组件打包成一个Operator,通过K8s原生的方式管理GPU节点。
GPU Operator管理的主要组件包括:
| 组件 | 作用 |
|---|---|
| nvidia-driver-daemonset | 在每个节点上安装NVIDIA驱动 |
| nvidia-container-toolkit-daemonset | 配置容器运行时支持GPU |
| nvidia-device-plugin-daemonset | 向K8s注册GPU资源 |
| nvidia-dcgm-exporter | 采集GPU监控指标(温度、显存、利用率等) |
| nvidia-mig-manager | 管理MIG配置(后面会细说) |
安装GPU Operator也很简单,用Helm就行:
helm repo add nvidia https://helm.ngc.nvidia.com/nvidia
helm repo update
helm install gpu-operator nvidia/gpu-operator --version v23.9.0
安装完成后,Operator会自动检测集群中的GPU节点,并部署对应的DaemonSet。你几乎不需要手动干预。
4.3 MIG(多实例GPU):一块GPU当多块用
聊完设备插件和Operator,咱们进入一个更高级的话题——MIG。
MIG是NVIDIA在Ampere架构(A100、A30)上推出的技术。它允许你把一块物理GPU切分成多个独立的GPU实例。每个实例有自己的显存、缓存和计算单元,互相隔离。
为什么要用MIG?说白了,就是提高利用率。你想想看,一个小模型推理任务,可能只需要2GB显存,但你手里只有一块80GB的A100。直接分配整卡?太浪费了。用MIG切一下,一块A100可以变成7个1g.10gb的实例,每个实例10GB显存,跑7个推理任务,利用率直接拉满。
4.3.1 MIG的配置方式
MIG配置有两种方式:
- 手动配置: 通过
nvidia-smi mig -cgi命令在节点上设置 - 自动配置: 通过GPU Operator的MIG Manager自动管理
手动配置的步骤大致如下:
# 1. 查看支持的MIG配置
nvidia-smi mig -lgip
# 2. 创建MIG配置(例如:3个20GB实例)
nvidia-smi mig -cgi 19,19,19 -C
# 3. 查看MIG实例
nvidia-smi mig -lgi
配置完成后,每个MIG实例在系统里会显示为一个独立的GPU设备。设备插件会自动识别它们,并向K8s注册为独立的nvidia.com/gpu资源。
4.3.2 在K8s中使用MIG
在K8s里使用MIG,关键是要让设备插件知道你要用哪种MIG配置。这通过设备插件策略来控制。
GPU Operator支持两种MIG策略:
- single策略: 每个MIG实例作为一个独立的GPU资源。Pod申请1个
nvidia.com/gpu,可能拿到一个完整的GPU,也可能拿到一个MIG实例。 - mixed策略: 允许Pod指定要申请的MIG配置。比如Pod可以声明“我要一个1g.10gb的MIG实例”。
配置mixed策略需要在GPU Operator的values.yaml中设置:
migManager:
enabled: true
default: all-disabled
strategy: mixed
然后在Pod的annotation中指定MIG配置:
apiVersion: v1
kind: Pod
metadata:
name: mig-pod
annotations:
nvidia.com/mig-config: "1g.10gb"
spec:
containers:
- name: cuda-container
image: nvidia/cuda:12.0-base
resources:
limits:
nvidia.com/gpu: 1
这样,调度器就会把这个Pod调度到有可用1g.10gb MIG实例的节点上。
nvidia.com/mig-config: "1g.10gb",但节点上实际配置的是 1g.10gb+me(带多进程服务的版本)。结果Pod一直Pending。后来查文档才发现,MIG配置名称必须完全匹配。建议在配置前先用 nvidia-smi mig -lgipp 确认一下准确的配置名称。
4.4 本章小结
咱们把Kubernetes GPU管理的三个核心点捋了一遍:
- 设备插件是基础,让K8s能“看见”GPU
- GPU Operator是进阶,把GPU运维自动化
- MIG是优化手段,让GPU利用率更高效
在实际项目中,我建议的落地路径是:先用设备插件跑通基础功能,然后上GPU Operator管理驱动和监控,最后根据业务需求决定是否启用MIG。别一上来就搞MIG,先把基础打牢。
嗯,关于GPU管理就聊这么多。下一节咱们会深入聊聊GPU集群的监控和可观测性——毕竟,没有监控,你都不知道你的GPU到底跑得怎么样。