docker 容器保存为镜像_Docker镜像/容器详解(一)

容器之所以如此流行,是因为:第一,它解决了环境一致性问题;第二,它不像虚拟机如此消耗系统性能;第三,它的启停灵活快速,没有虚拟机那么多冗杂的操作。

大家都知道,容器是一个相对隔离的环境。也就是说, 容器里的应用进程,应该看到的是一份独立的文件系统。 它在容器内的操作,不会影响外部或其它容器的文件系统。

为了让容器的根目录看起来更真实,我们一般会在这个容器的根目录下挂载一个完整操作系统的文件系统。比如,在CentOS容器里看到的根目录内容,和真正的CentOS操作系统根目录中的文件是一样的:

[root@88df060ef65f /]# ls
bin  dev  etc  home  lib  lib64  lost+found  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var

---
# 注意:这里的 ls 命令和在容器外执行的 ls 命令是完全不同的两个文件。

容器镜像实际上就是这个用来为容器进程提供隔离后执行环境的文件系统。我们也称之为根文件系统(Rootfs)。

注意, rootfs 只是一个操作系统所包含的文件、配置和目录,并不包括操作系统内核。同一台机器上的所有容器,都共享宿主机操作系统的内核。因此,如果你的应用程序需要操作内核,需要格外小心: 它将影响宿主机及运行在该机器上的所有容器。

由于 rootfs 里封装的不仅仅是应用,还包括它运行所需要的所有依赖。这就赋予了容器的强一致性:无论在本地、云端,还是其他任何地方,用户只需要解压打包好的容器镜像,这个应用运行所需要的完整的执行环境就被重现出来了。

但还有一个问题不容忽视的问题,例如如果我需要一个在CentOS环境中跑的apache应用,我可以将它打包成一个apache镜像;如果我还需要一个在CentOS环境中跑的mysql应用,我又将它打包成一个mysql镜像……大家应该看出问题所在了:这几个镜像中都有全部的CentOS的全部环境,将造成大量空间占用问题及碎片化问题。如何解决这些问题呢?

Docker的解决方法是: 在镜像的设计中,引入了层(layer)的概念。即: 用户制作镜像的每一步操作,都生成一个层,也就是一个增量 rootfs。

OverlayFS

Docker在镜像的设计中,用到了联合文件系统。

联合文件系统 (Union File System) 也叫 UnionFS,最主要的功能是将多个不同位置的目录 (这些目录被称为layer)联合挂载(union mount)到同一个目录下。Docker所用到的OverlayFS,就是联合文件系统中的一种。

在OverlayFS 中,底层的目录叫做 lowerdir,顶层的目录称之为 upperdir,对外展示统一视图的目录为merged。下图展示了Docker镜像和Docker容器是如何分层的。 镜像层是 lowerdir,容器层是 upperdir。暴露在外的统一视图是 merged:

c0cab85ad0867dd193fed6e43841fef3.png

A. 读文件

  • 目标文件不在容器层内,overlay会从镜像层读取文件
  • 目标文件在容器层内,overlay直接从容器层读取
  • 目标文件在容器层和镜像层同时存在,overlay读入容器层中的文件

B. 修改文件

  • 目标文件在容器层,则直接修改
  • 目标文件不在容器层,先将文件从镜像层copy到容器层,再进行修改

C. 删除文件

  • 若文件仅存在于容器层, 则直接删除文件
  • 若文件存在于镜像层,overlay存储驱动在容器层中创建标记文件,用于隐藏镜像层中的目标文件 - Whiteout
注: 任何写操作都不会去操作镜像层

下面通过一个小实验来理解OverlayFS

实验准备

[root@docker ~]# mkdir /test
[root@docker ~]# cd /test/
[root@docker test]# mkdir lower upper work merg
[root@docker test]# echo low > lower/1.txt
[root@docker test]# echo low > lower/2.txt
[root@docker test]# echo up > upper/1.txt
[root@docker test]# echo up > upper/3.txt

挂载为OverlayFS

# mount -t overlay overlay -o lowerdir=lower/,upperdir=upper/,workdir=work/ merg/
# df -h
Filesystem           Size  Used Avail Use% Mounted on
/dev/mapper/cl-root  8.0G  3.5G  4.6G  44% /
/dev/sda1           1014M  121M  894M  12% /boot
overlay              8.0G  3.5G  4.6G  44% /test/merg

验证

A. 读文件

# 目标文件不在容器层, 从镜像层读取文件
[root@docker test]# cat merg/2.txt 
low
​
# 目标文件在容器层, 直接从容器层读取
[root@docker test]# cat merg/3.txt 
up
​
# 目标文件同时存在于镜像和容器层, 读取容器层中的文件
[root@docker test]# cat merg/1.txt 
up

B. 修改文件

# 目标文件在容器层, 直接修改
[root@docker test]# echo "modify in merg" > merg/1.txt 
[root@docker test]# cat upper/1.txt 
modify in merg
[root@docker test]# cat lower/1.txt 
low
​
# 目标文件不在容器层, 先将文件从镜像层copy到容器层,再进行修改
[root@docker test]# ls upper/
1.txt  3.txt
[root@docker test]# echo "modify in merg" > merg/2.txt 
[root@docker test]# cat lower/2.txt 
low
[root@docker test]# cat upper/2.txt 
modify in merg

C. 删除文件

# 仅存在于容器层, 则直接删除文件
[root@docker test]# rm -rf merg/3.txt 
[root@docker test]# ll upper/
total 8
-rw-r--r-- 1 root root 15 Feb 24 01:20 1.txt
-rw-r--r-- 1 root root 15 Feb 24 01:25 2.txt
​
# 在容器层中创建标记文件,用于隐藏镜像层中的目标文件 - Whiteout
[root@docker test]# rm -rf merg/1.txt 
[root@docker test]# ll upper/
total 4
c--------- 1 root root 0, 0 Feb 24 01:32 1.txt   # 标记文件,表示 1.txt 已被删除
-rw-r--r-- 1 root root   15 Feb 24 01:25 2.txt

未完待续……

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值