文章目录
一、docker镜像详解
1.镜像分层结构
- 共享宿主机的kernel
- base镜像提供的是最小的Linux发行版(base镜像:不同发行版的/文件系统)
- 同一docker主机支持运行多种Linux发行版
- 采用分层结构的最大好处是:共享资源
镜像通过分层,如果本地已经有了,不管这一层属于哪个镜像,因为每一层都有独立的标识(都是唯一的),只要docker判断有这一层,那它就不会进行重复的拉取。包括在上传仓库的时候也是一样的,仓库内存储时也是按照层来存储的,如果远程仓库有这一层了,就不需要重复上传了,节省了带宽。
docker使用 Copy-on-Write 的机制(可写容器层),当我们想保存一个数据的时候,由于镜像是只读的,当我们创建容器时,是在镜像层的上面创建一个可写容器层,所有对容器的修改都会放置在可写容器层上,只要这个容器不被释放,这个数据一直存在,除非把这个容器删掉。如果想保存,把可写容器层进行打包,即把它创建成一个镜像层,一旦成为镜像层它就变成只读模式了(最多127层)。
镜像层数量可能会很多,所有镜像层会联合在一起组成一个统一的文件系统。如果不同层中有一个相同路径的文件,比如 /a,上层的 /a会覆盖下层的 /a,也就是说用户只能访问到上层中的文件 /a。在容器层中,用户看到的是一个叠加之后的文件系统。
- 添加文件:在容器中创建文件时,新文件被添加到容器层中;
- 读取文件:在容器中读取某个文件时,Docker会从上往下依次在各镜像层中查找此文件。一旦找到,立即将其复制到容器层,然后打开并读入内存;
- 修改文件:在容器中修改已存在的文件时,Docker 会从上往下依次在各镜像层中查找此文件。一旦找到,立即将其复制到容器层,然后修改之;
- 删除文件:在容器中删除文件时,Docker 也是从上往下依次在镜像层中查找此文件。找到后,会在容器层中记录下此删除操作;
只有当需要修改时才复制一份数据,这种特性被称作Copy-on-Write。可见,容器层保存的是镜像变化的部分,不会对镜像本身进行任何修改。这样就解释了我们前面提出的问题:容器层记录对镜像的修改,所有镜像层都是只读的,不会被容器修改,所以镜像可以被多个容器共享。
2.镜像的表示
镜像的表示分为四部分:红色的部分是镜像中心域名,黄色的部分是镜像命名空间,我们可以根据命名空间进行权限控制等操作,绿色是镜像的名称,每个镜像有一个版本(即标签)。Docker官方的镜像不需要镜像中心的域名,有一些镜像可以省略命名空间。
base 镜像简单来说就是不依赖其他任何镜像,完全从0开始建起,其他镜像都是建立在他的之上,可以比喻为大楼的地基,docker镜像的鼻祖。
base 镜像有两层含义:
(1)不依赖其他镜像,从 scratch 构建;
(2)其他镜像可以之为基础进行扩展。
所以,能称作 base 镜像的通常都是各种 Linux 发行版的 Docker 镜像,
比如 Ubuntu, Debian, CentOS 等。
二、镜像构建
1.commit提交
docker commit 构建新镜像三部曲
- 运行容器
- 修改容器
- 新的镜容器保存为镜像
拉取一个具有一个小工具的镜像:
由于busybox是基础镜像不是应用镜像,基础镜像不像应用镜像可以打到后台,只能以交互式方式打开:
docker镜像、容器相关命令如下:
使用下面这个指令可以看到容器的构建历史:
[root@server1 ~]# docker run -it --name demo busybox ##生成容器demo
/ # touch file1 ##ctrl+d: 退出容器后容器自动关闭
## -it:以交互式的方式创建容器
/ # touch file2 ##ctrl+pq: 退出容器后继续在后台运行
##已经停止的容器,删除后,创建的文件会丢失,因为容器内的变更都保存在可写容器层,生命周期和容器一致
显示所有容器
[root@server1 ~]# docker ps -a
启动容器
[root@server1 ~]# docker start demo
进入容器
[root@server1 ~]# docker attach demo
提交容器变更到新的镜像
[root@server1 ~]# docker commit -m "add files" demo demo:v1 ##通过容器生成镜像(保存了更改至新的镜像层)
[root@server1 ~]# docker history demo:v1
IMAGE CREATED CREATED BY SIZE COMMENT
2b25ea847e4e 9 seconds ago sh 39B add files##比旧的镜像多的部分
827365c7baf1 13 days ago /bin/sh -c #(nop) CMD ["sh"] 0B
<missing> 13 days ago /bin/sh -c #(nop) ADD file:3f2f2548e5ddec788… 4.86MB
Ctrl+d就退出容器了,此时容器会被stop掉,但是并不会被删除. 我们再启动容器就可以再次进入容器,我们还可以使用 ctrl+p+q 三个键同时按下,就可以将其打入后台运行而不是stop掉,我们也可以手动stop掉容器,我们将刚刚创建的容器删除再进去,就会发现我们刚刚创建的文件已经没有了, 这是因为我们在容器层把这个容器释放掉以后就没有了,如果我们想将数据保存下来,就需要将我们自己的镜像打包:
对比源镜像和我们自己打包的镜像,只比源镜像多了一层,就是我们刚刚创建文件的命令:
commit提交的缺点:我们发现在删除时它也只删除了一层,就是我们刚刚创建文件的那一层,基础的busybox镜像它是不会删除的。我们发现这种构建方式不是非常方便,他的缺点