Docker文件系统
Docker镜像是一层层构建的,其文件系统是一种联合文件系统,这种文件系统不是传统意义上的linux文件系统(如ext4,xfs,direct-lvm,btrfs,zfs等),并不直接参与磁盘空间的划分,而是基于底层的linux文件系统,联合文件系统中各目录所呈现。因此对于容器来讲,其根目录是挂载了多个目录的合集(merged,df即可查看)。
Docker不同文件系统对应不同的存储驱动。通过存储驱动来管理镜像层和可写容器层的内容。每个存储驱动程序对实现的处理方式不同,但是基本所有驱动程序都使用可堆叠的镜像层和写时复制(CoW)策略(除VFS外)。
CoW(Copy-on-write)
写时复制是一种共享和复制文件的策略。我们知道docker镜像层是只读的,所有容器的改变都仅发生在其容器读写层,如果容器层需要修改镜像层文件时,会将镜像层文件复制到该层并进行修改。如果容器对镜像层文件读操作时,则它可以直接读取镜像层文件。
多个容器是可以共享镜像的,通常镜像已经包含完整的应用和配置了,容器间彼此的差异只在于自己的容器层,该层只包含了将该容器系统与其他容器区分开来的内容,甚至,有些容器使用的是完全一样的镜像。在这些场景中,写时复制就可以非常有效地节省IO和后续层大小。
Docker写时复制缺点:容器进程写入时,整个文件会被复制和编辑,即便只是大文件的一部分被修改,整个文件都需要被复制,会增加容器系统大小且消耗容器IO。因此不适合写密集型应用,如数据库。这种情况可以通过外挂数据卷提高写性能。
Docker文件系统,存储驱动和底层文件系统对应关系:
本文仅介绍Overlayfs和对应的存储驱动Overlay2。Docker 18.09在主流linux系统中都默认使用overlay2驱动。
如果考虑修改为overlay2驱动,请确保Linux内核的版本4.0或更高版本,或者使用3.10.0-514及更高版本的RHEL或CentOS。
注意:更改存储驱动程序时,所有现有的镜像和容器都将无法访问。这是因为新存储驱动程序无法使用其镜像层。如果还原更改,则可以再次访问旧的就给镜像和容器,但是使用新驱动程序提取或创建的任何镜像和容器将无法访问。
# 修改docker存储驱动:
# systemctl stop docker
# cp -au /var/lib/docker /var/lib/docker.bak
# 创建或编辑/etc/docker/daemon.json,写入一些内容,注意json文件格式:
{
"storage-driver": "overlay2"
}
# systemctl start docker
# docker info
Containers: 1
Running: 1
Paused: 0
Stopped: 0
Images: 24
Server Version: 18.09.1
Storage Driver: overlay2
Backing Filesystem: xfs
...
使用Overlayfs驱动程序 – Overlay2
OverlayFS
官方介绍: OverlayFS是一种联合文件系统,在单个Linux主机上分层两个目录,并将它们显示为单个目录。这些目录称为“ 层”,统一过程称为“ 联合安装”。OverlayFS指的是下层目录lowerdir和上层目录upperdir。统一视图通过其自己的目录公开merged。
- 下层目录(lowerdir):镜像层,只读
- 上层目录(upperdir):容器层,可读写
- 统一目录:merged,联合挂载目录
overlay2
overlay2 是overlayfs的存储驱动,overlayfs还支持overlay驱动,但overlay2更加稳定且支持多层