作者介绍:简历上没有一个精通的运维工程师。希望大家多多关注作者,下面的思维导图也是预计更新的内容和当前进度(不定时更新)。
我们在上一章,讲了虚拟化,虚拟化是把硬件虚拟化,然后创建出来的虚拟机完全隔离,而Docker则是软件(内核)虚拟化,他的隔离性会低于虚拟机。我们将通过3-4周来讲解Docker相关内容,由于涉及到内容较多,就不一一列出来具体的细节,主要从以下几个方面来讲解:
Docker基本情况
Docker基本命令
Dockerfile
Docker镜像
Docker仓库
Docker原理(本小节属于)
Docker网络&存储&日志
Docker-Compose
Docker番外篇
基于我们对联合文件的理解,我们来讲解写实复制(cow),其实在讲kvm-外部快照的时候也提到了这个技术。
当 Docker 第一次启动一个容器时,初始的读写层是空的,当文件系统发生变化时,这些变化都会应用到这一层之上。比如,如果想修改一个文件,这个文件首先会从该读写层下面的只读层复制到该读写层。由此,该文件的只读版本依然存在于只读层,只是被读写层的该文件副本所隐藏。该机制则被称之为写时复制(Copy on write)。下面就是几种文件操作的具体流程。
添加文件
在容器中创建文件时,新文件被添加到可读写层中。
容器里面创建新目录
csharp
[root@localhost ~]# docker exec -it df3 bash
[root@df36a78f937e /]# ls
anaconda-post.log bin dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var
[root@df36a78f937e /]# mkdir -p eee
UpperDir同步存在
这2个文件的inode都是一样的(本质上他们就是一个文件),有兴趣可以下去对比下。
读取文件
在容器中读取某个文件时,Docker 会从上往下依次在各镜像层中查找此文件。如果这个文件存在于下面的只读层中,Docker直接从该只读层读取文件内容,不涉及任何复制操作。这是因为读操作不会改变文件内容,所以可以安全地与其它容器共享。
修改文件
在容器中修改已存在的文件时,Docker 会从上往下依次在各镜像层中查找此文件。一旦找到,立即将其复制到容器层,然后修改之。举例来说,就是如果编辑一个已经存在的文件,当保存以后,UpperDir里面就会出现同路径下的的同名文件,以后的读写操作的就是这个文件。
但是这个实际显示和理解的逻辑出现了一点误差,比如我在容器里面查看一个文件,那么这个时候我看到应该是LowerDir的内容,他的inode是固定的不会变的,可以在LowerDir层和MergeDir层看到他的inode都是一样的,可以确认是一个文件。当我对这个文件进行修改以后,UpperDir层出现文件以后,他有新的inode,到这里都是没问题的。但是这个时候在去看MergeDir的inode还是没有变化,按照联合文件系统来解释,MergeDir=LowerDir+UpperDir,当文件冲突的时候以UpperDir为准,从内容来看是没问题的,但是inode这个时候应该是MergeDir和UpperDir一样才对,但是实际是MergeDir层的inode并没有发生改变。
删除文件
在容器中删除文件时,Docker 也是从上往下依次在镜像层中查找此文件。找到后,会在容器层中记录下此删除操作,原始文件不会被删除,此为白障(whiteout)这个白障我们通过例子来讲解。
perl
#我们进入容器删除了3个文件
[root@e8bd94fb3082 bin]# pwd
/bin
[root@e8bd94fb3082 bin]# ll |grep kill
-rwxr-xr-x 1 root root 33608 Sep 30 2020 kill
-rwxr-xr-x 1 root root 28336 Sep 30 2020 pkill
-rwxr-xr-x 1 root root 24184 Sep 30 2020 skill
[root@e8bd94fb3082 bin]# rm -rf kill skill pkill
[root@e8bd94fb3082 bin]# ll |grep kill
[root@e8bd94fb3082 bin]#
#UpperDir,这里就显示了3个特殊的文件,就是我们删除的3个文件
root@localhost bin]# docker inspect e8bd |grep -i UpperDir
"UpperDir": "/var/lib/docker/overlay2/5b817c1abadb32403449f9123c13c2d8b0f95ee9f402444e23e344b466b1b4ca/diff",
[root@localhost bin]# cd /var/lib/docker/overlay2/5b817c1abadb32403449f9123c13c2d8b0f95ee9f402444e23e344b466b1b4ca/diff
[root@localhost diff]# ls
usr
[root@localhost diff]# cd usr/bin/
[root@localhost bin]# ll
total 0
c--------- 1 root root 0, 0 Dec 5 09:57 kill
c--------- 1 root root 0, 0 Dec 5 09:57 pkill
c--------- 1 root root 0, 0 Dec 5 09:57 skill
运维小路
一个不会开发的运维!一个要学开发的运维!一个学不会开发的运维!欢迎大家骚扰的运维!
关注微信公众号《运维小路》获取更多内容。