LabHub

博客

NVIDIA GPU Operator 完全指南 — 从安装部署到 MIG 分区配置

한국어English日本語中文

引言 — 摆脱 GPU 节点搭建的地狱

在 Kubernetes 集群里手动接入过 GPU 节点的人都懂。要把 NVIDIA 驱动装成和内核版本匹配的版本,装上 container toolkit,改运行时配置,部署设备插件,再接上监控 exporter——这五层的版本适配只要有一层没对上,Pod 就看不到 GPU。节点有 10 台,这套动作就要做 10 遍;内核一升级,又得从头再来。

NVIDIA GPU Operator 用 Kubernetes 的 Operator 模式把这整套栈自动化了。管理员只需安装一个 Helm Chart,声明期望状态,Operator 就会把各个节点所需的组件以容器形式部署上去,并持续 reconcile。本文将从安装、验证,一路讲到 A100/H100 级 GPU 的杀手级功能——MIG(Multi-Instance GPU)分区配置——全程配合实际命令。如果需要先补一下 Kubernetes 基础,也可以先去本站的 Kubernetes 游乐场找找感觉。

GPU Operator 部署了什么

安装 Operator 之后,gpu-operator 命名空间下会以 DaemonSet 的形式部署以下这些 operand。每一个都对应着手动搭建时代里手工做的一件事。

安装 — 一个 Helm Chart 搞定

前提条件有三个:装有 NVIDIA GPU 的节点、受支持的容器运行时(containerd 等),以及 Node Feature Discovery(Operator 默认会一并安装)。

# 1) 添加 NVIDIA Helm 仓库
helm repo add nvidia https://helm.ngc.nvidia.com/nvidia
helm repo update

# 2) 安装(版本请以官方文档最新为准 —— 本文写作时为 v26.3.3)
helm install --wait gpu-operator \
  -n gpu-operator --create-namespace \
  nvidia/gpu-operator \
  --version=v26.3.3

根据环境不同,常见的两种变体:

# 如果节点上已经装好驱动(DGX OS、手动安装等场景)
helm install --wait gpu-operator \
  -n gpu-operator --create-namespace \
  nvidia/gpu-operator \
  --version=v26.3.3 \
  --set driver.enabled=false

# 如果 container toolkit 也已经装好,再加上:
#   --set toolkit.enabled=false

确认安装状态:

kubectl get pods -n gpu-operator
# driver-daemonset、container-toolkit、device-plugin、dcgm-exporter、
# gpu-feature-discovery、operator-validator 全部为 Running/Completed 即正常

验证 — Pod 里能看到 GPU 吗

最可靠的验证方式,是用一个申请 GPU 的测试 Pod。

apiVersion: v1
kind: Pod
metadata:
  name: gpu-smoke-test
spec:
  restartPolicy: Never
  containers:
    - name: nvidia-smi
      image: nvidia/cuda:12.4.1-base-ubuntu22.04
      command: ['nvidia-smi']
      resources:
        limits:
          nvidia.com/gpu: 1
kubectl apply -f gpu-smoke-test.yaml
kubectl logs gpu-smoke-test
# nvidia-smi 输出里能看到 GPU 型号即成功

顺便确认一下 GFD 打上的节点标签,写节点选择器时会用得上:

kubectl get node <节点名> -o jsonpath='{.metadata.labels}' | jq . | grep nvidia
# nvidia.com/gpu.product、nvidia.com/gpu.memory、nvidia.com/gpu.count 等

MIG — 在硬件层面切分一张 GPU

像 A100/H100 这样的数据中心 GPU,单卡往往太大了。一个小型推理负载独占一张 80GB 的 GPU,剩下的容量就白白闲置。MIG(Multi-Instance GPU)是从 Ampere 世代开始支持的功能,能把一张 GPU 最多切分成 7 个硬件隔离的实例

关键在于"硬件隔离"。每个 MIG 实例都会物理分配到属于自己的一份 SM(计算单元)、L2 缓存和显存带宽。这正是它和时分复用(time-slicing)的决定性区别——时分复用是多个 Pod 轮流使用同一张 GPU,所以一个 Pod 的突发负载会波及另一个 Pod 的延迟;而 MIG 无论邻居实例在做什么,自己的性能都有保证。这也是多租户集群、推理服务、按团队分配 GPU 场景偏爱 MIG 的原因。

Profile 名称遵循 <GI 数量>g.<显存>gb 的格式。比如一张 H100 80GB,典型的切分方式是这样:

Profile       实例数(最多)     大致用途
1g.10gb   ×7                7 个小型推理
2g.20gb   ×3                3 个中型推理/实验
3g.40gb   ×2                2 个中大型训练
7g.80gb   ×1                不切分,整卡使用
(也可以混合:例如 3g.40gb 1 个 + 2g.20gb 1 个 + 1g.10gb 2 个)

