跳到主要内容

Kubernetes GPU 调度配置

本指南将详细介绍如何在 Kubernetes 集群中配置和管理 GPU 资源,实现高效的 GPU 调度和利用。

概述​

为什么需要 GPU 调度?​

在 Kubernetes 中使用 GPU 可以:

  • 统一管理 CPU 和 GPU 资源
  • 实现 GPU 资源的隔离和共享
  • 支持多租户环境
  • 提高资源利用率
  • 简化 AI/ML 工作负载部署

GPU 调度方式​

  1. 设备插件(Device Plugin): Kubernetes 原生支持
  2. GPU Operator: NVIDIA 提供的全栈解决方案
  3. 时间切片(Time Slicing): GPU 共享方案
  4. MIG(Multi-Instance GPU): A100/A800 硬件级隔离

前置要求​

硬件要求​

  • NVIDIA GPU(计算能力 7.0+)
  • 支持的 GPU 型号:
    • Tesla V100
    • Tesla T4
    • RTX 2080/3090/4090
    • A100/A800
    • H100/H800

软件要求​

  • Kubernetes 1.20+
  • NVIDIA Driver 450.80.02+
  • NVIDIA Container Toolkit
  • Docker 或 containerd

检查节点 GPU​

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

方式一:使用 NVIDIA GPU Operator(推荐)​

安装 NVIDIA GPU Operator​

1. 添加 Helm 仓库​

helm repo add nvidia https://helm.ngc.nvidia.com/nvidia
helm repo update

2. 安装 Operator​

helm install gpu-operator nvidia/gpu-operator \
--namespace gpu-operator \
--create-namespace \
--set driver.enabled=true \
--set toolkit.enabled=true \
--set devicePlugin.enabled=true \
--set dcgmExporter.enabled=true \
--set migManager.enabled=false

3. 验证安装​

kubectl get pods -n gpu-operator

预期输出:

NAME                                                              READY   STATUS      RESTARTS   AGE
gpu-feature-discovery-4xk9m 1/1 Running 0 5m
gpu-operator-7d8f9c5b4d-x2y3z 1/1 Running 0 5m
nvidia-container-toolkit-daemonset-5m6n7 1/1 Running 0 5m
nvidia-cuda-validator-8k9l0 0/1 Completed 0 4m
nvidia-device-plugin-daemonset-1a2b3 1/1 Running 0 5m
nvidia-driver-daemonset-4c5d6 1/1 Running 0 5m
nvidia-operator-validator-7e8f9 0/1 Completed 0 3m

4. 检查 GPU 资源​

kubectl describe node <node-name> | grep -A 10 "Allocatable:"

配置选项​

禁用驱动自动安装​

如果节点已安装驱动:

helm install gpu-operator nvidia/gpu-operator \
--namespace gpu-operator \
--set driver.enabled=false

配置 MIG​

helm install gpu-operator nvidia/gpu-operator \
--namespace gpu-operator \
--set migManager.enabled=true \
--set mig.strategy=single

方式二:使用 NVIDIA Device Plugin​

安装 NVIDIA Container Toolkit​

Ubuntu/Debian​

distribution=$(. /etc/os-release;echo $ID$VERSION_ID)
curl -s -L https://nvidia.github.io/libnvidia-container/gpgkey | sudo apt-key add -
curl -s -L https://nvidia.github.io/libnvidia-container/$distribution/libnvidia-container.list | \
sudo tee /etc/apt/sources.list.d/nvidia-container-toolkit.list

sudo apt-get update
sudo apt-get install -y nvidia-container-toolkit
sudo nvidia-ctk runtime configure --runtime=docker
sudo systemctl restart docker

CentOS/RHEL​

distribution=$(. /etc/os-release;echo $ID$VERSION_ID)
curl -s -L https://nvidia.github.io/libnvidia-container/$distribution/libnvidia-container.repo | \
sudo tee /etc/yum.repos.d/nvidia-container-toolkit.repo

