1. Docker 相关
1. Docker 相关
1.1. Docker 支持
Firefly 发布的普通固件一般不满足 Docker 的运行要求,如果有需求,可以使用 SDK 打开内核的相关配置,重新编译烧录内核以支持 Docker。
以下案例是基于 Firefly Ubuntu 20.04,内核配置部分是通用的!
1.1.1. 检查 Kernel 配置
首先需要通过工具检查当前设备的内核缺少了哪些 Docker 需要的配置。检测脚本check-config.sh
可以前往社区论坛获取。
获取到脚本之后,开始进行检测:
#将脚本拷贝到SDK的kernel目录下
cp check-config.sh PathToSDK/kernel/
cd PathToSDK/kernel
chmod +x check-config.sh
#获取当前内核配置
make ARCH=arm64 firefly_linux_defconfig
#检测
./check-config.sh .config
执行后的结果如下,主要是两部分:
Generally Necessary:
- cgroup hierarchy: properly mounted [/sys/fs/cgroup]
- apparmor: enabled and tools installed
- CONFIG_NAMESPACES: enabled
- CONFIG_NET_NS: enabled
- CONFIG_PID_NS: enabled
- CONFIG_IPC_NS: enabled
- CONFIG_UTS_NS: enabled
- CONFIG_CGROUPS: enabled
......
Optional Features:
- CONFIG_USER_NS: enabled
- CONFIG_SECCOMP: enabled
- CONFIG_SECCOMP_FILTER: enabled
- CONFIG_CGROUP_PIDS: enabled
- CONFIG_MEMCG_SWAP: enabled
......
Generally Necessary: 表示必要的配置,如果有显示 missing 的地方,就需要在内核配置中打开它。 Optional Features: 是可选配置,根据需要打开。
1.1.2. 开启需要的配置
从上面的检测结果中得知需要打开哪些配置后,即可使用make ARCH=arm64 menuconfig
进入菜单,搜索对应项目将其打开。请认真查看菜单中的操作说明,遇到不可选中的项目请注意依赖关系。
开启所有必要配置以及部分可选配置后,注意保存:
make ARCH=arm64 savedefconfig
mv defconfig arch/arm64/configs/firefly_linux_defconfig
之后进行编译内核:
#退回到SDK目录
cd ..
#编译内核
./build.sh kernel
1.1.3. 安装 Docker
烧录完新内核之后,可以开始在设备上安装 Docker 并验证:
#这里仅介绍直接使用脚本快速安装
apt-get update
wget -qO- https://get.docker.com/ | sh
等待安装成功之后应该会看见 Docker 版本信息,然后运行 demo:
root@firefly:~# docker run hello-world
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
93288797bd35: Pull complete
Digest: sha256:cc15c5b292d8525effc0f89cb299f1804f3a725c8d05e158653a563f15e4f685
Status: Downloaded newer image for hello-world:latest
Hello from Docker!
This message shows that your installation appears to be working correctly.
To generate this message, Docker took the following steps:
1. The Docker client contacted the Docker daemon.
2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
(arm64v8)
3. The Docker daemon created a new container from that image which runs the
executable that produces the output you are currently reading.
4. The Docker daemon streamed that output to the Docker client, which sent it
to your terminal.
To try something more ambitious, you can run an Ubuntu container with:
$ docker run -it ubuntu bash
Share images, automate workflows, and more with a free Docker ID:
https://hub.docker.com/
For more examples and ideas, visit:
https://docs.docker.com/get-started/
1.2. 使用 Docker 搭建分布式编译环境
distcc
是个通过网络上的若干台机器用来分布式编译 C、C++、Objective-C 或 Objective-C++ 代码的程序。distcc
不要求所有的机器共享文件系统,有同步的时钟,或者安装有同样的库和头文件,只要作为服务器的机器有合适的编译工具即可进行编译。本例在两个 Firefly-RK3399 板卡 (arm64) 和一台 PC 机 (x86_64) 上利用 Docker 技术来布署 distcc
分布式编译服务,进而实现在其中一个 Firefly-RK3399 板卡上利用 distcc
的分布式编译特性来加速内核的编译过程。
1.2.1. 准备工作
-
两个 Firefly-RK3399 板卡
-
路由器、网线
-
PC 机
将两块设备和 PC 机都连接到同一个局域网内。连接好后对应的 IP 地址别是:
-
PC 机:192.168.1.100
-
设备 A:192.168.1.101
-
设备 B:192.168.1.102
1.2.2. PC 机部署 Docker
使用脚本安装 Docker:
wget -qO- https://get.docker.com/ | sh
为了可以使当前普通用户可以执行 docker 相关命令,需要将当前用户添加到 dokcer 用户组中:
sudo groupadd docker # 添加 docker 用户组
sudo gpasswd -a $USER docker # 将当前用户添加到 docker 用户组中
newgrp docker # 更新 docker 用户组
启动 Docker 后台服务:
sudo service docker start
新建一个 Dockerfile_distcc.x86_64
文件。其文件内容如下:
FROM ubuntu:bionic
MAINTAINER Firefly <service@t-firefly.com>
ARG DEBIAN_FRONTEND=noninteractive
RUN apt-get update \
&& apt-get install -y --no-install-recommends --no-install-suggests\
gcc-aarch64-linux-gnu distcc\
&& apt-get clean \
&& rm -rf /var/lib/apt/lists
RUN ln -s aarch64-linux-gnu-gcc /usr/bin/gcc &&\
ln -s aarch64-linux-gnu-gcc /usr/bin/cc
EXPOSE 3632
ENTRYPOINT ["/usr/bin/distccd"]
CMD ["--no-detach" , "--log-stderr" , "--log-level", "debug", "--allow" , "0.0.0.0/0"]
生成 Docker 镜像:
docker build -t distcc_server:x86_64 -f Dockerfile_distcc.x86_64 .
可以用命令 docker images
查看生成的 Docker 镜像:
docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
distcc_server x86_64 138c0b7e3801 9 minutes ago 66.1MB
用新建的镜像启动 Docker 容器,在主机网络的 3632 TCP 端口提供 distcc 服务:
docker run -d -p 3632:3632 distcc_server:x86_64
用命令 docker ps
可以查看正在运行中的容器:
docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
fa468d068185 distcc_server:x86_64 "/usr/bin/distccd --…" 9 minutes ago Up 9 minutes 0.0.0.0:3632->3632/tcp epic_chatterjee
1.2.3. 设备部署 Docker
apt-get update
wget -qO- https://get.docker.com/ | sh
将当前用户添加到 dokcer 用户组中:
sudo groupadd docker
sudo gpasswd -a $USER docker
newgrp docker # 更新 docker
启动 Docker 后台服务:
service docker start
新建 Dockerfile_distcc.arm64
文件,内容如下:
FROM ubuntu:bionic
MAINTAINER Firefly <service@t-firefly.com>
ARG DEBIAN_FRONTEND=noninteractive
RUN apt-get update \
&& apt-get install -y --no-install-recommends --no-install-suggests \
gcc distcc\
&& apt-get clean \
&& rm -rf /var/lib/apt/lists
EXPOSE 3632
ENTRYPOINT ["/usr/bin/distccd"]
CMD ["--no-detach" , "--log-stderr" , "--log-level", "debug", "--allow" , "0.0.0.0/0"]
生成 Docker 镜像:
docker build -t distcc_server:arm64 -f Dockerfile_distcc.arm64 .
用新建的镜像启动 Docker 容器,在主机网络的 3632 TCP 端口提供 distcc
服务:
docker run -d -p 3632:3632 distcc_server:arm64
用 docker save
命令导出新建的镜像:
docker save -o distcc_server.tar distcc_server:arm64
将生成的 distcc_server.tar
文件复制到另一块设备上,然后导入镜像:
docker load -i distcc_server.tar
导入镜像后,在这个设备上也有了 distcc_server:arm64
镜像,然后可以运行一个容器:
docker run -d -p 3632:3632 distcc_server:arm64
提示:用户如果注册了 Docker Hub 帐号,可以用 docker push
推送镜像到远程仓库,在另一设备上用 docker pull
拉取远程仓库的镜像。用户可以自行了解相关操作。
1.2.4. 客户端用 distcc 编译内核
到这里,三个机器都部署了分布式编译环境。可以选择任意一台机器作为客户端,剩下两个机器作为服务器。这里选择其中一个设备作为客户端。
在客户端中创建 Dockerfile_compile.arm64
文件,生成一个编译内核的 Docker 镜像,文件内容如下:
FROM ubuntu:bionic
MAINTAINER Firefly <service@t-firefly.com>
ARG DEBIAN_FRONTEND=noninteractive
RUN apt-get update \
&& apt-get install -y --no-install-recommends --no-install-suggests \
bc make python sed libssl-dev binutils build-essential distcc\
liblz4-tool gcc \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists
然后生成镜像:
docker build -t compile:arm64 -f Dockerfile_compile.arm64 .
在启动容器前先将内核文件拉到客户端中。然后创建 /etc/distcc/hosts
文件,其内容是列举出所有提供 distcc 服务的机器的 IP 地址。内容如下:
# As described in the distcc manpage, this file can be used for a global
# list of available distcc hosts.
#
# The list from this file will only be used, if neither the
# environment variable DISTCC_HOSTS, nor the file $HOME/.distcc/hosts
# contains a valid list of hosts.
#
# Add a list of hostnames in one line, seperated by spaces, here.
192.168.1.100
192.168.1.101
193.168.1.102
为了测试结果更准确,先清除客户端设备上的缓存:
echo 3 > /proc/sys/vm/drop_caches
用 compile:arm64
镜像启动一个 Docker 容器,同时将主机当前内核目录挂载到容器中的 /mnt
目录,将主机的 /etc/distcc/hosts
文件挂载到容器的 /etc/distcc/hosts
中,并用参数 -it
以交互模式启动容器:
docker run -it --rm -v $(pwd):/mnt -v /etc/distcc/hosts:/etc/distcc/hosts compile:arm64 /bin/bash
root@f4415264351b:/# ls
bin boot dev etc home lib media mnt opt proc root run sbin srv sys tmp usr var
root@f4415264351b:/# cd mnt/
进入到容器中的 /mnt
目录,然后开始用 distcc 编译内核,加入 time
命令可以查看编译命令执行耗时,CC
参数指明用 distcc
进行编译:
time make ARCH=arm64 rk3399-firefly.img -j32 CC="distcc"
注意:如果用 PC 机作为客户端,则需要用以下命令进行编译:
time make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- rk3399-firefly.img -j32 CC="distcc aarch64-linux-gnu-gcc"
编译过程中,可以在用于编译的容器内新的窗口中用命令 distccmon-text 1
查看编译情况:
distccmon-text 1
...
15713 Compile perf_regs.c 192.168.1.101[0]
15327 Compile fork.c 192.168.1.101[2]
15119 Compile dma-mapping.c 192.168.1.101[3]
15552 Compile signal32.c 192.168.1.100[0]
15644 Compile open.c 192.168.1.100[2]
15112 Compile traps.c 192.168.1.100[3]
15670 Compile arm64ksyms.c 192.168.1.102[0]
15629 Compile mempool.c 192.168.1.102[2]
15606 Compile filemap.c 192.168.1.102[3]
15771 Preprocess localhost[0]
15573 Preprocess localhost[1]
15485 Preprocess localhost[2]
...
最后编译命令完成后可以看到编译所用时间:
real 15m44.809s
user 16m0.029s
sys 6m22.317s
下边是单独使用一块设备进行内核编译所耗费的时间:
real 23m33.002s
user 113m2.615s
sys 9m29.348s
对比可见,用采用 distcc 实现的分布式编译可以有效提高编译速度。
注意:
-
平台不同,所需的编译器也不同。如在 x86_64 平台上,需要安装对应的交叉编译工具
gcc-aarch64-linux-gnu
。在 arm64 平台则只需要安装gcc
编译工具即可。用户需要根据实际情况在对应的Dockerfile
文件里指定安装正确的工具。 -
如果用 PC 机做客户端,则在用于编译的容器中编译内核的时候,要用参数
CC="distcc aarch64-linux-gnu-gcc"
指明用aarch64-linux-gnu-gcc
交叉编译工具编译。
本公司成本价甩卖工控主板,欢迎大家选购:
PCIE总线转八串口卡,PCIE总线转IO卡,瑞芯微3568板卡,寒武纪CE3226摄像头板卡,龙芯3A4000工控板卡,龙芯3A5000工控板卡,海光3250工控板卡,飞腾FT-2000/4板卡
联系方式:
电话、微信:15918785568 罗生
Email:13279654@qq.com
公众号:开发之美