文章目录
- Docker镜像简介
- 1、Docker中镜像的结构
- (1)镜像的结构原理图
- (2)实践理解镜像结构特性
- <1>交互式运行容器的基础操作
- <2>实践操作理解镜像特性
- 2、如何构建镜像
- (1)手动构建新镜像
- (2)通过dockerfile自动构造新镜像
- (3)使用dockerfile方式自动构建镜像的缓存特性
Docker镜像简介 1、Docker中镜像的结构 (1)镜像的结构原理图
在使用Docker之前,先了解以下Docker中镜像的结构,所有的容器都是由镜像产生的,了解镜像的结构,有助于使用Docker。下面我画了一张结构图,帮助理解。
文章图片
由图可见镜像的结构大致分为四层:共享的内核层、基础镜像层、定制镜像层、可写容器层。每一层的功能和特性都在图中标注出了。
(2)实践理解镜像结构特性
<1>交互式运行容器的基础操作 在实践时需要已交互式运行容器,那先看一下如何用交互式的方式运行容器。此处使用的测试镜像为ubuntu的镜像。
命令 | 功能 |
---|---|
docker load -i ubuntu.tar | 先将ubuntu的镜像导入 |
docker run -it --name test1 ubuntu | -it就意为用交互式的方式运行容器,进入交互式界面后,就和平时一样操作即可 |
Ctrl+p+q | 让该容器在后台运行,此时容器不是stop的状态 |
docker attach test1 | 将后台运行的test1容器调到前台继续操作 |
Ctrl+d | 关闭容器,此时容器是stop的状态,不能attach到 |
docker start test1 | 在后台开启容器,开启后的容器再attach就可以调到前台操作了 |
docker ps | 查看当前运行着的容器(若容器关闭,则无法查看到) |
docker ps -a | 查看所有存在的容器 |
docker rm test1 | 删除test1容器,若容器正在运行则会报错 |
docker rm -f test1 | 强制删除test1容器,即使容器正在运行也会强行删除 |
- 已交互式方式开启容器并进行操作,此处试着建立了三个测试文件。
文章图片
- 使用Ctrl+p+q将容器打入后台运行,可直接通过docker attach调入前台进行操作。
文章图片
- 若用Ctrl+p+q将容器打入后台时,在当前运行的容器中仍旧可查看到。
文章图片
- 使用Ctrl+d关闭镜像,此时在当前运行的容器中查看不到,但可以在所有容器中查看到。
文章图片
- 关闭的容器需要先开启,再调入前台操作。
文章图片
- 删除容器
文章图片
例如刚刚我们在test1容器中建立了三个测试文件,然后将test1容器删除了,此时再用test1为容器名进入,也无法恢复三个测试文件。
文章图片
因为此时的test1容器,虽然名为test1,却与之前的test1是同名不同器,这是新建立的test1,而三个测试文件已经随着容器的删除灰飞烟灭,自然不会存在于新容器中。
2、如何构建镜像 了解了镜像的结构后,可以看到在镜像的结构中有定制镜像层,是根据用户需求定制的新的镜像,此时来学习以下如何构建这个新的定制镜像。此处使用的基础镜像是busybox。
(1)手动构建新镜像
【Docker|Docker镜像简介】使用docker commit的方式手动构建新镜像
命令 | 功能 |
---|---|
docker load -i busybox.tar | 导入busybox镜像 |
docker run -it --name busytest busybox | 以busybox为镜像,交互式启动busytest容器 |
docker commit busytest | 提交busytest容器的内容为一个新的镜像,此时未指定新镜像名称 |
docker commit busytest co1 | 此时指定了新镜像名称为co1,但未指定标签 |
docker run -it --name co1test co1 | 以co1镜像启动co1test容器 |
docker history co1:latest | 查看新镜像的创建历史 |
- 在busytest容器中创建测试文件,以作区分。
文章图片
- 提交容器内容为新镜像,未指定新镜像名称,查看镜像的时候会发现默认给了
,标签也默认给了 。
文章图片
- 指定了新镜像名称为co1,没有指定标签,但查看会发现标签默认给了latest。
文章图片
- 用co1为基础开启新容器,会发现有测试文件,说明测试文件是包含在co1镜像中的内容。
文章图片
- 查看co1的构建历史会发现无法做镜像的审计,因为通过docker commit的方式提交的话,不管做了什么改动操作,在提交之后,都只会显示“sh”,无法知道改动的内容。
文章图片
使用dockerfile的方式自动构造新的镜像,创建一个新的构建目录,构建镜像时会读取该目录中的所有数据发送到构建引擎,作为构建内容使用。
命令 | 功能 |
---|---|
mkdir docker | 建立一个新的构建目录,名称随意,此处为了方便区分起了docker |
cd docker | 进入到目录中进行操作 |
vim dockerfile | 建立一个名为dockerfile的文件,此名称不能任意起,将构建镜像的内容写入,内容已在附图中贴出 |
docker build -t co2:1 . | 使用docker build建立名为co2:1的新镜像,构建目录选为当前目录(用.表示当前) |
docker history ubuntu:latest | 构建完成后查看构建新镜像使用的基础镜像的构建历史 |
docker history co2:1 | 再查看新镜像的构建历史,会发现二者有一些联系 |
- 先建立构建目录和dockerfile,编写内容,内容如图中所示,意为基础镜像选用的是ubuntu镜像,在这基础上运行操作“echo testfile1 > testfile1”和操作“echo testfile2 > testfile2”。
此处要说明:每一个RUN就代表着一层自定义镜像层,即使是简单的命令,只要写了RUN,自定义镜像层就会多一层。
文章图片
- 使用docker build命令自动构建新镜像,名为co2:1,构建目录为当前目录。
可以在构建过程中看到:每构建一个RUN,就会开启一个临时容器去运行这个RUN所执行的命令,运行完毕后提交该容器内容为一个新镜像,并且删除该临时容器,生成一个新的临时镜像。当所有的RUN都构建完成后,最终的临时镜像就会变成真正的新镜像,此时再给该新镜像打上名字和标签。
说到开启一个临时容器,执行操作,提交容器内容,生成新镜像。这个流程是不是觉得有些熟悉?
没错,其实自动化构建镜像的过程中,就是通过docker commit来进行生成新临时镜像的。
文章图片
- 查看以下ubuntu镜像和co2镜像的构建历史,会发现co2镜像的构建历史中含有ubuntu镜像的ID,也就是说明ubuntu镜像是co2镜像的基础镜像,co2镜像是在此基础上加了两层构建的,图中可以清楚的看出来。这也验证了刚刚说的每一个RUN是一个新的自定义镜像层的特性。
并且从图中可以看出,自动化构建方式可以做镜像的审计,会写出在基础上执行了的新操作,这是与手动构建方式不同的一点。
文章图片
- 用co2:1镜像运行一个容器看看是否符合要求,发现testfile1和2都在,且内容正确,说明符合构建要求。
文章图片
使用自动化方式构建镜像还有一个好处就是有缓存特性,也就是说如果你想要在构建过的内容之上再添加新的内容再次构建,那么只有新的内容需要构建,而旧内容只需要使用缓存就可以了,能够将效率提高很多。
比如我们现在修改dockerfile的内容,增加一条新的RUN。
命令 | 功能 |
---|---|
vim dockerfile | 修改内容 |
docker build -t co2:2 . | 建立co2:2镜像,与刚刚的镜像标签不同作为区分 |
docker history co2:1 | 看一下co2:1的构建历史 |
docker history co2:2 | 再看一下co2:2的构建历史,二者有一些联系 |
- 增加了一条新的RUN作为新内容,其余不做改动。
注意:要想顺利使用缓存特性,旧内容一定不要做任何改动,不要有任何符号的添加删除。
文章图片
- 用新的dockerfile构建新的co2:2镜像,可以发现前两条RUN构建直接使用了缓存(Using
cache),提高了效率。
文章图片
- 根据二者的构建历史可以发现,co2:2比co2:1多了一层自定义镜像层,因为使用缓存的原因,co2:2的前几层镜像层ID与co2:1完全相同,使用缓存也就是说二者的这层是共享的自定义镜像层,就提高了构建效率,也节省了系统的资源。
文章图片
- 用co2:2打开一个容器,查看testfile3的内容,正确,符合构建要求。
文章图片
推荐阅读
- Linux|109 个实用 shell 脚本
- linux笔记|linux 常用命令汇总(面向面试)
- Linux|Linux--网络基础
- linux|apt update和apt upgrade命令 - 有什么区别()
- linux|2022年云原生趋势
- 个人日记|K8s中Pod生命周期和重启策略
- k8s|k8s(六)(配置管理与集群安全机制)
- Go|Docker后端部署详解(Go+Nginx)
- docker|Docker
- 开源生态|GPL、MIT、Apache...开发者如何选择开源协议(一文讲清根本区别)