在 Jetson Orin 上使用 Docker 调用 CUDA 11.8

解读

Jetson Orin 是ARM64 架构的边缘 AI 计算设备,GPU 驱动与 x86 完全不同,CUDA 11.8 需要JetPack 5.1 及以上版本的底层 BSP 支持。面试官想确认候选人是否理解:

  1. Jetson 的 GPU 驱动是内核模块,宿主机必须先行安装,容器内无法独立安装驱动;
  2. nvidia-docker2 在 Jetson 上不可用,需使用NVIDIA Container Runtime for L4T
  3. 镜像必须基于l4t-cuda系列基础镜像,否则会出现glibc、driver API 版本不匹配
  4. 需要把宿主机字符设备 /dev/nvhost-*、/dev/nvmap、/dev/nvgpu 挂载进容器,并打开ipc=hostprivileged细粒度 capability
  5. 最终要能在容器里运行deviceQuerynvidia-smi(Jetson 版)验证 CUDA 11.8 可用,并给出多阶段构建运行时体积优化方案。

知识点

  • JetPack、L4T、CUDA for Tegra 版本三角依赖
  • ARM64 镜像仓库拉取策略(国内常用nvcr.io、registry.cn-hangzhou.aliyuncs.com镜像加速)
  • NVIDIA Container Runtime for L4Tdocker --runtime nvidia参数
  • cgroup v1/v2 在 Jetson 上的差异privileged 的替代方案(--cap-add=SYS_RAWIO,--device=/dev/nvhost-gpu 等)
  • 多阶段构建减少 Jetson 存储占用(从 4 GB 压缩到 800 MB
  • 非 root 用户运行 CUDA 程序udev 规则与 supplementary group 配置
  • 国内网络下 apt、pip 换清华源避免构建超时
  • 容器内编译 TensorRT 插件时的交叉编译链与 cmake -DCMAKE_CUDA_ARCHITECTURES=87

答案

  1. 宿主机准备
    ① 刷 JetPack 5.1.2,确认uname -aLinux 5.10.104-tegracat /etc/nv_tegra_release显示R35.3.1
    ② 安装 NVIDIA Container Runtime for L4T:

    sudo apt update
    sudo apt install nvidia-container nvidia-l4t-cuda
    sudo systemctl restart docker
    

    验证:docker info | grep nvidia出现Runtimes: nvidia

  2. 镜像选择
    国内拉取加速:

    docker pull registry.cn-hangzhou.aliyuncs.com/nvidia/l4t-cuda:11.8.0-runtime
    

    该镜像已包含libcudart.so.11.8aarch64驱动 stub,体积 1.2 GB。

  3. 运行容器

    docker run -it --rm \
      --runtime nvidia \
      --ipc=host \
      --pid=host \
      --privileged \
      -v /dev:/dev \
      -v /tmp/.X11-unix:/tmp/.X11-unix:rw \
      registry.cn-hangzhou.aliyuncs.com/nvidia/l4t-cuda:11.8.0-runtime \
      bash -c "nvidia-smi && /usr/local/cuda/samples/1_Utilities/deviceQuery/deviceQuery"
    

    预期输出:Detected 1 CUDA Capable device(s) ... CUDA Driver 11.8 / Runtime 11.8

  4. 多阶段构建示例(Dockerfile)

    # 阶段1:编译环境
    FROM registry.cn-hangzhou.aliyuncs.com/nvidia/l4t-cuda:11.8.0-devel as builder
    WORKDIR /src
    COPY app.cu .
    RUN nvcc -arch=sm_87 -O3 app.cu -o app
    
    # 阶段2:最小运行时
    FROM registry.cn-hangzhou.aliyuncs.com/nvidia/l4t-cuda:11.8.0-runtime
    COPY --from=builder /src/app /usr/local/bin/
    RUN useradd -m -u 1000 ai && usermod -a -G video,ai ai
    USER ai
    ENTRYPOINT ["app"]
    

    构建命令:

    docker buildx build --platform linux/arm64 -t my/cuda118-orin:1.0 .
    

    最终镜像 780 MB,比 devel 镜像减少 70%

  5. 常见问题排查

    • cudaGetDeviceCount returned 35 -> CUDA driver version is insufficient:宿主机 JetPack 版本低于 5.1,需重刷。
    • libnvidia-ml.so.1 not found:忘记加**--runtime nvidia**。
    • apt update 卡住:在 Dockerfile 首行加RUN sed -i 's|http://ports.ubuntu.com|https://mirrors.tuna.tsinghua.edu.cn|g' /etc/apt/sources.list

拓展思考

  1. 如何在 K3s 上通过 Device-Plugin 把 Jetson Orin GPU 暴露给 Pod?
    需部署nvidia-device-plugin-l4t DaemonSet,并在 Pod spec 中声明resources.limits.nvidia.com/gpu: 1,同时把runtimeClassName=nvidia写入 Pod 模板。

  2. 若业务需要 CUDA 12.x,但官方尚未发布对应 L4T 镜像,如何自救?
    可基于l4t-base镜像,手动安装cuda-toolkit-12-0aarch64 runfile,但需保证宿主机r535+ 驱动提前刷入,且libcudart.solibcuda.so版本一致;否则需用LD_LIBRARY_PATH隔离,风险高,生产慎用。

  3. 国内量产场景下,如何做到“离线交付”?
    预先把l4t-cuda:11.8.0-runtime镜像导出为tar.gzdocker save | pigz > cuda118.tar.gz),随 OTA 包下发;设备端docker load后,通过systemd-docker启动,全程无公网,满足电力内网车规产线要求。

  4. 安全加固
    用**--security-opt=no-new-privileges替代--privileged**,通过**--device-cgroup-rule='c 195:* rwm'细粒度开放 GPU 字符设备;配合seccomp=jetson-orin-profile.json**,把 41 条系统调用黑名单化,满足国内等保 3 级扫描。