从云原生走向 AI 原生:一套面向未来的架构方法论 → 阅读《AI 原生基础设施》

端到端实战:从裸机节点到训练作业

草稿

每一条命令都达到生产可用。这一章是全书的“接线图”,把软件栈、设备插件、Operator、NUMA 与监控串成一条时间线。

环境

项目
节点 OSUbuntu 24.04 LTS
GPU1× NVIDIA H100 80GB SXM5(DGX H100 节点)
Kubernetesv1.34(DRA GA)
GPU Operatorv26.3.0
NVIDIA 驱动目标570.x(由 GPU Operator 管理)
容器运行时containerd v2.0
表 1: 实战环境

第 1 步:准备节点(K8s 之前)

# 在 GPU 节点上(纯净 OS,尚未装驱动)
sudo apt-get update
sudo apt-get install -y curl apt-transport-https ca-certificates gnupg lsb-release

# 安装 containerd
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor \
  -o /etc/apt/keyrings/docker.gpg
echo "deb [arch=amd64 signed-by=/etc/apt/keyrings/docker.gpg] \
  https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" \
  | sudo tee /etc/apt/sources.list.d/docker.list
sudo apt-get update && sudo apt-get install -y containerd.io

# 配置 containerd
sudo containerd config default | sudo tee /etc/containerd/config.toml
sudo sed -i 's/SystemdCgroup = false/SystemdCgroup = true/' /etc/containerd/config.toml
sudo systemctl restart containerd

# 加入集群
sudo kubeadm join <control-plane-ip>:6443 --token <token> \
  --discovery-token-ca-cert-hash sha256:<hash>

# 此刻:节点在集群里,但没有 GPU 支持
kubectl describe node gpu-node-01 | grep 'nvidia.com'
# GPU 对 Kubernetes 不可见

第 2 步:部署 GPU Operator

# 在控制平面 / 管理机上
curl -fsSL https://raw.githubusercontent.com/helm/helm/master/scripts/get-helm-3 | bash
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.0 \
  --set driver.enabled=true \
  --set driver.version='570.86.10' \
  --set toolkit.enabled=true \
  --set devicePlugin.enabled=true \
  --set dcgmExporter.enabled=true \
  --set dcgmExporter.serviceMonitor.enabled=true \
  --set migManager.enabled=true \
  --set nfd.enabled=true \
  --set gfd.enabled=true

第 3 步:观察自举顺序

watch kubectl get pods -n gpu-operator
# 预期顺序(与 GPU Operator 章的八步对应):
# 1. node-feature-discovery 启动 → 打 OS/内核标签
# 2. nvidia-driver-daemonset 启动 → 编译并加载 nvidia.ko(首次 2–5 分钟)
# 3. nvidia-container-toolkit 启动 → 配置 containerd
# 4. gpu-feature-discovery 启动 → 打 GPU 型号标签
# 5. nvidia-device-plugin 启动 → 注册 nvidia.com/gpu
# 6. nvidia-dcgm-exporter 启动 → 暴露指标
# 7. nvidia-mig-manager 启动 → 管理 MIG(空闲)
# 8. nvidia-operator-validator 启动 → CUDA 冒烟测试

kubectl describe node gpu-node-01 | grep -A3 'Allocatable'
# Allocatable:
#   nvidia.com/gpu: 1    ← 成功!GPU 已注册

第 4 步:运行 GPU 验证 Pod

kubectl run nvidia-smi-test \
  --image=nvcr.io/nvidia/cuda:12.6.0-base-ubuntu22.04 \
  --restart=Never \
  --limits='nvidia.com/gpu=1' \
  -- nvidia-smi

kubectl logs nvidia-smi-test
# +---------------------------------------------------------------------+
# | NVIDIA-SMI 570.86.10   Driver Version: 570.86.10   CUDA Version: 13.1|
# +-------+---------------------+------+------+------------------------+
# |   0   | NVIDIA H100 80GB HBM3     On    | 00000000:1E:00.0        |
# +-------+---------------------+------+------+------------------------+
# | 30W / 700W | 1023MiB / 81920MiB | 0%   Default                  |
# +---------------------------------------------------------------------+

