让 Kubernetes (K8s) 集群 使用 GPU

发布于:2025-06-10 ⋅ 阅读:(17) ⋅ 点赞:(0)

要让 Kubernetes (K8s) 集群 使用 GPU,并且节点是 KVM 虚拟化 出来的,需要确保以下几点:

  1. KVM 虚拟机透传 GPU(PCIe Passthrough)

  2. 宿主机和 K8s 节点正确安装 NVIDIA 驱动

  3. K8s 集群安装 nvidia-device-plugin

  4. 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 任务!