sudo yum install -y nvidia-container-toolkit
sudo nvidia-ctk runtime configure --runtime=docker
sudo systemctl restart docker

部署 Device Plugin​

1. 创建 DaemonSet​

创建 nvidia-device-plugin.yml:

apiVersion: apps/v1
kind: DaemonSet
metadata:
name: nvidia-device-plugin-daemonset
namespace: kube-system
spec:
selector:
matchLabels:
name: nvidia-device-plugin-ds
updateStrategy:
type: RollingUpdate
template:
metadata:
labels:
name: nvidia-device-plugin-ds
spec:
tolerations:
- key: nvidia.com/gpu
operator: Exists
effect: NoSchedule
containers:
- image: nvcr.io/nvidia/k8s-device-plugin:v0.14.1
name: nvidia-device-plugin-ctr
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop: ["ALL"]
volumeMounts:
- name: device-plugin
mountPath: /var/lib/kubelet/device-plugins
volumes:
- name: device-plugin
hostPath:
path: /var/lib/kubelet/device-plugins

2. 部署插件​

kubectl apply -f nvidia-device-plugin.yml

3. 验证安装​

kubectl get pods -n kube-system | grep nvidia
kubectl describe node <node-name> | grep nvidia.com/gpu

使用 GPU 资源​

基础 Pod 配置​

创建 gpu-pod.yml:

apiVersion: v1
kind: Pod
metadata:
name: gpu-pod
spec:
containers:
- name: cuda-container
image: nvcr.io/nvidia/cuda:12.4.0-base-ubuntu22.04
command: ["nvidia-smi"]
resources:
limits:
nvidia.com/gpu: 1
restartPolicy: Never

部署 Pod:

kubectl apply -f gpu-pod.yml
kubectl logs gpu-pod

Deployment 配置​

apiVersion: apps/v1
kind: Deployment
metadata:
name: gpu-deployment
spec:
replicas: 2
selector:
matchLabels:
app: gpu-app
template:
metadata:
labels:
app: gpu-app
spec:
containers:
- name: gpu-container
image: nvcr.io/nvidia/cuda:12.4.0-base-ubuntu22.04
command: ["python", "train.py"]
resources:
limits:
nvidia.com/gpu: 1
memory: "4Gi"
cpu: "2"
requests:
nvidia.com/gpu: 1
memory: "2Gi"
cpu: "1"

Job 配置​

apiVersion: batch/v1
kind: Job
metadata:
name: gpu-job
spec:
template:
spec:
containers:
- name: gpu-container
image: nvcr.io/nvidia/cuda:12.4.0-base-ubuntu22.04
command: ["python", "train.py"]
resources:
limits:
nvidia.com/gpu: 2
restartPolicy: Never
backoffLimit: 3

GPU 时间切片​

配置时间切片​

创建 time-slicing-config.yml:

apiVersion: v1
kind: ConfigMap
metadata:
name: time-slicing-config
namespace: gpu-operator
data:
config.yaml: |
version: v1
flags:
migStrategy: none
sharing:
timeSlicing:
resources:
- name: nvidia.com/gpu
replicas: 4

应用配置:

kubectl apply -f time-slicing-config.yml

重启 device-plugin:

kubectl rollout restart daemonset nvidia-device-plugin-daemonset -n gpu-operator

使用时间切片 GPU​

apiVersion: v1
kind: Pod
metadata:
name: gpu-pod-slice
spec:
containers:
- name: cuda-container
image: nvcr.io/nvidia/cuda:12.4.0-base-ubuntu22.04
command: ["nvidia-smi"]
resources:
limits:
nvidia.com/gpu: 1

MIG 配置​

启用 MIG​

1. 配置 MIG 策略​

helm install gpu-operator nvidia/gpu-operator \
--namespace gpu-operator \
--set migManager.enabled=true \
--set mig.strategy=mixed

