让 Kubernetes (K8s) 集群 使用 GPU

要让 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 任务!

相关推荐
虎头金猫4 天前
4K 视频总卡在公网带宽?用 N1 + OpenList 把网盘播放链路重新理顺
运维·服务器·网络·python·容器·beautifulsoup·pandas
分布式存储与RustFS4 天前
MinIO 官方 Docker 镜像被移除:依赖它的项目该怎么办
docker·云原生·devops·对象存储·minio·分布式存储
codeejun4 天前
每日一Go·MySQL-5、锁机制全解析
云原生·golang
赵文宇(温玉)4 天前
CoreDNS的hosts插件的缺行配置导致k8s集群异常
容器·kubernetes·rancher
guo_wen_qiang4 天前
上传本地镜像到harbor中
docker·容器·持续部署
张洛闻Eren4 天前
k8s云原生【第十课】:水平 Pod 自动扩缩容
运维·数据库·云原生·kubernetes·github
忆~遂愿4 天前
本地片库怎么在外面打开?Plex + cpolar 搭一套可远程访问的私人影音库
docker·容器
Thneonl4 天前
你的 Pod 为什么 Pending:调度器两阶段
后端·kubernetes
不吃香菜kkk、4 天前
CI/CD(GitOps)学习与部署手册
运维·云原生·容器·kubernetes·云计算·jenkins·argocd
ChaITSimpleLove4 天前
云原生性能对决:JDK21虚拟线程+GraalVM vs .NET10/11 技术栈深度对比
微服务·云原生·serverless·graalvm native·native aot·runtime async·.net11/java21