使用 Docker 将昇腾 310 NPU 驱动挂载到容器

解读

在国内 AI 推理产线中,华为昇腾 310 是最常见的边缘/数据中心 NPU 之一。面试官问“如何把驱动挂进容器”,并不是简单让你 docker run -v,而是考察你是否能在国产化、离线、安全合规三大场景下,把 Host 侧完整的“驱动+固件+工具链”注入容器,并保证:

  1. 容器内用户态程序能调用 libascendcl.so 等运行时;
  2. 内核态 davinci、 ascend 等 ko** 在 Host 侧正确加载且版本匹配;
  3. 容器重启、热升级、多卡并发时,设备节点权限不漂移
  4. 满足信创要求:非 root 启动、最小镜像、Secrets 不落地

一句话:把“昇腾全家桶”做成可交付、可运维、可审计的容器化方案。

知识点

  1. Ascend 驱动分层
    Host 侧必须装 ascend-driver-{version}.run(含 ko、udev 规则、固件),容器内只需 ascend-toolkitopp 包,做到“Host 管驱动、容器管业务”。
  2. 设备节点
    /dev/davinci*、/dev/davinci_manager、/dev/hisi_hdc、/dev/ascend_*,需 --device 逐一透传,不能用 -v 粗暴映射。
  3. 用户态库路径
    /usr/local/Ascend/driver/lib64:/usr/local/Ascend/driver/lib64:ro
    /usr/local/Ascend/add-ons:/usr/local/Ascend/add-ons:ro
    必须只读挂载,防止容器内升级把 Host 驱动写坏。
  4. udev 与权限
    Host 侧 ascend 安装包已自带 99-ascend.rules,容器内无需 systemd,但需保证 --group-add $(getent group ascendvideo | cut -d: -f3),使非 root 进程拥有 /dev/davinci0 读写权限。
  5. 镜像体积优化
    采用 多阶段构建:第一阶段用 ascend-toolkit 官方 deb 包装出 /usr/local/Ascend;第二阶段用 ubuntu:22.04 最小化拷贝,最终镜像 < 400 MB。
  6. 国产化 CI/CD
    华为 iSula 或 openEuler 22.03 LTS SP2 上构建,禁用国外源;驱动包走 华为企业支持网站(support.huawei.com)离线缓存,符合信创审计。
  7. 故障排查
    容器内 ldd /usr/local/Ascend/driver/lib64/libascendcl.so 查看缺失 .so;
    ascend-dmi 工具需挂载 /sys/class/davinci/davinci0 只读,否则报 “device not found”。

答案

  1. Host 侧一次性安装 ascend-driver-23.0.rc2.run,确保 npu-smi info 能看到 310 卡。
  2. 编写 ascend-runtime 最小镜像(Dockerfile):
    FROM ascend-toolkit:23.0.rc2 AS builder
    RUN apt-get update && \
        apt-get install -y --no-install-recommends ./ascend-toolkit*.deb && \
        rm -rf /var/lib/apt/lists/*
    
    FROM ubuntu:22.04
    COPY --from=builder /usr/local/Ascend /usr/local/Ascend
    ENV LD_LIBRARY_PATH=/usr/local/Ascend/driver/lib64:/usr/local/Ascend/add-ons
    USER 1000:1000
    
  3. 运行容器:
    docker run -it --rm \
      --device /dev/davinci0 \
      --device /dev/davinci_manager \
      --device /dev/hisi_hdc \
      --device /dev/ascend_ctl \
      --group-add $(getent group ascendvideo | cut -d: -f3) \
      -v /usr/local/Ascend/driver/lib64:/usr/local/Ascend/driver/lib64:ro \
      -v /usr/local/Ascend/add-ons:/usr/local/Ascend/add-ons:ro \
      -v /usr/local/Ascend/driver/tools:/usr/local/Ascend/driver/tools:ro \
      -v /sys/class/davinci:/sys/class/davinci:ro \
      ascend-infer:23.0.rc2 \
      ./my_model
    
  4. 验证: 容器内执行 npu-smi infoldd libascendcl.so 无 “not found”,且 /dev/davinci0 权限为 crw-rw---- 1 root ascendvideo,即挂载成功。

拓展思考

  1. 多卡并发
    使用 --device /dev/davinci0 … --device /dev/davinci7 逐一透传,并在 Kubernetes 侧通过 Ascend Device Plugin 做扩展资源调度,避免手写 device 列表。
  2. 热升级零中断
    把 ascend-driver 拆成 ko 层 + 用户态层,ko 走 Host 热补丁(kpatch),用户态层用容器滚动更新,实现“容器升级不重启 Host 驱动”。
  3. 安全合规
    华为 iSula 安全容器(kata-qemu) 中,把 ascend ko 加入 virtio-device 白名单,防止恶意容器通过 davinci_manager 提权;同时把 /usr/local/Ascend/driver/lib64 挂载为 只读 + noexec,防止注入 so 后门。
  4. 国产化替代
    若客户要求完全去 Ubuntu,可把基础镜像换成 openEuler 22.03 LTS SP2,并用 isula-build 在离线环境构建,镜像签名走 rpm-sign + ascend pubkey,满足等保 2.0 三级要求。