跳到主要内容

Docker

这里整理 Neardi Pi 3 上 Docker 的使用方法。内容参考 Rockchip Docker 部署文档,并结合 RK3576 Linux 6.1 R6 SDK 上已经验证过的补丁。

RK3576 上跑 Docker,关键不是只装一个 docker.io 包。内核里要打开 cgroups、namespace、netfilter、overlayfs 等配置。否则 Docker 可能能安装,但创建容器或配置网络时会报错。

SDK 中打开 Docker 支持

Neardi Pi 3 对应的板级配置在 device/rockchip/.chips/rk3576/rockchip_rk3576_neardi_pi3_defconfig,需要把 Docker 内核配置片段加进去:

RK_UBOOT_SPL=y
RK_KERNEL_DTS_NAME="rk3576-neardi-pi3-linux"
RK_USE_FIT_IMG=y
-RK_KERNEL_CFG_FRAGMENTS="rk3576_neardi_pi3.config"
+RK_KERNEL_CFG_FRAGMENTS="rk3576_neardi_pi3.config rockchip_linux_docker.config rk3576_neardi_fragment.config"

另外,rk3576_neardi_fragment.config 里需要补上 CONFIG_IP_NF_RAW=y

CONFIG_IP_NF_TARGET_MASQUERADE=y
CONFIG_IP_NF_TARGET_NETMAP=y
CONFIG_IP_NF_TARGET_REDIRECT=y
+CONFIG_IP_NF_RAW=y
CONFIG_NETFILTER=y
CONFIG_NETFILTER_ADVANCED=y
CONFIG_NETFILTER_XTABLES=y

改完后重新编译内核或整包固件,再烧录到板子上。这里要注意,Docker 依赖的是“当前正在运行的内核配置”,所以只在板子上重新安装 Docker,不能解决内核配置缺失的问题。

Ubuntu/Debian 上安装 Docker

在板端执行:

sudo apt update
sudo apt install -y docker.io
sudo systemctl enable docker
sudo systemctl start docker

查看服务状态:

sudo systemctl status docker
docker --version

切换到 iptables-legacy

这一点很容易漏。Debian/Ubuntu 默认可能使用 iptables-nft,但 Rockchip 这套 Docker 流程建议切到 iptables-legacy

测试 Docker 网络前,先执行:

sudo update-alternatives --set iptables /usr/sbin/iptables-legacy
sudo update-alternatives --set ip6tables /usr/sbin/ip6tables-legacy
sudo systemctl restart docker

如果 Docker 报 NAT、MASQUERADE、iptables、bridge 网络相关错误,优先检查这里。

基础测试

运行一个简单容器:

sudo docker run --rm hello-world

查看 Docker 信息:

sudo docker info
sudo docker image ls
sudo docker container ls -a

进入一个 Ubuntu 容器:

sudo docker run --rm -it ubuntu:22.04 /bin/bash

如果板子访问不了 Docker Hub,可以配置可用的镜像源,或者在其他机器上下载镜像后再导入。

FAQ

拉取镜像超时怎么办?

如果运行 hello-world 时卡在拉取镜像,或者出现下面这种超时:

Unable to find image 'hello-world:latest' locally
docker: Error response from daemon: failed to resolve reference "docker.io/library/hello-world:latest": failed to do request: Head "https://mirror.gcr.io/v2/library/hello-world/manifests/latest?ns=docker.io": dial tcp 142.251.188.82:443: i/o timeout

一般是板端网络访问 Docker Hub 或默认镜像源不稳定。可以配置 Docker registry mirror:

sudo mkdir -p /etc/docker
sudo vi /etc/docker/daemon.json

写入:

{
"registry-mirrors": [
"https://docker.1panel.live",
"https://dockerproxy.com",
"https://hub.rat.dev"
]
}

然后重启 Docker:

sudo systemctl daemon-reload
sudo systemctl restart docker

再次测试:

sudo docker run --rm hello-world

看到下面开头的输出,就表示 Docker 可以正常拉取并运行镜像:

Hello from Docker!
This message shows that your installation appears to be working correctly.

neardi 用户不能直接执行 docker 怎么办?

如果不想每次都加 sudo,可以把当前用户加入 docker 组:

sudo usermod -aG docker $USER
newgrp docker

也可以明确指定 neardi 用户:

sudo usermod -aG docker neardi
newgrp docker

然后直接运行:

docker run --rm hello-world

看到 Hello from Docker! 即可。

警告

加入 docker 组后,该用户可以控制 Docker daemon,权限接近 root。只建议给可信用户开启。

常用命令

从 Dockerfile 构建镜像:

sudo docker build -t my-app:latest .

运行容器并挂载主机目录:

sudo docker run --rm -it \
-v /home/neardi/work:/work \
my-app:latest /bin/bash

使用 host 网络:

sudo docker run --rm -it --network host my-app:latest /bin/bash

清理不用的镜像和容器:

sudo docker system prune

Buildroot 镜像

如果使用 Buildroot 系统,默认一般不会打开 Docker。Rockchip 文档中常用的配置如下:

BR2_PACKAGE_CGROUPFS_MOUNT=y
BR2_PACKAGE_DOCKER_ENGINE=y
BR2_PACKAGE_DOCKER_ENGINE_EXPERIMENTAL=y
BR2_PACKAGE_DOCKER_ENGINE_STATIC_CLIENT=y
BR2_PACKAGE_DOCKER_ENGINE_DRIVER_BTRFS=y
BR2_PACKAGE_DOCKER_ENGINE_DRIVER_DEVICEMAPPER=y
BR2_PACKAGE_DOCKER_ENGINE_DRIVER_VFS=y

如果是 Ubuntu/Debian 系统,通常板端安装 docker.io 即可,前提是内核已经按上面的 Docker fragment 重新编译并烧录。

常见排查

Docker 起不来,或者容器网络不通时,可以先看这几项:

uname -a
zcat /proc/config.gz | grep -E "CGROUP|NAMESPACE|OVERLAY|NETFILTER|IP_NF"
sudo update-alternatives --display iptables
sudo journalctl -u docker -n 100 --no-pager

常见现象:

现象先检查什么
Docker 能安装,但容器启动失败内核配置可能不完整,先确认是否加入 rockchip_linux_docker.config
网络或 NAT 报错确认 iptablesip6tables 是否已切到 legacy。
raw table 相关 iptables 报错确认运行中的内核已打开 CONFIG_IP_NF_RAW=y
拉取镜像超时板子网络可能访问不了 Docker Hub,换镜像源或手动导入镜像。

RK3576 Linux SDK 中可参考的原始文档:

  • Rockchip_Developer_Guide_Linux_Docker_Deploy_CN.pdf
  • Rockchip_Developer_Guide_Debian_Docker_CN.pdf