1.Mount Namespace 修改的,是容器进程对文件系统“挂载点”的认知。但是,这也就意味着,只有在“挂载”这个操作发生之后,进程的视图才会被改变。而在此之前,新创建的容器会直接继承宿主机的各个挂载点。
解决办法:创建新进程时,除了声明要启用 Mount Namespace 之外,我们还可以告诉容器进程,有哪些目录需要重新挂载
2.Mount Namespace 跟其他 Namespace 的使用略有不同的地方:它对容器进程视图的改变,一定是伴随着挂载操作(mount)才能生效。
这个挂载在容器根目录上、用来为容器进程提供隔离后执行环境的文件系统,就是所谓的“容器镜像”。它还有一个更为专业的名字,叫作:rootfs(根文件系统)
3.对 Docker 项目来说,它最核心的原理实际上就是为待创建的用户进程:启用 Linux Namespace 配置; 设置指定的 Cgroups 参数;切换进程的根目录(Change Root)。
需要明确的是,rootfs 只是一个操作系统所包含的文件、配置和目录,并不包括操作系统内核。在 Linux 操作系统中,这两部分是分开存放的,操作系统只有在开机启动时才会加载指定版本的内核镜像。
4.Docker 在镜像的设计中,引入了层(layer)的概念。也就是说,用户制作镜像的每一步操作,都会生成一个层,也就是一个增量 rootfs。
5.Union File System 也叫 UnionFS(联合文件系统),最主要的功能是将多个不同位置的目录联合挂载(union mount)到同一个目录下。
6.AuFS 的全称是 Another UnionFS,后改名为Alternative UnionFS,再后来干脆改名叫作Advance UnionFS,从这些名字中你应该能看出这样两个事实:它是对 Linux 原生 UnionFS 的重写和改进;
AuFS 来说,它最关键的目录结构在
/var/lib/docker/aufs/diff/<layer_id>
实验:
Docker 镜像使用的 rootfs,往往由多个“层”组成:
docker run -d ubuntu:latest sleep 3600
"RootFS": {
"Type": "layers",
"Layers": [
"sha256:bc7f4b25d0ae3524466891c41cefc7c6833c533e00ba80f8063c68da9a8b65fe",
"sha256:a768c3f3878e96565d2bf0dcf90508261862847b2e7b8fc804a0770c07f0d5d5",
"sha256:ca2991e4676cba899ad9bc6ad3a044cd0816915f9e97a6f2e67b6accbc779ba5",
"sha256:b9b7103af585bd8ae9130de947817be7ce76092aa19cf6d2f9d5290440c645eb"
]
}
/var/lib/docker/overlay2目录,通过docker inspect命令可以查看到镜像在该目录下生成的各种目录文件,
LowerDir:指向镜像层;
UpperDir:指向容器层,在容器中创建文件后,文件出现在此目录;
MergedDir:容器挂载点 ,lowerdir和upperdir整合起来提供统一的视图给容器,作为根文件系统;
WorkDir:用于实现copy_up操作。
docker run -d ubuntu:latest sleep 3600
"Data": {
"LowerDir": "/var/lib/docker/overlay2/a4ab1062db4130d37292706d5f6ad8880b1f15cf6dcf47077cf83c0e36a782f0/diff:/var/lib/docker/overlay2/f8cf3d1e69744cbb66377aa589a2305778b65b28012ea1d9ab9d17cc7fca205e/diff:/var/lib/docker/overlay2/4f1e076eb451fe684911eb2f1c693ed6f648ef8e3b0e338c1d5e76f24d00a05e/diff",
"MergedDir": "/var/lib/docker/overlay2/9d183dbfff848b438892d95a423e33a7629ec9325dae3fa1d926ced6d5bf6ea3/merged",
"UpperDir": "/var/lib/docker/overlay2/9d183dbfff848b438892d95a423e33a7629ec9325dae3fa1d926ced6d5bf6ea3/diff",
"WorkDir": "/var/lib/docker/overlay2/9d183dbfff848b438892d95a423e33a7629ec9325dae3fa1d926ced6d5bf6ea3/work"
}
},
7.只读层,挂载方式ro+wh,即 readonly+whiteout
8.可读写层,挂载方式为rw,即 read write。在没有写入文件之前,这个目录是空的。而一旦在容器里做了写操作,你修改产生的内容就会以增量的方式出现在这个层中。
如果我现在要做的,是删除只读层里的一个文件呢? 为了实现这样的删除操作,AuFS 会在可读写层创建一个 whiteout文件,把只读层里的文件“遮挡”起来。你要删除只读层里一个名叫 foo 的文件,那么这个删除操作实际上是在可读写层创建了一个名叫.wh.foo 的文件。这样,当这两个层被联合挂载之后,foo 文件就会被.wh.foo 文件“遮挡”起来,“消失”了。这个功能,就是“ro+wh”的挂载方式,即只读 +whiteout 的含义
9.Init层
它是一个以“-init”结尾的层,夹在只读层和读写层之间。Init 层是 Docker 项目单独生成的一个内部层,专门用来存放 /etc/hosts等
10.上面的读写层通常也称为容器层,下面的只读层称为镜像层,所有的增删查改操作都只会作用在容器层,相同的文件上层会覆盖掉下层。知道这一点,就不难理解镜像文件的修改,比如修改一个文件的时候,首先会从上到下查找有没有这个文件,找到,就复制到容器层中,修改的结果就会作用到下层的文件,这种方式也被称为copy-on-write。
11.UnionFS包括但不限于以下这几种:aufs, device mapper, btrfs, overlayfs, vfs, zfs。aufs是ubuntu 常用的,device mapper 是 centos,btrfs 是 SUSE,overlayfs ubuntu 和 centos 都会使用,现在最新的 docker 版本中默认两个系统都是使用的 overlayfs,vfs 和 zfs 常用在 solaris 系统。