«

K8s GPU 指南宝典

myluzh 发布于 阅读:1 Kubernetes


适合已经会 Kubernetes、但第一次运维 GPU 集群的人。
目标不是让你马上变成 CUDA 开发者,而是让你能把 GPU 节点稳定接入 K8s、让业务 Pod 正确使用 GPU,并且知道怎么排障、扩展、监控和规划后续能力。


0. 你应该先建立的整体模型

K8s GPU 集群可以拆成 6 层:

硬件 GPU
  ↓
宿主机 NVIDIA Driver
  ↓
容器运行时 GPU 注入层:NVIDIA Container Toolkit / CDI
  ↓
Kubernetes GPU 资源发现:nvidia-device-plugin / GPU Operator / HAMi
  ↓
调度与资源声明:nvidia.com/gpu、RuntimeClass、nodeSelector、affinity
  ↓
业务容器:CUDA、cuDNN、PyTorch、TensorFlow、推理服务

新手最容易混淆的是:

一句话:

Driver 让宿主机能用 GPU;Container Toolkit 让容器能看见 GPU;device plugin 让 K8s 能调度 GPU。


1. 你需要学哪些东西,学到什么深度

1.1 CUDA

你不需要一开始学习 CUDA 编程,但要理解这些概念:

运维侧最重要的是:

nvidia-smi

它可以看:

1.2 NVIDIA Driver

Driver 是 GPU 节点最核心的宿主机依赖。没有 Driver,nvidia-smi 就不能正常工作。

生产建议:

1.3 NVIDIA Container Toolkit

它负责让容器运行时能把 GPU 设备和 NVIDIA 驱动库注入到容器里。

常见组件:

在 containerd 场景下,常见配置命令:

nvidia-ctk runtime configure --runtime=containerd
systemctl restart containerd

你还会看到 CDI 这个词。CDI 是 Container Device Interface,用来把设备注入容器。新的 GPU Operator 默认走 CDI 方向;手工安装 NVIDIA runtime 时,很多环境仍会用 RuntimeClass 指向 nvidia runtime。两条路线都能工作,但不要把两套配置混在一起理解。

1.4 nvidia-device-plugin

这是 NVIDIA 官方 Kubernetes device plugin。

它负责把 GPU 注册给 kubelet,默认资源名是:

nvidia.com/gpu

Pod 通过下面这种方式申请 GPU:

resources:
  limits:
    nvidia.com/gpu: 1

1.5 GPU Operator

NVIDIA GPU Operator 是更自动化的路线。

它可以帮你管理:

如果是新集群、节点环境标准化、希望少手工维护,优先考虑 GPU Operator。

1.6 HAMi

HAMi 是 GPU 共享和异构设备虚拟化方案。

它常用于:

HAMi 不是第一天必须上。建议先掌握官方 device plugin,再看 HAMi。


2. 最小可行学习路线

建议按这个顺序学:

第 1 阶段:单机 GPU 基础

目标:

要会的命令:

lspci | grep -i nvidia
lsmod | grep nvidia
nvidia-smi
journalctl -k | grep -i nvidia

第 2 阶段:容器里使用 GPU

目标:

要理解:

第 3 阶段:K8s 整卡调度

目标:

要理解:

第 4 阶段:生产化

目标:

第 5 阶段:共享和高级调度

目标:


3. 安装 GPU 节点:手工路线

下面以 Ubuntu/Debian 系为例。生产环境请先在测试节点验证。

3.1 确认 GPU 硬件

lspci | grep -i nvidia

如果没有输出,先检查:

3.2 禁用 nouveau

nouveau 是开源 NVIDIA 显卡驱动,通常会和官方 NVIDIA Driver 冲突。

查看是否加载:

lsmod | grep nouveau

写入 blacklist:

cat >/etc/modprobe.d/blacklist-nouveau.conf <<'EOF'
blacklist nouveau
options nouveau modeset=0
EOF

更新 initramfs:

update-initramfs -u

如果系统使用 GRUB,可以追加内核参数:

vim /etc/default/grub

找到类似这一行:

GRUB_CMDLINE_LINUX_DEFAULT="quiet splash"

改成:

GRUB_CMDLINE_LINUX_DEFAULT="quiet splash nouveau.modeset=0"

更新 GRUB:

update-grub
reboot

重启后确认:

