Jetson Orin Nano Super 安装 Docker:别只装 Docker,还需要 NVIDIA Container Runtime
最近在整理一台 Jetson Orin Nano Super 的开发环境时,我准备顺手把 Docker 配好。
一开始很容易按照普通 Ubuntu 的经验去想:
sudo apt install docker.io
或者直接安装 Docker CE。
但 Jetson 和普通 Ubuntu + CPU 主机有一点关键区别:
如果希望容器正常访问 Jetson 的 GPU、CUDA、TensorRT 等 NVIDIA 平台能力,仅有 Docker Engine 是不够的。
Jetson 官方还提供了一层 NVIDIA Container Toolkit / Runtime,用来把 Jetson 的 GPU 与平台能力暴露给容器。
因此完整结构其实是:
Jetson Linux / L4T
│
├── Docker Engine
│
└── NVIDIA Container Toolkit
│
└── NVIDIA Container Runtime
│
↓
GPU Container
本文记录在以下环境中的完整安装过程:
Device: Jetson Orin Nano Developer Kit Super
Architecture: aarch64
Ubuntu: 22.04.5 LTS
L4T: R36.4.3
JetPack: 6.2.x
Kernel: 5.15.148-tegra
官方参考:
NVIDIA 当前明确将 Docker 用作 Jetson 上可复现的 CUDA / AI 开发环境之一。NVIDIA Docs
1. Jetson 上推荐怎么安装 Docker?
NVIDIA 官方当前给出的安装流程是:
sudo apt update
sudo apt install -y nvidia-container curl
curl https://get.docker.com | sh
sudo nvidia-ctk runtime configure --runtime=docker
sudo systemctl daemon-reload
sudo systemctl restart docker
这里其实包含了两套东西:
nvidia-container
↓
Jetson / NVIDIA Container Toolkit
Docker Engine
↓
普通 Linux container runtime
Docker 官方本身支持 Ubuntu 22.04 和 ARM64,所以 Jetson 的 aarch64 并不是问题。Docker Documentation
如果已经配置过 Docker 官方 APT 源,也可以直接安装:
sudo apt install \
docker-ce \
docker-ce-cli \
containerd.io \
docker-buildx-plugin \
docker-compose-plugin
而不是使用 Ubuntu 自带的 docker.io。
本文机器已经存在:
https://download.docker.com/linux/ubuntu jammy
因此 Docker CE 可以直接通过 APT 安装。
不过实际安装时,我先从 Jetson 侧的 nvidia-container 开始。
2. 安装前先 dry-run
Jetson 上的 CUDA、TensorRT、L4T、JetPack 之间存在比较强的版本关联,可以说,镜像实际上进行了特调,所以直接apt upgrade往往会破坏特调。
因此我不希望为了安装 Docker,顺手触发几百个 JetPack 软件包更新。
先模拟:
sudo apt-get -s install \
nvidia-container \
docker-ce \
docker-ce-cli \
containerd.io \
docker-buildx-plugin \
docker-compose-plugin
结果却直接出现依赖冲突:
nvidia-container :
Depends: nvidia-container-toolkit-base (= 1.16.2-1)
but 1.20.1-1 is to be installed
Depends: libnvidia-container-tools (= 1.16.2-1)
but 1.20.1-1 is to be installed
Depends: nvidia-container-toolkit (= 1.16.2-1)
but 1.20.1-1 is to be installed
Depends: libnvidia-container1 (= 1.16.2-1)
but 1.20.1-1 is to be installed
这不是 Docker 损坏,也不是 dpkg 状态异常。
真正的问题是:
JetPack 6.2.1
└── nvidia-container
└── 严格要求 Toolkit 1.16.2-1
当前 APT 软件源
└── 同时提供 Toolkit 1.20.1-1
APT 默认选择新版
↓
版本依赖冲突
3. 确认 NVIDIA Container Toolkit 版本
查看相关包:
for p in \
nvidia-container \
nvidia-container-toolkit \
nvidia-container-toolkit-base \
libnvidia-container-tools \
libnvidia-container1
do
echo "===== $p ====="
apt-cache policy "$p" |
grep -E 'Installed:|Candidate:|1\.16\.2-1|1\.20\.1-1'
done
本文机器实际输出为:
===== nvidia-container =====
Installed: (none)
Candidate: 6.2.1+b38
===== nvidia-container-toolkit =====
Installed: (none)
Candidate: 1.20.1-1
1.20.1-1 600
1.16.2-1 600
===== nvidia-container-toolkit-base =====
Installed: (none)
Candidate: 1.20.1-1
1.20.1-1 600
1.16.2-1 600
另外两个包情况相同。
这里已经很清楚:
nvidia-container 6.2.1+b38
↓
要求 1.16.2-1
APT
↓
优先想装 1.20.1-1
这种情况下,我选择服从当前 JetPack 的版本组合,而不是强行追较新的 Toolkit。
4. 显式安装 JetPack 要求的版本
先继续 dry-run:
sudo apt-get -s install \
nvidia-container=6.2.1+b38 \
nvidia-container-toolkit=1.16.2-1 \
nvidia-container-toolkit-base=1.16.2-1 \
libnvidia-container-tools=1.16.2-1 \
libnvidia-container1=1.16.2-1
结果:
The following NEW packages will be installed:
libnvidia-container-tools
libnvidia-container1
nvidia-container
nvidia-container-toolkit
nvidia-container-toolkit-base
0 upgraded, 5 newly installed, 0 to remove and 899 not upgraded.
这正是希望看到的。
于是正式安装:
sudo apt-get install \
nvidia-container=6.2.1+b38 \
nvidia-container-toolkit=1.16.2-1 \
nvidia-container-toolkit-base=1.16.2-1 \
libnvidia-container-tools=1.16.2-1 \
libnvidia-container1=1.16.2-1
5. 一个很 Jetson 的行为:它自己开始装 Docker 了
安装完 nvidia-container 后,我准备继续:
sudo apt install \
docker-ce \
docker-ce-cli \
containerd.io \
docker-buildx-plugin \
docker-compose-plugin
结果发现 APT lock 已经被占用:
Could not get lock /var/lib/dpkg/lock-frontend.
It is held by process 34667 (apt-get)
这时候不要删 lock,也不要直接 kill -9。
先看进程:
ps -fp 34667
得到:
apt-get install -y docker-ce docker-ce-cli containerd...
再看父进程:
ps -fp 32056
结果非常有意思:
/bin/bash /etc/systemd/nv-install-docker.sh
继续确认这个脚本来自哪里:
dpkg -S /etc/systemd/nv-install-docker.sh
得到:
nvidia-container: /etc/systemd/nv-install-docker.sh
也就是说:
JetPack 6.2.1 的
nvidia-container包在这台机器上会通过 systemd 自动运行自己的 Docker 安装脚本。
实际流程变成了:
安装 nvidia-container
↓
/etc/systemd/nv-install-docker.sh
↓
自动 apt-get install Docker CE
↓
enable docker.service
↓
写入 NVIDIA runtime 配置
所以这里正确做法反而是什么都不做,让 NVIDIA 自己把安装跑完。
可以通过 journal 查看进度:
journalctl -u nv-install-docker.service -n 50 --no-pager
日志中可以看到:
Setting up docker-ce ...
Setting up docker-compose-plugin ...
Created symlink ... docker.service ...
Docker service installed
Wrote updated config to /etc/docker/daemon.json
因此对于这个版本的 JetPack:
如果安装
nvidia-container后突然遇到 dpkg lock,先查一下是不是 NVIDIA 的nv-install-docker.sh正在后台工作。
6. 检查 Docker
安装结束后:
docker --version
docker compose version
docker buildx version
systemctl is-enabled docker
systemctl is-active docker
本文机器得到:
Docker version 29.9.1
Docker Compose version v5.6.0
github.com/docker/buildx v0.38.0 ...
enabled
active
Docker 本体已经正常。
7. 检查 NVIDIA Runtime
继续:
cat /etc/docker/daemon.json
NVIDIA 已经自动写入:
{
"runtimes": {
"nvidia": {
"args": [],
"path": "nvidia-container-runtime"
}
}
}
但是第一次运行:
sudo docker info | grep -i -A3 runtime
只有:
Runtimes: io.containerd.runc.v2 runc
Default Runtime: runc
原因很简单:
配置已经写入,但 Docker daemon 是在写配置之前启动的。
安装日志本身也提示:
It is recommended that docker daemon be restarted.
因此:
sudo systemctl restart docker
重新检查:
sudo docker info | grep -i -A3 runtime
得到:
Runtimes: io.containerd.runc.v2 nvidia runc
Default Runtime: runc
这就说明 NVIDIA Runtime 已经正确注册。
8. Default Runtime: runc 有问题吗?
没有。
现在是:
Runtimes:
├── runc
└── nvidia
Default Runtime:
└── runc
普通容器继续用 runc。
需要 NVIDIA runtime 时:
docker run --runtime nvidia ...
不过 NVIDIA 当前 Jetson 官方教程进一步建议把:
"default-runtime": "nvidia"
加入 /etc/docker/daemon.json,这样以后运行 Jetson GPU 容器时不用每次显式写 --runtime nvidia。NVIDIA Docs
本文暂时保留,因为 runtime 已经正常注册,而且显式指定更容易看清普通容器和 NVIDIA 容器的区别。
9. 去掉 sudo docker
第一次执行:
docker images
可能遇到:
permission denied while trying to connect to the docker API
这是因为当前用户还没有加入 docker group。
执行:
sudo usermod -aG docker "$USER"
然后退出并重新登录 SSH。
再运行:
docker images
即可正常访问 Docker daemon。
Docker 官方同样提醒:docker group 会给予用户非常高的系统权限,因此只应加入可信用户。Docker Documentation
10. 最终状态
最后这台 Jetson 的容器环境为:
Jetson Orin Nano Super
│
├── Docker Engine 29.9.1
├── Docker Compose 5.6.0
├── Docker Buildx 0.38.0
├── containerd
│
├── NVIDIA Container Toolkit 1.16.2
└── NVIDIA Container Runtime
检查:
docker --version
docker compose version
docker buildx version
systemctl is-active docker
docker info | grep -i -A3 runtime
能够看到:
Runtimes: io.containerd.runc.v2 nvidia runc
即可认为 Docker + NVIDIA Container Runtime 安装完成。
Troubleshooting:本文真正踩到的两个坑
1. nvidia-container 要 1.16.2,但 APT 想装 1.20.1
不要看到更高版本就直接强行安装。
JetPack 对平台组件存在明确的版本依赖。先:
apt-cache policy ...
确认当前 JetPack 所要求的版本,再显式指定对应版本。
本文最终使用:
nvidia-container 6.2.1+b38
nvidia-container-toolkit 1.16.2-1
nvidia-container-toolkit-base 1.16.2-1
libnvidia-container-tools 1.16.2-1
libnvidia-container1 1.16.2-1
2. apt 突然提示 dpkg lock 被占用
不要立刻:
sudo rm /var/lib/dpkg/lock-frontend
更不要上来就:
kill -9
先:
ps -fp <PID>
如果父进程最终是:
/etc/systemd/nv-install-docker.sh
说明 JetPack 正在替你自动安装 Docker。
等它完成即可。
最后
Jetson 上安装 Docker 的关键其实不是 Docker 本身。
真正需要意识到的是:
普通 Ubuntu:
Docker
Jetson:
Docker
+
NVIDIA Container Runtime
+
JetPack / L4T 版本配套
直接照普通 Ubuntu 的 Docker 教程,Docker Engine 本身很可能也能安装成功,但会漏掉 Jetson 真正需要的平台集成。
而 JetPack 6.2.x 这一代已经把流程做得相当自动化:至少本文实际使用的 nvidia-container 6.2.1+b38 会自动触发 Docker CE 安装、启用服务并写入 NVIDIA runtime 配置。
剩下需要人为注意的,反而是版本冲突、不要误杀后台 installer,以及安装后重启 Docker daemon。
参考资料
本文安装流程和排查主要参考以下官方资料:
- NVIDIA Jetson Orin Nano Developer Kit — Docker Setup
介绍 Jetson 上安装 Docker、nvidia-container、配置 NVIDIA Container Runtime,以及使用nvidia-ctk配置 Docker runtime 的官方流程。
https://docs.nvidia.com/jetson/orin-nano-devkit/user-guide/latest/setup_docker.html - NVIDIA JetPack 6.2 — Install & Setup
用于确认 JetPack 6.2 / L4T R36.4 系列的软件栈、安装方式和平台版本关系。
https://docs.nvidia.com/jetson/jetpack/6.2/install-setup/index.html - Docker Engine — Install on Ubuntu
Docker 官方 Ubuntu 安装文档,用于确认docker-ce、docker-ce-cli、containerd.io、Buildx、Compose 等官方软件包及 ARM64 支持方式。
https://docs.docker.com/engine/install/ubuntu/ - Docker Engine — Linux Post-installation Steps
介绍将用户加入dockergroup、无需sudo使用 Docker 等常见安装后配置。
https://docs.docker.com/engine/install/linux-postinstall/ - NVIDIA Container Toolkit Documentation
NVIDIA Container Toolkit 的通用官方文档,可用于进一步了解nvidia-container-runtime、nvidia-ctk以及 Docker runtime 配置机制。
https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/latest/