A100 40GB 也是同样的原理,会变成 1g.5gb×7、2g.10gb×3、3g.20gb×2……。具体的组合规则因 GPU 型号而异,请以 NVIDIA MIG 用户指南里的 Profile 表为准。

MIG 策略 — single vs mixed

要在 GPU Operator 里使用 MIG,首先得在安装时定好 策略(strategy)。这个选择会改变资源向 Kubernetes 广播的方式。

# 以 single 策略安装
helm install --wait gpu-operator \
  -n gpu-operator --create-namespace \
  nvidia/gpu-operator \
  --version=v26.3.3 \
  --set mig.strategy=single

# 如果是像 GKE/EKS 这类需要重启的云环境,再加上:
#   --set migManager.env[0].name=WITH_REBOOT \
#   --set-string migManager.env[0].value=true

如果只想在已安装的集群上改变策略,可以 patch ClusterPolicy:

kubectl patch clusterpolicies.nvidia.com/cluster-policy \
  --type='json' \
  -p='[{"op":"replace", "path":"/spec/mig/strategy", "value":"mixed"}]'

应用 MIG — 一个节点标签搞定

MIG Manager 的工作原理简单得优雅:监听 nvidia.com/mig.config 节点标签,标签一变,就把对应的 Profile 应用到硬件上

# 把一台 H100 节点切分成 7 个 1g.10gb
kubectl label nodes <节点名> nvidia.com/mig.config=all-1g.10gb --overwrite

内置的 Profile 包括 all-disabled(关闭 MIG)、all-1g.10gball-2g.20gball-3g.40gball-balanced(多种尺寸均衡混合)等。应用过程可以通过标签追踪:

kubectl get node <节点名> -o jsonpath='{.metadata.labels}' | jq . | grep mig
# nvidia.com/mig.config.state 依次经过
#   pending → (如有需要则 rebooting) → success 即完成

success 之后确认资源,就能看到切分结果:

kubectl describe node <节点名> | grep -A5 'Allocatable'
# single 策略: nvidia.com/gpu: 7 (标签中的 gpu.product 会显示 MIG-1g.10gb)
# mixed  策略: nvidia.com/mig-1g.10gb: 7 这样按 Profile 划分的资源

在 mixed 策略下,Pod 会像这样指定具体 Profile:

resources:
  limits:
    nvidia.com/mig-1g.10gb: 1

自定义 Profile — 在一张卡内混合尺寸

如果内置 Profile 不够用(比如"只有 0 号 GPU 需要 3g+1g+1g 混合,其余关闭 MIG"),可以用 ConfigMap 直接定义。

apiVersion: v1
kind: ConfigMap
metadata:
  name: custom-mig-config
  namespace: gpu-operator
data:
  config.yaml: |
    version: v1
    mig-configs:
      all-disabled:
        - devices: all
          mig-enabled: false
      inference-mix:
        - devices: [0]
          mig-enabled: true
          mig-devices:
            "1g.10gb": 5
            "2g.20gb": 1
        - devices: [1, 2, 3]
          mig-enabled: false
# 让 MIG Manager 使用这个 ConfigMap,需要 patch ClusterPolicy
kubectl patch clusterpolicies.nvidia.com/cluster-policy \
  --type='json' \
  -p='[{"op":"replace", "path":"/spec/migManager/config/name", "value":"custom-mig-config"}]'

# 把自定义 Profile 应用到节点
kubectl label nodes <节点名> nvidia.com/mig.config=inference-mix --overwrite

另外,从 v26.3.0 开始,MIG Manager 会在启动时通过 NVML 查询节点硬件,在运行时自动生成可用的 Profile 列表,并写成每个节点各自的 ConfigMap。这样一来,新的 GPU 型号发布后,也不用再等内置 Profile 列表更新了。

运维注意事项 — 提前知道就不算故障

结语

GPU Operator 把"搭建 GPU 节点"这项重复劳动变成了一个声明式资源,MIG Manager 又在此基础上让昂贵 GPU 的利用率问题只靠一行标签就能处理。归纳一下:用 Helm 安装,定策略(single/mixed),用 nvidia.com/mig.config 标签分区,用 mig.config.state 确认,用 DCGM 观察——这五句话就是全部。剩下的,就是为你自己的负载找到合适的 Profile,而这件事,监控数据会告诉你答案。

如果想顺便打牢 Linux 和 Kubernetes 的基础,也可以用一下 Linux 终端Kubestronaut 测验

参考资料

评论

还没有评论。

登录后即可发表评论