lsmod | grep nouveau

没有输出通常表示未加载。

3.3 安装 NVIDIA Driver

推荐用包管理器安装,便于升级和卸载。

Ubuntu 常见方式:

ubuntu-drivers devices

选择推荐版本后安装,例如:

apt-get update
apt-get install -y nvidia-driver-550
reboot

重启后验证:

nvidia-smi

看到 GPU 型号、驱动版本、显存信息就算第一步成功。

3.4 关于 CUDA .run 安装包

别人笔记里的方式是:

wget https://developer.download.nvidia.com/compute/cuda/12.1.0/local_installers/cuda_12.1.0_530.30.02_linux.run
chmod +x cuda_12.1.0_530.30.02_linux.run
./cuda_12.1.0_530.30.02_linux.run

这确实能安装 CUDA Toolkit,并且安装时可以选择安装 Driver。

但在 K8s GPU 节点运维里,我建议你理解为:

业务需要的 CUDA runtime 通常在镜像里,例如:

nvidia/cuda:12.3.2-base-ubuntu20.04
pytorch/pytorch:...
tensorflow/tensorflow:...

3.5 安装 NVIDIA Container Toolkit

Ubuntu/Debian 示例:

curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey \
  | gpg --dearmor -o /usr/share/keyrings/nvidia-container-toolkit-keyring.gpg

curl -s -L https://nvidia.github.io/libnvidia-container/stable/deb/nvidia-container-toolkit.list \
  | sed 's#deb https://#deb [signed-by=/usr/share/keyrings/nvidia-container-toolkit-keyring.gpg] https://#g' \
  | tee /etc/apt/sources.list.d/nvidia-container-toolkit.list

apt-get update
apt-get install -y nvidia-container-toolkit

生产环境建议固定版本。NVIDIA 官方安装页在 2026-05-25 的示例版本是:

export NVIDIA_CONTAINER_TOOLKIT_VERSION=1.19.1-1
apt-get install -y \
  nvidia-container-toolkit=${NVIDIA_CONTAINER_TOOLKIT_VERSION} \
  nvidia-container-toolkit-base=${NVIDIA_CONTAINER_TOOLKIT_VERSION} \
  libnvidia-container-tools=${NVIDIA_CONTAINER_TOOLKIT_VERSION} \
  libnvidia-container1=${NVIDIA_CONTAINER_TOOLKIT_VERSION}

配置 containerd:

nvidia-ctk runtime configure --runtime=containerd
systemctl restart containerd

检查 containerd 配置:

containerd config dump | grep -A20 -B5 nvidia

你应该能看到 nvidia runtime handler。


4. containerd、RuntimeClass 和 GPU 容器

4.1 两种常见模式

模式 A:默认 runtime 仍是 runc

这是我更推荐的新手和生产混合节点方式。

特点:

模式 B:默认 runtime 改成 nvidia

特点:

NVIDIA runtime 对非 GPU 容器通常可以作为 no-op,但生产上我仍建议你先用 RuntimeClass 显式区分。

4.2 创建 RuntimeClass

前提:宿主机 containerd 已经有 nvidia runtime handler。

apiVersion: node.k8s.io/v1
kind: RuntimeClass
metadata:
  name: nvidia
handler: nvidia

应用:

kubectl apply -f runtimeclass-nvidia.yaml

确认:

kubectl get runtimeclass

5. 安装 nvidia-device-plugin

5.1 作用

NVIDIA device plugin 会在 GPU 节点上运行 DaemonSet,然后向 kubelet 注册 GPU 资源。

默认资源名:

nvidia.com/gpu

5.2 安装

可以先用官方静态 YAML 学习。生产环境建议固定版本,不要长期直接追 main

截至 2026-05-25,NVIDIA k8s-device-plugin GitHub release 页面显示的最新版本是 v0.19.1。示例:

kubectl apply -f https://raw.githubusercontent.com/NVIDIA/k8s-device-plugin/v0.19.1/deployments/static/nvidia-device-plugin.yml

如果你要确认当前最新版本:

open https://github.com/NVIDIA/k8s-device-plugin/releases

版本号请按你实际验证过的版本调整。注意:官方 README 里的示例版本有时会滞后,release 页面更适合作为版本判断入口。

5.3 验证资源

查看 DaemonSet:

kubectl -n kube-system get ds | grep nvidia
kubectl -n kube-system get pods -o wide | grep nvidia

查看节点资源:

kubectl describe node <gpu-node-name> | grep -A10 -B5 nvidia.com/gpu

或:

kubectl get nodes -o custom-columns=NAME:.metadata.name,GPU:.status.allocatable.nvidia\\.com/gpu

如果能看到 nvidia.com/gpu,说明 K8s 已经认识 GPU。


6. 第一个 GPU Pod

6.1 整卡测试 Pod

apiVersion: v1
kind: Pod
metadata:
  name: gpu-test
spec:
  runtimeClassName: nvidia
  restartPolicy: Never
  containers:
  - name: gpu-test
    image: nvidia/cuda:12.3.2-base-ubuntu20.04
    command: ["nvidia-smi"]
    resources:
      limits:
        nvidia.com/gpu: 1

应用:

kubectl apply -f gpu-test.yaml
kubectl logs gpu-test

如果日志里看到 nvidia-smi 输出,说明链路成功:

Driver -> Container Toolkit -> containerd -> RuntimeClass -> device plugin -> Pod

6.2 常驻测试 Pod

有时你想进容器里手动检查:

apiVersion: v1
kind: Pod
metadata:
  name: gpu-shell
spec:
  runtimeClassName: nvidia
  restartPolicy: Never
  containers:
  - name: gpu-shell
    image: nvidia/cuda:12.3.2-base-ubuntu20.04
    command: ["sleep", "infinity"]
    resources:
      limits:
        nvidia.com/gpu: 1

进入容器:

kubectl exec -it gpu-shell -- bash
nvidia-smi

6.3 不要把型号写成资源名

默认情况下不要写:

resources:
  limits:
    nvidia.com/t4: 1

NVIDIA 官方 device plugin 默认不是这样暴露资源。

正确写法通常是:

resources:
  limits:
    nvidia.com/gpu: 1

如果你要选择 T4、A10、A100 这种型号,用 node label:

kubectl label node <node-name> accelerator=nvidia-t4

Pod:

nodeSelector:
  accelerator: nvidia-t4

7. GPU 节点的标签、污点和调度

7.1 给 GPU 节点打标签

例子:

kubectl label node gpu-node-1 node-role.kubernetes.io/gpu=true
kubectl label node gpu-node-1 accelerator=nvidia-t4
kubectl label node gpu-node-1 gpu.vendor=nvidia

业务 Pod 可以使用:

nodeSelector:
  accelerator: nvidia-t4

7.2 给 GPU 节点打污点

如果不希望普通 CPU Pod 跑到 GPU 节点:

kubectl taint node gpu-node-1 nvidia.com/gpu=true:NoSchedule

GPU Pod 增加 toleration:

tolerations:
- key: "nvidia.com/gpu"
  operator: "Equal"
  value: "true"
  effect: "NoSchedule"

7.3 GPU Pod 示例

apiVersion: v1
kind: Pod
metadata:
  name: gpu-test-t4
spec:
  runtimeClassName: nvidia
  restartPolicy: Never
  nodeSelector:
    accelerator: nvidia-t4
  tolerations:
  - key: "nvidia.com/gpu"
    operator: "Equal"
    value: "true"
    effect: "NoSchedule"
  containers:
  - name: gpu-test
    image: nvidia/cuda:12.3.2-base-ubuntu20.04
    command: ["nvidia-smi"]
    resources:
      limits:
        nvidia.com/gpu: 1

8. CUDA 版本和 Driver 兼容性

8.1 基本原则

你要记住:

8.2 举例

如果宿主机驱动来自 CUDA 12.1 安装包:

Driver 530.30.02

然后你跑:

nvidia/cuda:12.3.2-base-ubuntu20.04

这时就要查 CUDA 12.3 对 Driver 的要求。

为了减少这类问题,生产上常用策略:

8.3 常见现象

如果 Driver 太旧,容器里可能报:

CUDA driver version is insufficient for CUDA runtime version

或:

Failed to initialize NVML

排查顺序:

nvidia-smi
kubectl logs <pod>
kubectl describe pod <pod>
kubectl describe node <node>

9. GPU Operator 路线

9.1 什么时候用 GPU Operator

适合:

不适合:

9.2 GPU Operator 管理哪些东西

常见包括:

9.3 基本安装思路

通常用 Helm 安装:

helm repo add nvidia https://helm.ngc.nvidia.com/nvidia
helm repo update
helm install --wait --generate-name \
  -n gpu-operator --create-namespace \
  nvidia/gpu-operator \
  --version=v26.3.1

截至 2026-05-25,NVIDIA GPU Operator 官方安装文档标注当前 patch release 是 v26.3.1。安装前仍然要看 release notes 和组件矩阵。

生产前一定要看 values:

helm show values nvidia/gpu-operator > gpu-operator-values.yaml

你要重点确认:

特别注意:GPU Operator v26.3.1 默认 cdi.enabled=true。在 CDI 模式下,GPU 注入逻辑和手工 RuntimeClass: nvidia 路线不同,很多场景里 Pod 只需要申请 nvidia.com/gpu,不需要再写 runtimeClassName: nvidia。如果你是手工安装 NVIDIA runtime,才按第 4 章的 RuntimeClass 路线理解。

9.4 手工路线 vs GPU Operator

方案 优点 缺点 适合场景
手工安装 容易理解每一层,排障清晰 节点多了维护成本高 学习、少量节点、强自定义
GPU Operator 自动化程度高,组件完整 黑盒感更强,和已有环境可能冲突 新集群、标准化生产环境

我的建议:

先手工跑通 1 台测试节点,再考虑 GPU Operator 管理生产集群。


10. GPU 共享方案

GPU 默认是按整卡分配的:

nvidia.com/gpu: 1

但很多场景里,一张 GPU 太大,一个小模型或推理服务用不满。这时会考虑共享。

10.1 time-slicing

特点:

适合:

不适合:

10.1.1 原理

NVIDIA device plugin 本身就是一个 DaemonSet Pod。它的 ConfigMap 里有一个 sharing.timeSlicing 配置项,可以把一张物理 GPU "复制"成多份上报给 K8s 调度器。

物理 GPU 0  →  replicas: 4  →  K8s 看到 4 个 nvidia.com/gpu
物理 GPU 1  →  replicas: 4  →  K8s 看到 4 个 nvidia.com/gpu

总共 2 张物理卡,K8s 认为有 8 张

本质是时间片轮转,不是显存硬隔离。多个 Pod 共享同一张卡的 GPU 时间,但共享全部显存,没有显存上限限制。

重要提醒nvidia.com/gpu 仍然是整数型资源,Pod 里还是写 nvidia.com/gpu: 1。只是节点上报的数量变多了。

10.1.2 方式一:ConfigMap 配置(推荐)

适用于单独安装 nvidia-device-plugin 的场景。

第 1 步:创建 ConfigMap

apiVersion: v1
kind: ConfigMap
metadata:
  name: nvidia-device-plugin-config
  namespace: kube-system
data:
  config.yaml: |
    version: v1
    sharing:
      timeSlicing:
        resources:
          - name: nvidia.com/gpu
            replicas: 4
            # devices: ["0", "1"]    # 可选:只对指定 GPU 生效,不填则全部
    # flags:
    #   failOnInitError: true
    #   migStrategy: none
    #   deviceListStrategy: envvar

参数说明:

参数 说明
replicas 每张物理 GPU 上报的份数。replicas: 4 表示 1 张卡变 4 份
devices 可选,指定对哪些 GPU 编号生效。不填则对节点上所有 GPU 生效

第 2 步:部署或修改 Device Plugin DaemonSet

需要让 DaemonSet 挂载这个 ConfigMap 并通过 --config-file 参数引用。

完整 DaemonSet 示例:

apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: nvidia-device-plugin-daemonset
  namespace: kube-system
  labels:
    app: nvidia-device-plugin
spec:
  selector:
    matchLabels:
      app: nvidia-device-plugin
  template:
    metadata:
      labels:
        app: nvidia-device-plugin
    spec:
      tolerations:
        - key: nvidia.com/gpu
          operator: Exists
          effect: NoSchedule
      priorityClassName: system-node-critical
      containers:
        - name: nvidia-device-plugin
          image: nvcr.io/nvidia/k8s-device-plugin:v0.19.1
          args:
            - --config-file=/etc/nvidia-device-plugin/config.yaml
          env:
            - name: PASS_DEVICE_SPECS
              value: "true"
            - name: FAIL_ON_INIT_ERROR
              value: "true"
          volumeMounts:
            - name: device-plugin
              mountPath: /var/lib/kubelet/device-plugins
            - name: config
              mountPath: /etc/nvidia-device-plugin
      volumes:
        - name: device-plugin
          hostPath:
            path: /var/lib/kubelet/device-plugins
        - name: config
          configMap:
            name: nvidia-device-plugin-config

