13. 使用Docker构建镜像

我们的SDK使用Ubuntu22.04作为标准开发环境,但是由于不同版本的Ubuntu镜像构建环境不同, 导致我们在构建不同版本的根文件系统时要频繁安装新的构建环境,不仅浪费了大量时间,还容易导致构建失败。

为了解决以上问题,我们借助Docker来隔离我们的根文件系统构建环境。

13.1. 什么是Docker

Docker是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中, 然后发布到任何流行的Linux或Windows操作系统的机器上,也可以实现虚拟化。 容器是完全使用沙箱机制,相互之间不会有任何接口。

简单理解,Docker就是一个小型的虚拟化系统,可以起到与主机环境隔离的作用。 下图是docker的logo,是一个小鲸鱼上托着很多集装箱,很生动形象的描述了Docker的作用。

../../_images/docker-logo.png

docker的官网是 https://www.docker.com/

13.2. Docker的安装

在不同的操作系统上安装Docker有不同的方法,我们主要使用的是Ubuntu操作系统。 其他系统的安装方法可以参考官方文档 https://docs.docker.com/engine/install/

我们在Ubuntu虚拟机上安装 Docker CE 即可,具体安装过程如下

13.2.1. 卸载旧版本

在尝试安装新版本之前卸载旧版本

1
sudo apt-get remove docker docker-engine docker.io containerd runc

13.2.2. 使用存储库安装

在新主机上首次安装Docker之前,需要设置Docker存储库,之后就可以从存储库安装和更新Docker。

13.2.2.1. 设置存储库

  • 安装 Docker 所需的依赖包:

1
2
sudo apt-get update
sudo apt install apt-transport-https ca-certificates curl software-properties-common -y
  • 添加 Docker 的 GPG 密钥:

1
curl -fsSL https://mirrors.ustc.edu.cn/docker-ce/linux/ubuntu/gpg | sudo apt-key add -
  • 验证 0EBFCD88 公钥:

1
sudo apt-key fingerprint 0EBFCD88
  • 添加 Docker 仓库

1
sudo add-apt-repository "deb [arch=amd64] https://mirrors.ustc.edu.cn/docker-ce/linux/ubuntu $(lsb_release -cs) stable" -y

13.2.2.2. 安装 Docker CE

1
2
3
sudo apt update
sudo apt --fix-broken install -y
sudo apt install docker-ce -y

13.2.2.3. 创建 docker 用户组

1
2
sudo groupadd docker
sudo gpasswd -a $(whoami) docker

13.2.2.4. 重新启动 Docker 服务

1
sudo systemctl restart docker

13.2.2.5. 验证安装完成

使用以下命令打印出版本号即为安装成功

1
2
3
4
sudo docker -v

# 打印出版本号
Docker version 20.10.22, build 3a2c30b

13.3. 创建本地docker镜像

由于Docker的镜像服务器在国外,由于某种原因,国内目前已经访问不了了,所以我们使用本地打包好的Docker镜像。

下载资料网盘/7-SDK源码压缩包/ubuntu22_sg200x_docker.tar 离线Docker镜像压缩包,将压缩包拷贝到Linux下。

13.3.1. 安装离线镜像包

不需要解压,直接通过docker命令进行安装:

1
2
3
4
5
6
#安装docker离线包
sudo docker load -i ubuntu22_sg200x_docker.tar

#信息输出如下
e66431576313: Loading layer [==================================================>]  820.1MB/820.1MB
Loaded image: ubuntu22_sg200x:22.04

安装完成后查看docker镜像:

1
2
3
4
5
#查看当前系统存在的docker镜像
sudo docker image ls

REPOSITORY                  TAG       IMAGE ID       CREATED        SIZE
ubuntu22_sg200x             22.04     31f61a33eef8   17 hours ago   877MB

存储库名字为ubuntu22_sg200x,标签为22.04的docker镜像就是我们的镜像,大小为877MB。

13.4. 创建docker容器

执行 docker run 命令运行docker镜像,并将SDK挂载到运行docker镜像的容器中,进入工作目录。

1
2
3
4
5
6
7
#需要指定实际的SDK目录路径
sudo docker run --name ubuntu22_sg200x -it --privileged -v /home/hyw/sg200x/sophon-image-build:/works ubuntu22_sg200x:22.04 /bin/bash

#将works设置为git安全目录
git config --global --add safe.directory /works

cd works/
  • docker run :运行容器。

  • –name ubuntu22_sg200x:设置容器的名称。

  • -it:以交互模式运行容器。

  • –privileged:以特权模式运行容器。

  • -v /home/hyw/sg200x/sophon-image-build:/works 设置挂载到容器的目录,:前是宿主机的路径,:后是挂载到容器的路径,使用绝对路径。这里把整个SDK挂载到容器的/works目录下。

  • ubuntu22_sg200x:22.04 容器使用的镜像,这里指定了镜像的名称,使用镜像ID也可以。

  • /bin/bash 交互模式中使用的shell解释器。

../../_images/docker01.jpg

图中可以看到,执行完运行运行容器的命令后,我们从guest@dev107变成了root@36c3e73bbdb5,这说明我们现在已经进入了容器,以root用户运行,容器ID是36c3e73bbdb5。

注意此时不要关闭当前的终端,关闭中断则失去了和当前容器的连接。

13.5. 编译SDK

构建方法和在虚拟机中是一样的,这里做简单演示。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
#初始化编译环境,输入当前用户的密码
source build/cvisetup.sh

#加载板级配置文件
defconfig sg2000_lubancat_riscv_ubuntu_emmc

#清除之前编译输出
clean_all

#一键编译完整镜像
build_all

运行完成以上命令后,镜像就构建出来了。

13.6. docker的相关操作命令

13.6.1. 退出当前容器

在当前终端运行 exit 即可停止并退出当前容器

13.6.2. 查看当前正在运行的容器

1
sudo docker ps -a

-a 选项,查看所有容器,包括退出的和正在运行的。

13.6.3. 重新运行停止的容器并进入容器

1
sudo docker start build_rootfs

重新运行停止的容器,可以指定容器名称,也可以指定容器ID

1
sudo docker start 36c3e73bbdb5

进入正在运行的容器,可以指定容器名称,也可以指定容器ID

1
sudo docker attach 36c3e73bbdb5

13.6.4. 删除容器

1
sudo docker rm ubuntu22_sg200x

删除容器,可以指定容器名称,也可以指定容器ID,添加-f 选项,可以强制删除未停止的容器。

13.6.5. 删除镜像

1
sudo docker rmi build_rootfs:2204

删除镜像,可以指定镜像名称:TAG,也可以指定镜像ID