kubectl delete pod nvidia-smi-test

第 5 步:配置 NUMA 感知调度

# 在 GPU 节点上配置 kubelet
sudo tee -a /var/lib/kubelet/config.yaml << 'EOF'
cpuManagerPolicy: static
topologyManagerPolicy: single-numa-node
topologyManagerScope: pod
memoryManagerPolicy: Static
reservedMemory:
- numaNode: 0
  limits:
    memory: 4Gi
EOF

# 策略变更后必须清理管理器状态
sudo systemctl stop kubelet
sudo rm -f /var/lib/kubelet/cpu_manager_state
sudo rm -f /var/lib/kubelet/memory_manager_state
sudo systemctl start kubelet

sudo journalctl -u kubelet | grep -i topology
# 'topology manager policy: single-numa-node'

第 6 步:运行分布式训练作业

---
apiVersion: batch/v1
kind: Job
metadata:
  name: pytorch-training
  namespace: ml-team
spec:
  template:
    spec:
      restartPolicy: Never
      nodeSelector:
        nvidia.com/gpu.product: NVIDIA-H100-80GB-HBM3
      tolerations:
      - key: nvidia.com/gpu
        operator: Exists
        effect: NoSchedule
      containers:
      - name: trainer
        image: nvcr.io/nvidia/pytorch:25.03-py3
        command:
        - python
        - -c
        - |
          import torch
          print(f'CUDA available: {torch.cuda.is_available()}')
          print(f'GPU count: {torch.cuda.device_count()}')
          print(f'GPU name: {torch.cuda.get_device_name(0)}')
          x = torch.randn(4096, 4096, device='cuda')
          y = torch.mm(x, x)
          print(f'MatMul result shape: {y.shape} -- GPU compute verified!')
        resources:
          limits:
            nvidia.com/gpu: '1'
            memory: 64Gi
            cpu: '16'
          requests:
            nvidia.com/gpu: '1'
            memory: 64Gi
            cpu: '16'
        env:
        - name: NCCL_DEBUG
          value: INFO
        - name: CUDA_VISIBLE_DEVICES
          value: '0'

第 7 步:用 DCGM 监控

kubectl get svc -n gpu-operator | grep dcgm
# nvidia-dcgm-exporter   ClusterIP   10.96.xxx.xxx   9400/TCP

kubectl port-forward svc/nvidia-dcgm-exporter 9400:9400 -n gpu-operator &
curl -s localhost:9400/metrics | grep DCGM_FI_DEV_GPU_UTIL
# DCGM_FI_DEV_GPU_UTIL{gpu='0',UUID='GPU-xxxx',...} 87.0

# 训练期间的关键指标(口径详见“可观测”部分):
# DCGM_FI_DEV_GPU_UTIL      -> 活跃 matmul 期间应为 85-99%
# DCGM_FI_DEV_MEM_COPY_UTIL -> 数据加载期间升高
# DCGM_FI_DEV_FB_USED       -> 显存占用(警惕逼近上限的 OOM)
# DCGM_FI_DEV_POWER_USAGE   -> H100 SXM 满载应为 600-700W
# DCGM_FI_DEV_GPU_TEMP      -> 满载通常 65-80°C(健康)
# DCGM_FI_DEV_XID_ERRORS    -> 必须为 0,非零立即排查
# DCGM_FI_DEV_SM_CLOCK      -> 应处于加速频率(H100 约 1800 MHz)

# GPU 健康诊断
kubectl exec -n gpu-operator -it nvidia-dcgm-exporter-xxxxx -- dcgmi diag -r 1
# -r 1 短诊断(30 秒)/ -r 2 中等(90 秒)/ -r 3 完整 burn-in(约 10 分钟)

总结

七步走完,恰好对应全书的机制链条:容器运行时与驱动(软件栈)→ 设备注册(设备模型)→ Operator 自举(GPU Operator)→ 拓扑对齐(NUMA)→ 负载(工作负载)→ 验收(可观测)。把这套流程套进实施顺序的阶段 1–3,就是一台 GPU 节点从上架到生产的完整剧本。

创建于 2026/08/30 更新于 2026/08/30 1135 字 阅读约 3 分钟