第 3 步:应用并验证

# 应用 ConfigMap 和 DaemonSet
kubectl apply -f nvidia-device-plugin-config.yaml
kubectl apply -f nvidia-device-plugin-ds.yaml

# 等待 Pod 重建
kubectl -n kube-system rollout status ds/nvidia-device-plugin-daemonset

# 验证节点 GPU 资源(应该看到数量变多了)
kubectl describe node <gpu-node-name> | grep -A10 nvidia.com/gpu

如果原来有 2 张 GPU,配置 replicas: 4 后应该看到:

nvidia.com/gpu:  8    # 2 × 4 = 8

10.1.3 方式二:GPU Operator 场景

如果使用 GPU Operator 安装,通过 ClusterPolicy 或 Helm values 配置。

Helm values 示例

# values-time-slicing.yaml
devicePlugin:
  enabled: true
  config:
    name: nvidia-device-plugin-config
    share:
      timeSlicing:
        resources:
          - name: nvidia.com/gpu
            replicas: 4

或者通过 patch ClusterPolicy:

kubectl patch clusterpolicy cluster-policy \
  -n gpu-operator \
  --type=merge \
  -p '{"devicePlugin":{"config":{"name":"nvidia-device-plugin-config"}}}'

10.1.4 只对部分节点生效

如果你只想让某些 GPU 节点开启 time-slicing(比如推理节点),其他节点保持整卡分配(比如训练节点),可以用 label 区分:

# 给推理节点打标签
kubectl label node gpu-inference-01 nvidia.com/device-plugin.config=time-slicing

# 训练节点不打标签,使用默认整卡模式

然后在 DaemonSet 上加 nodeAffinity,或者使用 GPU Operator 的 node-specific 配置。

10.1.5 Time-Slicing 的局限

方面 说明
显存隔离 ❌ 无。所有共享 Pod 可以访问全部显存
算力隔离 ❌ 无硬隔离,时间片轮转
OOM 风险 高。一个 Pod 吃满显存会导致其他 Pod 崩溃
调度感知 调度器只看数量,不知道实际显存用量
适用场景 多个轻量推理、开发测试、GPU 利用率低的场景

对比 HAMi 的显存隔离:

Time-Slicing:
  Pod A: nvidia.com/gpu: 1  →  可用全部显存(如 16G)
  Pod B: nvidia.com/gpu: 1  →  可用全部显存(如 16G)
  Pod C: nvidia.com/gpu: 1  →  可用全部显存(如 16G)
  Pod D: nvidia.com/gpu: 1  →  可用全部显存(如 16G)
  → 实际物理显存只有 16G,谁用多了别人就没了

HAMi:
  Pod A: nvidia.com/gpu: 1, nvidia.com/gpumem: 4000  →  最多 4G
  Pod B: nvidia.com/gpu: 1, nvidia.com/gpumem: 4000  →  最多 4G
  Pod C: nvidia.com/gpu: 1, nvidia.com/gpumem: 4000  →  最多 4G
  Pod D: nvidia.com/gpu: 1, nvidia.com/gpumem: 4000  →  最多 4G
  → 每个有硬上限,互不影响

10.1.6 验证 Time-Slicing 是否生效

# 查看节点 GPU 资源
kubectl describe node <gpu-node-name> | grep nvidia.com/gpu

# 查看 device plugin 日志,确认加载了 config
kubectl -n kube-system logs <nvidia-device-plugin-pod> | grep -i "time.slicing\|replicas\|sharing"

# 部署多个 Pod 测试
for i in $(seq 1 4); do
  kubectl run gpu-test-$i --restart=Never \
    --image=nvidia/cuda:12.3.2-base-ubuntu20.04 \
    --limits=nvidia.com/gpu=1 \
    -- nvidia-smi
done

# 确认都能 Running
kubectl get pods -o wide | grep gpu-test

10.2 MPS

MPS 是 NVIDIA Multi-Process Service。

