如何为国产 GPU 构建最小基础镜像

解读

面试官想知道三件事:

  1. 你是否理解国产 GPU(寒武纪 MLU、华为 Ascend、天数智芯、沐曦、壁仞、景嘉微 等)与 NVIDIA 在驱动、运行时、编译链上的差异;
  2. 能否用 Docker 多阶段构建把 驱动库、用户态运行时、算子库、业务二进制 分层打薄,做出 <100 MB 的交付件;
  3. 是否熟悉国内镜像源、合规要求(国密算法、等保、信创名录)以及 CI 流水线中的签名、扫描、缓存策略。
    回答时要体现“最小”“可维护”“可复现”三大关键词,并给出可落地的 Dockerfile 片段与验证步骤。

知识点

  • 国产 GPU 驱动形态:KO 文件 + 用户态 .so,多数提供 dkms 包容器化驱动注入 方案,需确认宿主机内核版本与驱动 ABI 兼容性。
  • 多阶段构建:用 FROM scratchFROM gcr.io/distroless/static 作终态,前一阶段用 官方 SDK 镜像(如 ascend-toolkit:23.0.RC2-ubuntu20.04)完成编译、裁剪。
  • ldd 裁剪ldd bin/xxx | awk '{print $3}' | grep -v '^(' | xargs -I {} cp --parents {} /rootfs 配合 chrpath -d 删除 RPATH,减少 30% 体积。
  • 国内源加速sed -i 's@http://.*.ubuntu.com@http://mirrors.aliyun.com@g' /etc/apt/sources.list,CI 中缓存 /var/cache/apt 层。
  • 安全加固:非 root 用户(USER 65534:65534)、只读根文件系统、--security-opt no-new-privileges、把 设备节点 /dev/davinci 通过 --device 挂载* 而非 COPY。
  • 合规签名:使用 Harbor 国产版(v2.8+)+ cosign 国密 SM2 签名,镜像扫描用 trivy --security-checks secret,config 并输出 SBOM。
  • 验证命令docker run --rm --gpus ascend -e ASCEND_VISIBLE_DEVICES=0 minimal-mlu:latest /app/vectoradd 返回 PASS 且 docker images 显示 <80 MB。

答案

  1. 选定基础层
    国产 GPU 厂商已提供 最小运行时包,例如华为 Ascend 的 ascend-runtime-23.0-ubuntu20.04-minimal.tar.gz(仅 42 MB),优先采用官方包而非完整 SDK。

  2. 多阶段 Dockerfile(以 Ascend 为例,可类比寒武纪 CNML)

# 阶段 1:编译与收集依赖
FROM ascend-toolkit:23.0.RC2-ubuntu20.04 AS builder
WORKDIR /build
COPY src/vectoradd.cpp .
RUN g++ -O3 -std=c++17 vectoradd.cpp -o vectoradd \
    -I/usr/local/Ascend/ascend-toolkit/latest/acllib/include \
    -L/usr/local/Ascend/ascend-toolkit/latest/acllib/lib64 \
    -lascendcl --static-libgcc --static-libstdc++ && \
    mkdir -p /rootfs/lib /rootfs/lib64 /rootfs/usr/bin && \
    ldd vectoradd | awk '{print $3}' | grep -v '^(' | xargs -I {} cp -L {} /rootfs/lib64/ && \
    cp vectoradd /rootfs/usr/bin/ && \
    cp -L /usr/local/Ascend/ascend-toolkit/latest/acllib/lib64/libascendcl.so* /rootfs/lib64/

# 阶段 2:组装最小镜像
FROM scratch
COPY --from=builder /rootfs /
# 创建非 root 用户
COPY --chown=65534:65534 --from=builder /etc/passwd /etc/passwd
USER 65534:65534
ENTRYPOINT ["/usr/bin/vectoradd"]
  1. 构建与验证
docker build -t minimal-ascend:1.0 .
# 体积 78 MB
docker images | grep minimal
# 功能验证
docker run --rm --device /dev/davinci_manager --device /dev/davinci0 \
           -v /usr/local/Ascend/driver/lib64:/usr/local/Ascend/driver/lib64:ro \
           minimal-ascend:1.0
# 输出 Test PASSED
  1. 推送与合规
docker tag minimal-ascend:1.0 registry.cn-shanghai.aliyuncs.com/ascend/minimal:1.0
cosign sign --key sm2://hash key registry.cn-shanghai.aliyuncs.com/ascend/minimal:1.0

拓展思考

  • 寒武纪 MLU 采用 CNRT+CNML 双库,可把 libcnrt.solibcnml.so 合并为单一 libmluops.so 并通过 strip --strip-unneeded 再省 15 MB。
  • 若宿主机已加载 dkms 驱动,可把 /dev/cambricon_* 通过 --device 挂载,镜像内无需包含 KO,实现“驱动与业务彻底解耦”。
  • 对于 壁仞 BR100 等 PCIe 型 GPU,需额外挂载 /sys/class/drm/sys/kernel/debug 进行温度监控,镜像体积仍可控在 90 MB 以内。
  • 信创 ARM64+麒麟 V10 场景,需把 FROM 换成 kylin10-minimal:arm64 并交叉编译,注意 libnuma.so.1 必须静态链接,否则容器在鲲鹏 920 上启动失败。