docker镜像(一)overlayfs

一、Docker使用的存储引擎

Docker镜像是分层的结构,一个镜像一般是由多层镜像所构成的,然后通过联合文件系统,把各个镜像层进行组合,形成rootfs供容器使用。

现在docker默认使用的存储引擎是overlay2

# docker info
Storage Driver: overlay2
  Backing Filesystem: xfs
  Supports d_type: true
  Native Overlay Diff: true

二、什么是overlayfs?

Overlayfs是一种堆叠文件系统,它依赖并建立在其它的文件系统之上(例如ext4fs和xfs等等),并不直接参与磁盘空间结构的划分,仅仅将原来底层文件系统中不同的目录进行“合并”,然后向用户呈现。因此对于用户来说,它所见到的overlay文件系统根目录下的内容就来自挂载时所指定的不同目录的“合集”。

三、使用overlayfs

挂载一个overlay文件系统,可以使用如下命令

mount -t overlay -o <options> overlay <mount point>
mount -t overlay -o lowerdir=/dir1:/dir2:/dir3:...:/dir25,upperdir=... overlay <mount point>

<mount point>是最终overlay的挂载点,其中overlay的options有如下:

  • lowerdir=<dir>:指定用户需要挂载的lower层目录,lower层支持多个目录,用“:”间隔,优先级依次降低。最多支持500层。
  • upperdir=<dir>:指定用户需要挂载的upper层目录,upper层优先级高于所有的lower层目录。
  • workdir=<dir>:指定文件系统挂载后用于存放临时和间接文件的工作基础目录。
  • default_permissions:
  • redirect_dir=on/off:开启或关闭redirect directory特性,开启后可支持merged目录和纯lower层目录的rename/renameat系统调用。
  • index=on/off:开启或关闭index特性,开启后可避免hardlink copyup broken问题。

让我们实例操作下

docker镜像(一)overlayfs

 

 

# mkdir -p lower/common-dir
# mkdir -p lower/lower-dir
# mkdir -p upper/common-dir
# mkdir -p upper/upper-dir
# mkdir merge work
# echo From lower >>lower/common-dir/lower-file
# echo From lower >>lower/lower-dir/lower-file
# echo From lower >>lower/lower-file
# echo From lower >>lower/common-file

# echo From upper >>upper/common-dir/upper-file
# echo From upper >>upper/upper-dir/upper-file
# echo From upper >>upper/upper-file
# echo From upper >>upper/common-file

# mount -t overlay \
-o lowerdir=/data/lower,upperdir=/data/upper,workdir=/data/work \
overlay /data/merge

# tree merge/
merge/
|-- common-dir
|   |-- lower-file
|   `-- upper-file
|-- common-file
|-- lower-dir
|   `-- lower-file
|-- lower-file
|-- upper-dir
|   `-- upper-file
`-- upper-file
# more merge/common-file 
From upper

1、在merge目录创建文件或目录,新建的文件或目录会出现在upper目录的对应位置

# mkdir merge/new-dir
# touch merge/new-file merge/common-dir/new-file merge/lower-dir/new-file
# ll */new-file
-rw-r--r-- 1 root root 0 Oct  5 16:29 merge/new-file
-rw-r--r-- 1 root root 0 Oct  5 16:29 upper/new-file
# ll -d */new-dir
drwxr-xr-x 2 root root 6 Oct  5 16:28 merge/new-dir
drwxr-xr-x 2 root root 6 Oct  5 16:28 upper/new-dir
# ll */common-dir/new-file 
-rw-r--r-- 1 root root 0 Oct  5 16:29 merge/common-dir/new-file
-rw-r--r-- 1 root root 0 Oct  5 16:29 upper/common-dir/new-file
# ll */lower-dir/new-file
-rw-r--r-- 1 root root 0 Oct  5 16:29 merge/lower-dir/new-file
-rw-r--r-- 1 root root 0 Oct  5 16:29 upper/lower-dir/new-file

2、修改merge目录中的upper的文件,upper目录中相应的文件被修改