特点:

适合:

10.3 MIG

MIG 是 Multi-Instance GPU。

特点:

适合:

不适合:

10.4 HAMi

HAMi 提供更细粒度的 GPU 虚拟化和调度。

常见资源写法类似:

resources:
  limits:
    nvidia.com/gpu: 1
    nvidia.com/gpumem: 3000

也可能用百分比方式:

resources:
  limits:
    nvidia.com/gpu: 1
    nvidia.com/gpumem-percentage: 50

以你安装的 HAMi 版本文档为准。

HAMi 适合:

不建议一开始就上 HAMi 的原因:

建议路线:

nvidia-device-plugin 整卡
  ↓
time-slicing / MIG
  ↓
HAMi

11. 监控和可观测性

11.1 你要监控什么

GPU 节点至少要监控:

11.2 DCGM Exporter

NVIDIA DCGM Exporter 可以把 GPU 指标暴露给 Prometheus。

常见指标包括:

如果使用 GPU Operator,通常可以一起部署 DCGM Exporter。

11.3 节点日志

常用:

journalctl -u kubelet -f
journalctl -u containerd -f
journalctl -k | grep -i nvidia
dmesg | grep -i xid

NVIDIA Xid 错误很重要,通常说明驱动或 GPU 层面发生过异常。


12. 常见排障手册

12.1 宿主机 nvidia-smi 不工作

先看:

nvidia-smi
lsmod | grep nvidia
journalctl -k | grep -i nvidia
dmesg | grep -i nvidia

常见原因:

12.2 宿主机正常,但容器里看不到 GPU

先看 containerd runtime:

containerd config dump | grep -A20 -B5 nvidia

看 toolkit:

nvidia-container-cli info

看 Pod:

kubectl describe pod <pod>
kubectl logs <pod>

常见原因:

12.3 K8s 节点没有 nvidia.com/gpu

看 device plugin:

kubectl -n kube-system get pods -o wide | grep nvidia
kubectl -n kube-system logs <nvidia-device-plugin-pod>

看节点:

kubectl describe node <node-name>

常见原因:

12.4 Pod 一直 Pending

查看:

kubectl describe pod <pod>

常见事件:

Insufficient nvidia.com/gpu

原因:

12.5 Pod 启动失败,提示 runtime handler 不存在

类似:

RuntimeHandler "nvidia" not supported

排查:

kubectl get runtimeclass
containerd config dump | grep -A20 -B5 nvidia
systemctl restart containerd
systemctl restart kubelet

原因:

12.6 nvidia-smi 报 NVML 错误

常见错误:

Failed to initialize NVML

排查:

nvidia-smi
ldconfig -p | grep nvidia-ml
journalctl -k | grep -i nvidia

常见原因:


13. 卸载和清理

13.1 原则

不要随便复制网上的卸载命令直接跑。先确认安装方式:

13.2 .run 安装的常见卸载方式

如果用 CUDA .run 安装:

nvidia-uninstall
/usr/local/cuda-*/bin/cuda-uninstaller

路径以实际为准。

13.3 apt 安装的常见卸载方式

先看包:

dpkg -l | grep -E 'nvidia|cuda|cudnn'

再按需卸载:

apt-get remove --purge 'nvidia-*'
apt-get remove --purge 'cuda-*'
apt-get remove --purge 'libcudnn*'
apt-get autoremove -y

13.4 清理 Container Toolkit

apt-get remove --purge nvidia-container-toolkit
systemctl restart containerd

如果你改过 containerd 配置,要确认是否需要回滚 runtime 配置。


14. 生产实践建议

14.1 不要直接在生产节点试命令

建议:

14.2 节点分组

建议用 label 区分:

kubectl label node gpu-a accelerator=nvidia-t4
kubectl label node gpu-b accelerator=nvidia-a10
kubectl label node gpu-c accelerator=nvidia-a100

如果有训练/推理隔离:

kubectl label node gpu-a workload.gpu/usage=inference
kubectl label node gpu-b workload.gpu/usage=training

14.3 驱动版本治理

建议维护一张表:

节点组 GPU 型号 Driver CUDA 镜像基线 device plugin 备注
inference-t4 T4 550.xx CUDA 12.3 v0.19.1 推理
training-a100 A100 550.xx CUDA 12.4 v0.19.1 MIG 可选