2. 创建 MIG 配置​

创建 mig-config.yml:

apiVersion: v1
kind: ConfigMap
metadata:
name: mig-parted-config
namespace: gpu-operator
data:
config.yaml: |
version: v1
mig-configs:
all-balanced:
- devices: all
mig-enabled: true
mig-devices:
"1g.10gb": 7

3. 应用配置​

kubectl apply -f mig-config.yml
kubectl label node <node-name> nvidia.com/mig.config=all-balanced

使用 MIG 设备​

apiVersion: v1
kind: Pod
metadata:
name: mig-pod
spec:
containers:
- name: cuda-container
image: nvcr.io/nvidia/cuda:12.4.0-base-ubuntu22.04
command: ["nvidia-smi"]
resources:
limits:
nvidia.com/mig-1g.10gb: 1

监控 GPU​

安装 DCGM Exporter​

GPU Operator 默认安装 DCGM Exporter。

配置 ServiceMonitor​

apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
name: dcgm-exporter
namespace: monitoring
spec:
selector:
matchLabels:
app: nvidia-dcgm-exporter
namespaceSelector:
matchNames:
- gpu-operator
endpoints:
- port: metrics
interval: 30s

Prometheus 指标​

常用 GPU 指标:

# GPU 利用率
DCGM_FI_DEV_GPU_UTIL

# GPU 内存使用
DCGM_FI_DEV_FB_USED
DCGM_FI_DEV_FB_FREE

# GPU 温度
DCGM_FI_DEV_GPU_TEMP

# GPU 功耗
DCGM_FI_DEV_POWER_USAGE

# GPU SM 时钟频率
DCGM_FI_DEV_SM_CLOCK

Grafana 仪表板​

导入 NVIDIA 官方仪表板:Dashboard ID: 12239

故障排查​

常见问题​

1. GPU 资源不可见​

问题: kubectl describe node 不显示 GPU 资源

解决方案:

kubectl get pods -n gpu-operator
kubectl logs -n gpu-operator <nvidia-device-plugin-pod>
nvidia-smi

2. Pod 无法调度​

问题: Pod 一直处于 Pending 状态

解决方案:

kubectl describe pod <pod-name>
kubectl get nodes -o custom-columns=NAME:.metadata.name,GPU:.status.capacity.'nvidia\.com/gpu'

3. GPU 驱动版本不匹配​

问题: 驱动版本与 CUDA 版本不兼容

解决方案:

nvidia-smi
kubectl exec -it <gpu-pod> -- nvidia-smi

4. 容器无法访问 GPU​

问题: 容器内 nvidia-smi 失败

解决方案:

kubectl describe pod <pod-name>
docker run --gpus all nvidia/cuda:12.4.0-base-ubuntu22.04 nvidia-smi

日志查看​

kubectl logs -n gpu-operator <nvidia-device-plugin-pod>
kubectl logs -n gpu-operator <nvidia-driver-daemonset-pod>
journalctl -u kubelet -f

最佳实践​

1. 资源规划​

  • 合理设置 GPU 资源请求和限制
  • 使用节点选择器和污点容忍
  • 实现多租户资源隔离

2. 性能优化​

  • 使用 GPU 时间切片提高利用率
  • 配置 MIG 实现硬件级隔离
  • 监控 GPU 使用情况

3. 高可用部署​

  • 多节点部署避免单点故障
  • 配置 Pod 反亲和性
  • 实现自动故障恢复

4. 安全加固​

  • 限制 GPU 访问权限
  • 使用命名空间隔离
  • 配置网络策略

参考资料​

官方文档​

相关教程​


提示

生产环境建议使用 GPU Operator,它提供了完整的 GPU 管理解决方案。

信息

本指南基于 Kubernetes 1.28 和 NVIDIA GPU Operator v23.9 编写,不同版本配置可能略有差异。