# echo new > merge/common-dir/upper-file  
# ll */common-dir/upper-file     
-rw-r--r-- 1 root root 4 Oct  6 10:42 merge/common-dir/upper-file
-rw-r--r-- 1 root root 4 Oct  6 10:42 upper/common-dir/upper-file
# echo new > merge/upper-dir/upper-file
# ll */upper-dir/upper-file
-rw-r--r-- 1 root root 4 Oct  6 10:45 merge/upper-dir/upper-file
-rw-r--r-- 1 root root 4 Oct  6 10:45 upper/upper-dir/upper-file
# echo new > merge/common-file 
# ll */common-file
-rw-r--r-- 1 root root 11 Oct  5 16:22 lower/common-file
-rw-r--r-- 1 root root  4 Oct  6 10:46 merge/common-file
-rw-r--r-- 1 root root  4 Oct  6 10:46 upper/common-file

3、修改merge目录中lower的文件,lower目录的中文件没有修改,upper目录拷贝了lower的文件,并进行修改

# echo new > merge/common-dir/lower-file # ll */common-dir/lower-file
-rw-r--r-- 1 root root 11 Oct  5 16:22 lower/common-dir/lower-file
-rw-r--r-- 1 root root  4 Oct  6 10:43 merge/common-dir/lower-file
-rw-r--r-- 1 root root  4 Oct  6 10:43 upper/common-dir/lower-file
# echo new > merge/lower-dir/lower-file 
# ll */lower-dir/lower-file
-rw-r--r-- 1 root root 11 Oct  5 16:22 lower/lower-dir/lower-file
-rw-r--r-- 1 root root  4 Oct  6 10:44 merge/lower-dir/lower-file
-rw-r--r-- 1 root root  4 Oct  6 10:44 upper/lower-dir/lower-file

4、重命名merge中的lower目录,lower目录没有变化,upper目录新增whitout文件和重命名后的目录

# mv merge/lower-dir merge/new-dir
# ll -d */lower-dir
drwxr-xr-x 2 root root   24 Oct  5 16:22 lower/lower-dir
c--------- 1 root root 0, 0 Oct  6 10:48 upper/lower-dir
# ll -d */new-dir
drwxr-xr-x 3 root root 23 Oct  6 10:48 merge/new-dir
drwxr-xr-x 3 root root 23 Oct  6 10:48 upper/new-dir

5、删除文件或目录
Whiteout文件在用户删除文件时创建,用于屏蔽底层的同名文件,同时该文件在merge中是不可见的,所以用户就看不到被删除的文件或目录了。
whiteout文件并非普通文件,而是主次设备号都为0的字符设备(可以通过"mknod <name> c 0 0"命令手动创建),当用户在merge中通过ls命令(将通过readddir系统调用)检查父目录的目录项时,overlayfs会自动过过滤掉和whiteout文件自身以及和它同名的lower层文件和目录,达到了隐藏文件的目的,让用户以为文件已经被删除了。
在merge目录无法看到任何文件,lower目录文件没有任何变化,upper目录删除了属于其的文件,并创建了whieout文件遮盖lower的文件

