目录
1 引言
在构建ubuntu rootfs的时候,我们在自己的PC上完成了环境的搭建,但是其他PC上需要应用该构建框架时候,需要我们一台一台的去配置,会导致大量重复工作。所以我们应该提供一种统一的工具来搭建我们的构建环境,这个工具就是docker。本章将对docker进行描述,主要围绕搭建ubuntu发行版本的环境。
2 docker简介
docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的镜像中,然后发布到任何流行的 Linux或Windows 机器上,也可以实现虚拟化。容器是完全使用沙箱机制,相互之间不会有任何接口。借助 docker,我们可将容器当做轻巧、模块化的虚拟机使用。同时,还可以获得高度的灵活性,从而实现对容器的高效创建、部署及复制,并能将其从一个环境顺利迁移至另一个环境。
3 docker工具安装
在Ubuntu 上安装 docker 比较容易。我们将会启用 docker 软件源,导入 GPG key,并且安装软件包。
1)更新软件包索引,并且安装必要的依赖软件,来添加一个新的 HTTPS 软件源
sudo apt update
sudo apt install apt-transport-https ca-certificates curl gnupg-agent software-properties-common
2)导入源仓库的 GPG key
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
3)将 docker APT 软件源添加到系统
sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
4)安装 docker 最新版本
sudo apt update
sudo apt install docker-ce docker-ce-cli containerd.io
5)docker安装指定版本及禁止更新
列出 docker 软件源中所有可用的版本
sudo apt update
apt list -a docker-ce
通过在软件包名后面添加版本=<VERSION>
来安装指定版本:
sudo apt install docker-ce=<VERSION> docker-ce-cli=<VERSION> containerd.io
一旦安装完成,docker 服务将会自动启动。你可以输入下面的命令,验证它:
sudo systemctl status docker
输出信息:
● docker.service - Docker Application Container Engine
Loaded: loaded (/lib/systemd/system/docker.service; enabled; vendor preset: enabled)
Active: active (running) since Thu 2021-05-23 18:21:57 UTC; 30s ago
当一个新的 docker 发布时,你可以使用标准的sudo apt update && sudo apt upgrade流程来升级 docker 软件包。
如果你想阻止 docker 自动更新,锁住它的版本:
sudo apt-mark hold docker-ce
6)卸载 docker
在卸载 docker 之前,你最好 移除所有的容器,镜像,卷和网络。
运行下面的命令停止所有正在运行的容器,并且移除所有的 docker 对象
docker container stop $(docker container ls -aq)
docker system prune -a --volumes
使用apt正常
卸载 docker:
sudo apt purge docker-ce
sudo apt autoremove
4 docker常规应用
4.1 docker参数
4.1.0 docker创建网络
我们在创建网络的时候指定IP地址段,创建自定义网络。
docker network create --subnet=192.168.1.0/24 test_network
上述操作的目的是为了创建docker容器的时候,指定一个固定的IP地址。
4.1.1 创建docker
docker run :创建一个新的容器并运行一个命令
语法:
docker run [OPTIONS] IMAGE [COMMAND] [ARG...]
常用OPTIONS
-d: 后台运行容器,并返回容器ID;
-i: 以交互模式运行容器,通常与 -t 同时使用;
-P: 随机端口映射,容器内部端口随机映射到主机的端口
-p: 指定端口映射,格式为:主机(宿主)端口:容器端口
-t: 为容器重新分配一个伪输入终端,通常与 -i 同时使用;
--net="bridge": 指定容器的网络连接类型,支持 bridge/host/none/container: 四种类型;
--link=[]: 添加链接到另一个容器;
使用案例:
docker run --privileged -it --net test_network --ip 192.168.1.101 IMAGE_ID /bin/bash
参数含义:
--privileged:container内的root拥有真正的root权限。否则,container内的root只是外部的一个普通用户权限。
-net myself_network:指定容器的网络连接类型为创建的myself_network
--ip 192.168.1.101:指定docker的ip地址为:192.168.1.101
--/bin/bash:LINUX中执行SHELL命令的格式,docker启动一个bash终端,允许用户进行交互。
4.1.2 进入docker
1)docker start :启动一个或多个已经被停止的容器
使用格式:docker start [OPTIONS] CONTAINER [CONTAINER...]
2)docker attach :连接到正在运行中的容器。
使用格式:docker attach [OPTIONS] CONTAINER
注意:要attach上去的容器必须正在运行
4.1.3 退出docker
进入docker后,输入:exit;即可退出。
4.1.4 删除docker
docker rm :删除一个或多个容器。
语法:
docker rm [OPTIONS] CONTAINER [CONTAINER...]
删除image
docker rmi <image id>
4.1.5 其他应用
docker cp :用于容器与主机之间的数据拷贝。
语法:
docker cp [OPTIONS] CONTAINER:SRC_PATH DEST_PATH|-
docker cp [OPTIONS] SRC_PATH|- CONTAINER:DEST_PATH
-L :保持源目标中的链接
5 dockerfile应用
docker可以从一个Dockerfile中读取指令自动创建镜像, Dockerfile是一个包含了用户可以在命令行上所有用于组合镜像的命令。 用户可以使用docker build创建一个连续执行一些命令的自动构建。
docker的build操作,默认是基于缓存,也就是修改Dockerfile后,build任务会快速略过之前成功的步骤,从修改的那一步之后的操作,都会重新运行。如果想每一次build都不基于之前的缓存,在build 命令加上 --no-cache=true 参数。
5.1 常见参数
Dockerfile 格式如下:
# 注释
指令 参数
在这里列出了一些常用的指令:
FROM:指定基础镜像,必须为第一个命令
MAINTAINER: 维护者信息
RUN:构建镜像时执行的命令
ADD:将本地文件添加到容器中
COPY:功能类似ADD
CMD:构建容器后调用,也就是在容器启动时才进行调用
ENTRYPOINT:配置容器,使其可执行化
USER:指定运行容器时的用户名或 UID,后续的 RUN 也会使用指定用户
5.2 ENTRYPOINT 应用
docker 指令CMD与ENTRYPOINT用于配置容器启动时的运行命令,通常会写在Dockerfile中。
当指定了 ENTRYPOINT 后,CMD 的含义就发生了改变,不再是直接的运行其命令,而是将 CMD 的内容作为参数传给 ENTRYPOINT 指令,换句话说实际执行时,将变为:
<ENTRYPOINT> "<CMD>"
5.2.1 测试例子
在Dockerfile中,ENTRYPOINT命令定义可执行文件,而CMD设置默认参数
Dockerfile的内容:
FROM ubuntu
MAINTAINER sofija
RUN apt-get update
ENTRYPOINT [“echo”, “Hello”]
CMD [“World”]
如果从此文件构建映像并使用它运行docker容器,则输出显示:
可以通过将所需参数添加到docker run命令来轻松覆盖默认CMD
但是,使用的时候可能想覆盖默认的可执行文件,需要使用--entrypoint标志
5.2.2 demo
Dockerfile内容:
FROM ubuntu:20.04
RUN apt-get update -y && export DEBIAN_FRONTEND=noninteractive && \
apt-get install -y expect \
wget net-tools \
lsb-release
RUN apt-get update -y
ENTRYPOINT ["/usr/sbin/entrypoint.sh"]
entrypoint.sh内容:
#!/bin/sh
set -e
export HOME=/home/docker
exec "$@"
所以在创建容器的时候,如果不需要覆盖entrypoint.sh,则正常创建;如果需要覆盖,则增加参数:--entrypoint
注意:个脚本都应该在文件开头加上set -e, 这句语句告诉bash如果任何语句的执行结果不是true则应该退出. 这样的好处是防止错误像滚雪球般变大导致一个致命的错误, 而这些错误本应该在之前就被处理掉. 如果要增加可读性, 可以使用set -o errexit, 它的作用与set -e相同。
exec "$@" 命令的意义在于你已经为你的镜像预想到了应该有的调用情况, 当实际使用镜像的人执行了你没有预料到的可执行命令时, 将会走到脚本的这最后一行, 去执行用户新的可执行命令。exec是用被执行的命令行替换掉当前的shell进程,且exec命令后的其他命令将不再执行。
5.3 注意事项
需要特别注意:
在docker中使用qemu,如chroot rootfs之前需要把qemu-aarch64-static cp到rootfs/usr/bin,然后再执行chroot rootfs命令,但是如果在docker外的服务器上没有安装qemu-user-static,则会产生报错:
chroot: failed to run command '/bin/bash': Exec format error.
这个问题不容易解决,所以特别开一个小节介绍。
参考
https://baike.baidu.com/item/Docker/13344470?fr=aladdin
https://zhuanlan.zhihu.com/p/143156163
https://bbs.csdn.net/topics/392160887
https://zhuanlan.zhihu.com/p/33366306
https://blog.csdn.net/liufuwu1/article/details/88096213