要让 Kubernetes (K8s) 集群 使用 GPU,并且节点是 KVM 虚拟化 出来的,需要确保以下几点:
KVM 虚拟机透传 GPU(PCIe Passthrough)
宿主机和 K8s 节点正确安装 NVIDIA 驱动
K8s 集群安装
nvidia-device-plugin
Pod 配置 GPU 资源请求
1. KVM 虚拟机透传 GPU(PCIe Passthrough)
要让 KVM 虚拟机直接访问 GPU,必须启用 PCIe Passthrough(VFIO 直通)。
步骤 1:宿主机启用 IOMMU
编辑 /etc/default/grub
,修改 GRUB_CMDLINE_LINUX
:
GRUB_CMDLINE_LINUX="intel_iommu=on iommu=pt" # Intel CPU
# 或
GRUB_CMDLINE_LINUX="amd_iommu=on iommu=pt" # AMD CPU
更新 GRUB 并重启:
sudo update-grub
sudo reboot
验证 IOMMU 是否启用:
dmesg | grep -i iommu
# 应看到类似输出:
# DMAR: IOMMU enabled
步骤 2:屏蔽宿主机 GPU 驱动
echo "options vfio-pci ids=10de:13c2,10de:0fbb" | sudo tee /etc/modprobe.d/vfio.conf # 替换 `ids` 为你的 GPU PCI ID(用 `lspci -nn | grep NVIDIA` 查)
echo "vfio-pci" | sudo tee /etc/modules-load.d/vfio-pci.conf
sudo update-initramfs -u
sudo reboot
验证 GPU 是否绑定到 vfio-pci
:
lspci -nnk -d 10de:
# 应显示 `Kernel driver in use: vfio-pci`
步骤 3:KVM 虚拟机配置 GPU 直通
使用 virt-manager
或 virsh
给虚拟机添加 PCI 设备:
virsh edit <vm-name>
添加:
<hostdev mode='subsystem' type='pci' managed='yes'>
<source>
<address domain='0x0000' bus='0x01' slot='0x00' function='0x0'/>
</source>
</hostdev>
(替换 bus/slot/function
为 lspci
查到的 GPU PCI 地址)
2. K8s 节点安装 NVIDIA 驱动
在 每个 K8s 节点(包括 KVM 虚拟机) 上安装 NVIDIA 驱动:
# Ubuntu/Debian
sudo apt install -y nvidia-driver-535 nvidia-dkms-535 # 替换为适合的驱动版本
sudo reboot
# 验证
nvidia-smi
如果 nvidia-smi
无输出,检查:
KVM 直通是否成功(
lspci -nnk | grep NVIDIA
)驱动是否正确安装(
dkms status
)
3. K8s 集群安装 nvidia-device-plugin
方法 1:使用 Helm(推荐)
helm repo add nvidia https://helm.ngc.nvidia.com/nvidia
helm repo update
helm install --generate-name nvidia/nvidia-device-plugin
方法 2:直接部署 DaemonSet
kubectl create -f https://raw.githubusercontent.com/NVIDIA/k8s-device-plugin/v0.14.1/nvidia-device-plugin.yml
检查是否正常运行:
kubectl get pods -n kube-system | grep nvidia
kubectl describe node <node-name> | grep nvidia.com/gpu
4. 在 Pod 中使用 GPU
在 Pod 的 resources.requests
中申请 GPU:
apiVersion: v1
kind: Pod
metadata:
name: gpu-pod
spec:
containers:
- name: cuda-container
image: nvidia/cuda:12.2.0-base-ubuntu22.04
command: ["sleep", "infinity"]
resources:
limits:
nvidia.com/gpu: 1 # 申请 1 个 GPU
部署并验证:
kubectl apply -f gpu-pod.yaml
kubectl exec -it gpu-pod -- nvidia-smi
5. 验证 K8s GPU 支持
检查节点 GPU 资源:
kubectl describe node <node-name> | grep -A 10 "Capacity"
输出应包含:
Capacity:
nvidia.com/gpu: 1
Allocatable:
nvidia.com/gpu: 1
常见问题
Q1: nvidia-device-plugin
Pod CrashLoopBackOff
检查 KVM 直通是否成功(
nvidia-smi
是否能在虚拟机内运行)。检查
kubectl logs <nvidia-device-plugin-pod>
是否有错误。
Q2: Pod 无法调度(0/1 nodes are available: 1 Insufficient nvidia.com/gpu
)
确认节点有 GPU(
kubectl describe node
)。检查
nvidia-device-plugin
是否正常运行。
Q3: KVM 虚拟机无法识别 GPU
检查
lspci -nn | grep NVIDIA
是否显示 GPU。确保
vfio-pci
正确绑定(dmesg | grep vfio
)。
总结
步骤 | 操作 |
---|---|
1. KVM GPU 直通 | 启用 IOMMU + vfio-pci |
2. 节点安装驱动 | nvidia-driver + nvidia-smi 验证 |
3. K8s 安装插件 | nvidia-device-plugin |
4. Pod 申请 GPU | resources.limits: nvidia.com/gpu: 1 |
如果你的 KVM 虚拟机成功识别 GPU,并且 K8s 节点能运行 nvidia-smi
,那么 K8s 集群就可以调度 GPU 任务!