# rm -rf merge/*
# ll merge/*  
ls: cannot access merge/*: No such file or directory

# ll upper/*   
c--------- 1 root root 0, 0 Oct  6 10:55 upper/common-dir
c--------- 1 root root 0, 0 Oct  6 10:55 upper/common-file
c--------- 1 root root 0, 0 Oct  6 10:48 upper/lower-dir
c--------- 1 root root 0, 0 Oct  6 10:55 upper/lower-file

# ll lower/*  
-rw-r--r-- 1 root root 11 Oct  5 16:22 lower/common-file
-rw-r--r-- 1 root root 11 Oct  5 16:22 lower/lower-file

lower/common-dir:
total 4
-rw-r--r-- 1 root root 11 Oct  5 16:22 lower-file

lower/lower-dir:
total 4
-rw-r--r-- 1 root root 11 Oct  5 16:22 lower-file

五、在容器中的应用
Docker容器将镜像层(image layer)作为lower dir,将容器层(container layer)作为upper dir,最后挂载到容器merge挂载点,即容器的根目录下

docker镜像(一)overlayfs

 

# docker run -d ubuntu:latest sleep 3600
# docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
605074f51a09        ubuntu:latest       "sleep 3600"        17 minutes ago      Up 17 minutes                           nostalgic_murdock
# docker inspect 605074f51a09
        "GraphDriver": {
            "Data": {
                "LowerDir": 
"/var/lib/docker/overlay2/e79c703ecfde4f4d62ac45a8006708b9557eea24743adb7b03881f699aafc56c-init/diff:
/var/lib/docker/overlay2/261602d78f852f9ebff7ffa4bc3b39469738e4a280f50886d797fb687b7e8703/diff:
/var/lib/docker/overlay2/3a613e532ba2bc17f964c5379070bb1c3a1408b9df958346cfa693463fd41290/diff:
/var/lib/docker/overlay2/b066cee05900179651f310ff3e8acbe2728236c7813cdb551a069765c9427204/diff",
                "MergedDir": "/var/lib/docker/overlay2/e79c703ecfde4f4d62ac45a8006708b9557eea24743adb7b03881f699aafc56c/merged",
                "UpperDir": "/var/lib/docker/overlay2/e79c703ecfde4f4d62ac45a8006708b9557eea24743adb7b03881f699aafc56c/diff",
                "WorkDir": "/var/lib/docker/overlay2/e79c703ecfde4f4d62ac45a8006708b9557eea24743adb7b03881f699aafc56c/work"
            },
            "Name": "overlay2"
        },


Lower层,容器镜像
"LowerDir": 
"/var/lib/docker/overlay2/e79c703ecfde4f4d62ac45a8006708b9557eea24743adb7b03881f699aafc56c-init/diff:
/var/lib/docker/overlay2/261602d78f852f9ebff7ffa4bc3b39469738e4a280f50886d797fb687b7e8703/diff:
/var/lib/docker/overlay2/3a613e532ba2bc17f964c5379070bb1c3a1408b9df958346cfa693463fd41290/diff:
/var/lib/docker/overlay2/b066cee05900179651f310ff3e8acbe2728236c7813cdb551a069765c9427204/diff",

# docker image inspect ubuntu:latest
        "RootFS": {
            "Type": "layers",
            "Layers": [
                "sha256:d42a4fdf4b2ae8662ff2ca1b695eae571c652a62973c1beb81a296a4f4263d92",
                "sha256:90ac32a0d9ab11e7745283f3051e990054616d631812ac63e324c1a36d2677f5",
                "sha256:782f5f011ddaf2a0bfd38cc2ccabd634095d6e35c8034302d788423f486bb177"
            ]
        },

镜像由三层组成
# tree /var/lib/docker/overlay2/e79c703ecfde4f4d62ac45a8006708b9557eea24743adb7b03881f699aafc56c-init/diff
/var/lib/docker/overlay2/e79c703ecfde4f4d62ac45a8006708b9557eea24743adb7b03881f699aafc56c-init/diff
|-- dev
|   |-- console
|   |-- pts
|   `-- shm
`-- etc
    |-- hostname
    |-- hosts
    |-- mtab -> /proc/mounts
`-- resolv.conf


Upper层
"UpperDir": "/var/lib/docker/overlay2/e79c703ecfde4f4d62ac45a8006708b9557eea24743adb7b03881f699aafc56c/diff",

# ll /var/lib/docker/overlay2/e79c703ecfde4f4d62ac45a8006708b9557eea24743adb7b03881f699aafc56c/diff
total 0
空目录

Merge目录
"MergedDir": "/var/lib/docker/overlay2/e79c703ecfde4f4d62ac45a8006708b9557eea24743adb7b03881f699aafc56c/merged",

Work目录
"WorkDir": "/var/lib/docker/overlay2/e79c703ecfde4f4d62ac45a8006708b9557eea24743adb7b03881f699aafc56c/work"

docker镜像(一)overlayfs

 

上一篇:图标基本元素


下一篇:使用 Python 为女神挑选口红 ,成功把女神拿下,你学会了吗