容器的文件系统

通过镜像的文件系统,我们知道了文件系统,联合文件系统,镜像分层,镜像元数据,镜像分层后的各层文件存储;

那么镜像运行成容器后,存于何处呢?

一个容器完整的层应由三个部分组成:

镜像层:也称为rootfs,提供容器启动的文件系统。rootfs也就是我们上一节中分析的image文件。镜像层属于roLayer。
init层: 用于修改容器中一些文件如/etc/hostname,/etc/hosts,/etc/resolv.conf等。init层属于mountedLayer。
容器层:使用联合挂载统一给用户提供的可读写目录。容器层属于mountedLayer。

因为镜像一般都是只读的,修改在容器层;

运行一个容器:docker run -it --name test ubuntu /bin/bash

我们来看一下mountedLayer的元数据目录:

cd /var/lib/docker/image/overlay2/layerdb/mounts && ls
f355cfb27b74a08589322650f7570f7bebb9fd3b7d6ae2a55fda60044f5b6dfa
[root@VM-12-7-centos mounts]# tree
.
`-- f355cfb27b74a08589322650f7570f7bebb9fd3b7d6ae2a55fda60044f5b6dfa
    |-- init-id
    |-- mount-id
    `-- parent

 cat init-id 
4718d46203109184ad2876462456ac651312ed933dee3898179ddfc711fa9164-init
cat mount-id 
4718d46203109184ad2876462456ac651312ed933dee3898179ddfc711fa9164
 cat parent 
sha256:0214f4b057d78b44fd12702828152f67c0ce115f9346acc63acdf997cab7e7c8

可以看到该文件夹有3种文件:

  • mount-id:存储在/var/lib/docker/overlay2/的目录名称。

  • init-id:initID是在mountID后加了一个-init,同时initID就是存储在/var/lib/docker/overlay2/的目录名称。

  • parent:容器所基于的镜像的最上层的chain_id。(注意这个parent和镜像Layer元数据的parent的不同之处)

我们再来看看/var/lib/docker/overlay2/下的内容

[root@VM-12-7-centos mounts]# ll /var/lib/docker/overlay2/
total 28
2fe7941e58c703d680c08c074bd73df87aabc4d65a61f267b2314301e7ace5d2
31c568526ac00784db29f2581eb501d0b2861526c092c721a22b8c59db8318e5
4718d46203109184ad2876462456ac651312ed933dee3898179ddfc711fa9164
4718d46203109184ad2876462456ac651312ed933dee3898179ddfc711fa9164-init
59b99b583de5c6e507325415775c77f1096ae885814713ebf40a740a5bcfac0e
9e039848a3fd3dd1b5f32f3fa9951772619701697313eb71ea7e21b64986c82c

我们发现新增了4718d46203109184ad2876462456ac651312ed933dee3898179ddfc711fa91644718d46203109184ad2876462456ac651312ed933dee3898179ddfc711fa9164-init两个哈希值的文件夹

并且目录名和mount-id,init-id的内容一致;

再分别看一下4718d46203109184ad2876462456ac651312ed933dee3898179ddfc711fa91644718d46203109184ad2876462456ac651312ed933dee3898179ddfc711fa9164-init

 cd 4718d46203109184ad2876462456ac651312ed933dee3898179ddfc711fa9164-init/
tree
.
|-- committed
|-- diff
|   |-- dev
|   |   `-- console
|   `-- etc
|       |-- hostname
|       |-- hosts
|       |-- mtab -> /proc/mounts
|       `-- resolv.conf
|-- link
|-- lower
`-- work
    `-- work

我们看到,diff里面只有一些/etc/hosts、/etc/resolv.conf等配置文件。需要这一层的原因是当容器启动时候,这些本该属于image层的文件或目录,比如hostname,用户需要修改,但是image层又不允许修改,所以启动时候通过单独挂载一层init层,通过修改init层中的文件达到修改这些文件目的。而这些修改往往只读当前容器生效,而在docker commit提交为镜像时候,并不会将init层提交。

再来看看容器层的内容:

cd 4718d46203109184ad2876462456ac651312ed933dee3898179ddfc711fa9164
 ls
diff  link  lower  merged  work
 ll diff
total 0
ls merged/
bin  boot  dev  etc  home  lib  lib64  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var

我们可以看到merged目录就是容器内部进程所看到的文件目录,他是由镜像层,init层与容器层联合挂载而来的。就跟之前我们举的联合挂载系统的例子一样;

另外可以看到diff文件夹是空的,说明容器还未对文件进行任何修改。如果修改,diff目录会相应发生变化;

如在容器中新增test.txt文件

docker run -it --name myubuntu  ubuntu:16.04 /bin/sh
# ls
bin  boot  dev    etc  home  lib    lib64  media  mnt  opt    proc  root  run  sbin  srv  sys  tmp  usr  var
# cd /opt
# ls
# touch test.txt

查看diff变化:

cd diff/
[root@VM-12-7-centos diff]# ls
opt
[root@VM-12-7-centos diff]# cd opt/
[root@VM-12-7-centos opt]# ls
test.txt

总结

容器的文件系统是在底层的容器的基础上使用联合挂载新增了一层读写层(分层);并使用了写时复制技术;

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值