如何为国产 GPU 构建最小基础镜像
解读
面试官想知道三件事:
- 你是否理解国产 GPU(寒武纪 MLU、华为 Ascend、天数智芯、沐曦、壁仞、景嘉微 等)与 NVIDIA 在驱动、运行时、编译链上的差异;
- 能否用 Docker 多阶段构建把 驱动库、用户态运行时、算子库、业务二进制 分层打薄,做出 <100 MB 的交付件;
- 是否熟悉国内镜像源、合规要求(国密算法、等保、信创名录)以及 CI 流水线中的签名、扫描、缓存策略。
回答时要体现“最小”“可维护”“可复现”三大关键词,并给出可落地的 Dockerfile 片段与验证步骤。
知识点
- 国产 GPU 驱动形态:KO 文件 + 用户态 .so,多数提供 dkms 包 或 容器化驱动注入 方案,需确认宿主机内核版本与驱动 ABI 兼容性。
- 多阶段构建:用
FROM scratch或FROM 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。
答案
-
选定基础层
国产 GPU 厂商已提供 最小运行时包,例如华为 Ascend 的ascend-runtime-23.0-ubuntu20.04-minimal.tar.gz(仅 42 MB),优先采用官方包而非完整 SDK。 -
多阶段 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"]
- 构建与验证
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
- 推送与合规
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.so与libcnml.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 上启动失败。