昇腾NPU Kubernetes集成实战:Device Plugin、资源调度与Prometheus监控
详解华为昇腾NPU在Kubernetes中的完整集成方案:Ascend Device Plugin安装与配置、NPU资源调度(单卡/多卡/虚拟化vNPU)、NPU Exporter接入Prometheus监控、MindX DL训练任务调度、NPU隔离与健康检查,以及常见调度问题排查。
将昇腾 NPU 集成到 Kubernetes 集群,需要安装 Device Plugin(让 K8s 发现和调度 NPU 资源)、配置监控(NPU Exporter + Prometheus),以及处理昇腾特有的资源模型(Chip 级别的资源隔离)。本文覆盖完整的集成流程。
昇腾 K8s 集成架构
Kubernetes API Server
↓
Scheduler(调度器)
↓ 分配 NPU 资源
kubelet(节点代理)
↓ 通过 Device Plugin API
Ascend Device Plugin(DaemonSet)
↓ 管理和分配设备
NPU 硬件(/dev/davinci0, /dev/davinci1, ...)
监控链路:
NPU 硬件 → NPU Exporter → Prometheus → Grafana
一、安装 Ascend Device Plugin
准备工作
# 1. 确保所有节点已安装驱动和 CANN
# 2. 打 NPU 节点标签
kubectl label node gpu-node-01 accelerator=huawei-npu
kubectl label node gpu-node-02 accelerator=huawei-npu
# 3. 查看节点 NPU 信息(安装 Device Plugin 前,K8s 不认识 NPU)
kubectl describe node gpu-node-01 | grep -A5 "Capacity"
# 安装前:只显示 cpu/memory/pods 等标准资源
安装 Device Plugin
# 华为官方 Device Plugin(MindX DL 组件)
# 下载地址:https://gitee.com/ascend/ascend-device-plugin
# ascend-device-plugin.yaml
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: ascend-device-plugin
namespace: kube-system
spec:
selector:
matchLabels:
name: ascend-device-plugin
template:
metadata:
labels:
name: ascend-device-plugin
spec:
nodeSelector:
accelerator: huawei-npu # 只在昇腾节点部署
tolerations:
- key: "npu.huawei.com"
operator: "Exists"
effect: "NoSchedule"
hostNetwork: true
hostPID: true
containers:
- name: device-plugin
image: ascend-device-plugin:latest
imagePullPolicy: Never # 使用本地镜像
command: ["/usr/local/bin/ascend-device-plugin"]
args:
- "--mode=ascend910" # 910B/910C 使用 ascend910
- "--fdFlag=false"
resources:
limits:
cpu: 500m
memory: 512Mi
securityContext:
privileged: true # 必须特权模式访问 NPU 设备
volumeMounts:
- name: device-plugin
mountPath: /var/lib/kubelet/device-plugins
- name: driver
mountPath: /usr/local/Ascend/driver
readOnly: true
- name: log
mountPath: /var/log/mindx-dl
volumes:
- name: device-plugin
hostPath:
path: /var/lib/kubelet/device-plugins
- name: driver
hostPath:
path: /usr/local/Ascend/driver
- name: log
hostPath:
path: /var/log/mindx-dl
kubectl apply -f ascend-device-plugin.yaml
# 等待 DaemonSet 就绪
kubectl rollout status daemonset/ascend-device-plugin -n kube-system
# 验证:安装后 NPU 资源出现在节点 Capacity 中
kubectl describe node gpu-node-01 | grep -A10 "Capacity"
# Capacity:
# cpu: 128
# huawei.com/Ascend910: 8 ← NPU 资源
# memory: 1056Gi
# pods: 110
二、在 Pod 中使用 NPU
基础单卡 Pod
apiVersion: v1
kind: Pod
metadata:
name: npu-test-pod
spec:
containers:
- name: npu-container
image: ascendai/cann:8.0.RC3-ubuntu22.04-aarch64
command: ["python3", "-c"]
args:
- |
import torch
import torch_npu
print(f"NPU 可用: {torch.npu.is_available()}")
print(f"NPU 数量: {torch.npu.device_count()}")
x = torch.randn(1000, 1000).npu()
print(f"运算成功: {x.shape}")
resources:
limits:
huawei.com/Ascend910: 1 # 申请 1 个 NPU
requests:
huawei.com/Ascend910: 1
volumeMounts:
- name: driver
mountPath: /usr/local/Ascend/driver
readOnly: true
volumes:
- name: driver
hostPath:
path: /usr/local/Ascend/driver
多卡分布式训练 Job
apiVersion: batch/v1
kind: Job
metadata:
name: llm-training-job
spec:
template:
spec:
nodeSelector:
accelerator: huawei-npu
containers:
- name: trainer
image: my-llm-training:v1.0
command:
- "torchrun"
- "--nproc_per_node=8" # 每节点 8 个 NPU
- "--master_addr=$(MASTER_ADDR)"
- "--master_port=29500"
- "train_llm.py"
resources:
limits:
huawei.com/Ascend910: 8 # 申请整机 8 个 NPU
env:
- name: MASTER_ADDR
value: "llm-training-job-0"
- name: ASCEND_VISIBLE_DEVICES
value: "0,1,2,3,4,5,6,7"
volumeMounts:
- name: driver
mountPath: /usr/local/Ascend/driver
readOnly: true
- name: training-data
mountPath: /data
volumes:
- name: driver
hostPath:
path: /usr/local/Ascend/driver
- name: training-data
persistentVolumeClaim:
claimName: training-data-pvc
restartPolicy: OnFailure
三、NPU Exporter + Prometheus 监控
# 安装 NPU Exporter(收集 NPU 指标发送到 Prometheus)
# 下载:https://gitee.com/ascend/ascend-npu-exporter
# npu-exporter-daemonset.yaml
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: npu-exporter
namespace: monitoring
spec:
selector:
matchLabels:
name: npu-exporter
template:
metadata:
labels:
name: npu-exporter
annotations:
prometheus.io/scrape: "true"
prometheus.io/port: "8082"
spec:
nodeSelector:
accelerator: huawei-npu
hostNetwork: true
hostPID: true
containers:
- name: npu-exporter
image: npu-exporter:6.0.RC1
ports:
- containerPort: 8082
name: metrics
command: ["/usr/local/bin/npu-exporter"]
args:
- "-port=8082"
- "-updateTime=5" # 每 5 秒更新一次
- "-logFile=/var/log/npu-exporter/npu-exporter.log"
- "-logLevel=0"
securityContext:
privileged: true
volumeMounts:
- name: log
mountPath: /var/log/npu-exporter
volumes:
- name: log
hostPath:
path: /var/log/npu-exporter
Prometheus 采集配置
# 在 prometheus.yml 中添加
scrape_configs:
- job_name: 'ascend-npu'
kubernetes_sd_configs:
- role: pod
relabel_configs:
- source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_scrape]
action: keep
regex: true
- source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_port]
action: replace
target_label: __address__
regex: (.+)
replacement: ${1}:8082
- source_labels: [__meta_kubernetes_pod_label_name]
action: keep
regex: npu-exporter
关键监控指标
# NPU 利用率(AI Core 使用率)
container_npu_utilization{job="ascend-npu"}
# NPU 显存使用
container_npu_memory_used_bytes{job="ascend-npu"}
# NPU 显存使用率
container_npu_memory_used_bytes / container_npu_memory_total_bytes * 100
# NPU 温度
container_npu_temperature{job="ascend-npu"}
# NPU 功耗
container_npu_power_draw{job="ascend-npu"}
# NPU 健康状态(0=健康,非0=故障)
container_npu_health_status{job="ascend-npu"} != 0
# Grafana 告警:NPU 利用率长期过低(可能任务卡住了)
avg_over_time(container_npu_utilization[10m]) < 5
# 告警:NPU 温度过高
container_npu_temperature > 85
Grafana Dashboard 核心面板
NPU 集群 Dashboard 布局:
第一行(集群概览):
[健康 NPU 数] [故障 NPU 数] [集群平均利用率] [集群总显存使用率]
第二行(节点详情 - 变量下钻):
[各节点 NPU 利用率热力图]
[各节点 NPU 显存使用趋势]
第三行(任务视图):
[每个训练任务的 NPU 利用率(by pod_name)]
[MFU 趋势(模型利用率 = 实际FLOPS / 峰值FLOPS)]
第四行(健康状态):
[NPU 温度趋势] [功耗趋势] [错误计数]
四、NPU 节点污点与调度策略
# 给 NPU 节点打污点(防止普通 Pod 调度到 NPU 节点浪费资源)
kubectl taint node gpu-node-01 npu.huawei.com=:NoSchedule
kubectl taint node gpu-node-02 npu.huawei.com=:NoSchedule
# NPU 任务 Pod 中需要配置容忍(toleration)
tolerations:
- key: "npu.huawei.com"
operator: "Exists"
effect: "NoSchedule"
# 使用 NodeAffinity 实现 NPU 任务调度到特定节点池
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: accelerator
operator: In
values:
- huawei-npu
- key: npu-model
operator: In
values:
- 910b # 只调度到 910B 节点(区分 910B 和 910C)
五、常见问题排查
# 问题1:Pod 一直 Pending,NPU 资源不足
kubectl describe pod <pod-name>
# Events: 0/3 nodes are available: 3 Insufficient huawei.com/Ascend910
# 解决:检查节点 NPU 资源是否被其他 Pod 占用
kubectl get pods --all-namespaces -o custom-columns="NAME:.metadata.name,NPU:.spec.containers[*].resources.limits.huawei\.com/Ascend910" | grep -v none
# 问题2:Pod 启动后 NPU 不可用
kubectl exec -it <pod-name> -- npu-smi info
# 如果报错,检查设备文件挂载
kubectl exec -it <pod-name> -- ls /dev/davinci*
# 问题3:Device Plugin 无法发现 NPU
kubectl logs -n kube-system daemonset/ascend-device-plugin
# 常见:驱动未安装或版本不匹配
# 问题4:多卡训练 HCCS 通信失败
# 检查 HCCS 链路
npu-smi info -i 0 -t link-info
# 检查 P2P 通信
python3 -c "
import torch, torch_npu
x = torch.randn(1000).npu(0)
y = x.npu(1) # 跨卡传输测试
print('P2P OK')
"
# 问题5:NPU Exporter 采集不到数据
kubectl logs -n monitoring daemonset/npu-exporter | tail -20
# 检查权限:Exporter 需要特权模式
kubectl get pod -n monitoring -o yaml | grep privileged
小结
昇腾 K8s 集成的关键点:Device Plugin 负责让 K8s 感知和调度 NPU 资源(huawei.com/Ascend910);NPU Exporter 负责将 npu-smi 指标暴露给 Prometheus;Pod 必须以特权模式运行并挂载驱动目录。生产部署建议:NPU 节点统一打污点,训练任务用 Toleration + NodeAffinity 精确调度;Prometheus 告警要覆盖 NPU 温度(>85°C)、健康状态(非0)和利用率长期过低(可能任务阻塞)三个维度。