14.4 镜像版本治理

不要用:

nvidia/cuda:latest

建议固定:

nvidia/cuda:12.3.2-base-ubuntu20.04

业务镜像也要明确:

14.5 GPU 节点是否跑 CPU Pod

建议:


15. 学习实验清单

你可以按这个清单一点点做。

实验 1:宿主机 GPU 可用

目标:

nvidia-smi

能正常输出。

实验 2:containerd 识别 NVIDIA runtime

目标:

containerd config dump | grep -A20 -B5 nvidia

能看到 nvidia runtime。

实验 3:K8s 识别 GPU

目标:

kubectl get nodes -o custom-columns=NAME:.metadata.name,GPU:.status.allocatable.nvidia\\.com/gpu

能看到 GPU 数量。

实验 4:Pod 使用整张 GPU

目标:

kubectl logs gpu-test

能看到 nvidia-smi 输出。

实验 5:GPU 节点调度控制

目标:

实验 6:监控 GPU

目标:

实验 7:共享方案验证

目标:


16. 一张排障决策树

Pod 用不了 GPU
  ↓
宿主机 nvidia-smi 正常吗?
  ├─ 不正常:先修 Driver / nouveau / kernel module / Secure Boot
  └─ 正常
      ↓
K8s node 上有 nvidia.com/gpu 吗?
  ├─ 没有:查 nvidia-device-plugin / GPU Operator / kubelet
  └─ 有
      ↓
Pod 是否 Pending?
  ├─ 是:查资源名、GPU 数量、nodeSelector、taint/toleration
  └─ 否
      ↓
Pod 是否启动失败?
  ├─ runtime handler 错:查 RuntimeClass 和 containerd runtime
  ├─ NVML/CUDA 错:查 Driver 和容器 CUDA 兼容性
  └─ 业务错误:查框架、模型、显存、权限、镜像依赖

17. 常用命令速查

宿主机

lspci | grep -i nvidia
lsmod | grep -E 'nvidia|nouveau'
nvidia-smi
nvidia-smi -L
journalctl -k | grep -i nvidia
dmesg | grep -i xid

containerd

containerd config dump | grep -A20 -B5 nvidia
systemctl status containerd
journalctl -u containerd -f

Kubernetes

kubectl get runtimeclass
kubectl get nodes
kubectl describe node <node-name>
kubectl get pods -A -o wide | grep -i nvidia
kubectl -n kube-system logs <nvidia-device-plugin-pod>
kubectl describe pod <pod-name>
kubectl logs <pod-name>

GPU 资源

kubectl get nodes -o custom-columns=NAME:.metadata.name,GPU:.status.allocatable.nvidia\\.com/gpu
kubectl describe node <node-name> | grep -A10 -B5 nvidia.com/gpu

18. 推荐参考资料

优先看官方资料:


19. 新手最容易踩的坑

  1. nvidia.com/gpu 写成 nvidia.com/t4
  2. 宿主机 Driver 太旧,容器 CUDA 太新。
  3. 混用 .run 和 apt 安装驱动。
  4. 忘记禁用 nouveau。
  5. 配了 containerd 但没重启。
  6. 创建了 RuntimeClass,但 handler 名字和 containerd 不一致。
  7. GPU Pod 没写 runtimeClassName: nvidia,而默认 runtime 还是 runc
  8. device plugin 没跑起来,却直接排查业务容器。
  9. GPU 节点没有 taint,普通 CPU Pod 占了昂贵节点。
  10. 没有监控温度、功耗、显存和 Xid 错误。

20. 最后给你的学习建议

你已经会 Kubernetes,所以不要从 CUDA 编程开始学。你应该从运维链路开始:

Driver
  → Container Toolkit
  → containerd runtime
  → RuntimeClass
  → nvidia-device-plugin
  → nvidia.com/gpu
  → GPU Pod
  → 监控和排障
  → 共享和高级调度

掌握这条链路后,再去学:

先把一张卡稳定跑起来,再谈共享和复杂调度。这是最稳的学习路径。

k8s kubernetes gpu nvidia hami


正文到此结束
版权声明:若无特殊注明,本文皆为 Myluzh Blog 原创,转载请保留文章出处。
文章内容:https://itho.cn/k8s/611.html
文章标题:《K8s GPU 指南宝典