4.Docker存储引擎

Docker存储驱动程序

目前docker的默认存储引擎为overlay2,不同的存储引擎需要相应的文件系统支持,如需要磁盘分区的时候传递d-type稳健分层功能,即需要传递内核参数并开启格式化磁盘的时候指定的功能

  • 历史更新信息

https://github.com/moby/moby/blob/master

  • 存储引擎的选择文档

https:/docs.docker.com/storage/storagedriver/select-storage-driver/

容器和层

我们构建 Docker 镜像一般采用 Dockerfile 的方式,而 Dockerfile 的每行命令,其实就会生成一个“层”,即使什么文件都没有添加。

FROM ubuntu:15.04
COPY . /app
RUN make /app
CMD python /app/app.py

基于Ubuntu映像的容器层

Docker 的镜像(image)是静态的,所以当镜像构建完成后,所有的层都是只读的,并会赋予一个唯一的 ID。而容器(container)是动态的,当容器启动后,Docker 会给这个容器创建一个可读写“层”,位于所有镜像“层”的最上面。我们对容器的所有操作也就是在这个“层”里完成,当我们执行 docker commit 将容器生成镜像的时候,就是把这个“层”给拍了个快照,添加了一个新的只读层。

文件的创建是在读写层增加文件,那修改和删除呢?

这就要提一下 Docker 设计的 copy-on-write (CoW) 策略。

当我们试图读取一个文件时,Docker 会从上到下一层层去找这个文件,找到的第一个就是我们的文件。所以下面层相同的文件就被“覆盖”了。而修改就是当我们找到这个文件时,将它“复制”到读写层并修改,这样读写层的文件就是我们修改后的文件,并且“覆盖”了镜像中的文件了。而删除就是创建了一个特殊的 whiteout 文件,这个 whiteout 文件覆盖的文件即表示删除了。

这样的设计有什么好处吗?

显而易见的就是减少了存储空间,由于镜像被分成了多个层,而各个层是静态只读的,是可以共享的。当你从一个镜像构建另一个镜像时,只需要添加新的层,原有的层不会被复制。

我们可以用 docker history 命令查看我们创建的镜像,相同的层将共享且只保存一份。

我们可以在系统的 /var/lib/docker/<存储驱动>/ 下看到我们所有的层。

第二个好处是启动容器就变得非常轻量和快速。因为我们的容器只是添加了一个“空”的读写层,其他的都是复用的只读层,需要用时才会去搜索。

共享相同图像的容器

存储驱动

存储驱动类型

AUFS

AUFSAnotherUnionFileSystem是一种UnionFS。V2版本后更名为 advanced multi‐layered unification fileystem,即高级多层统一文件系统。所谓UnionFS就是把不同物理位置的目录合并mount到同一个目录中。简单来说就是支持将不同目录挂载到同一个虚拟文件系统下的文件系统。这种系统可以一层一层的叠加修改文件。无论底下有多少层都是只读,只有最上层的文件系统是可读写。当需要修改一个文件时,AUFS创建该文件的一个副本。使用CoWCopy-on-Write将文件从只读层复制到可写层进行修改,结果也保留在可写层、在Docker中。底下的制度层就是image,可写层就是Container。

在 Ubuntu 14.04 系统上现有如下目录结构:

$ tree
.
├── fruits
│   ├── apple
│   └── tomato
└── vegetables
    ├── carrots
    └── tomato

输入以下几个命令:

# 创建一个mount目录
$ mkdir mnt
 
# 把水果目录和蔬菜目录union mount到 ./mnt目录中
$ sudo mount -t aufs -o dirs=./fruits:./vegetables none ./mnt
 
#  查看./mnt目录
$ tree ./mnt
./mnt
├── apple
├── carrots
└── tomato

我们来修改一下其中的文件内容:

$ echo mnt > ./mnt/apple
$ cat ./mnt/apple
mnt
$ cat ./fruits/apple
mnt

上面的示例,我们可以看到./mnt/apple的内容改了,./fruits/apple的内容也改了。

$ echo mnt_carrots > ./mnt/carrots
$ cat ./vegetables/carrots
 
$ cat ./fruits/carrots
mnt_carrots

AUFS是Docker18.06及更早版本的首选存储驱动程序,在内核3.13上运行Unbantu14.04时不支持overlay2

Overlay

一种Union FS文件系统,Linux内核3.18后支持

Overlay2

overlay的升级版,到目前为止,所有Linux发行版推荐使用的存储类型

devicemapper

是CentOS和RHEL的推荐存储驱动程序,但是依赖于direct-lvm,存在空间受限的问题,虽然可以通过后期配置解决;因为之前的内核版本不支持overlay2(集中在Centos/RHEL7.2之前版本);但当前较新版本Centos和RHEL现已经支持overlay2。

https://www.cnblogs.com/youruncloud/p/5736718.html

zfs/btrfs(Oracle-2007)

目前没有广泛应用;这些文件系统允许使用高级选项,例如创建“快照”,但需要更多的维护和设置。并且每一个都依赖于正确配置的后备文件系统。

vfs

用于测试环境,适用于无法适用Cow文件系统的情况。此存储驱动程序的性能很差,通常不建议在生产中使用。

Linux发行版 推荐的存储驱动程序 替代驱动
Docker Engine-Ubuntu上的社区 overlay2aufs(对于在内核3.13上运行的Ubuntu 14.04) overlaydevicemapper zfsvfs
Docker Engine-Debian上的社区 overlay2(Debian Stretch)aufsdevicemapper(旧版本) overlayvfs
Docker Engine-CentOS上的社区 overlay2 overlaydevicemapper zfsvfs
Docker Engine-Fedora上的社区 overlay2 overlaydevicemapper zfsvfs

1)overlay存储驱动程序已在Docker Engine-Enterprise 18.09中弃用,并将在以后的版本中删除。建议将overlay存储驱动程序的用户迁移到overlay2

2)devicemapper存储驱动程序已在Docker Engine 18.09中弃用,并将在以后的版本中删除。建议将devicemapper存储驱动程序的用户迁移到overlay2

建议使用overlay2存储驱动程序。首次安装Docker时,默认情况下使用overlay2。早期版本,默认情况下会使用aufs。如果要在新版本中使用aufs,则需要对其配置,并且可能需要安装其他软件包,例如linux-image-extra

支持的文件系统

对于Docker,支持文件系统是所在的文件系统 /var/lib/docker/。一些存储驱动程序仅适用于特定的后备文件系统。

存储驱动 支持的后备文件系统
overlay2overlay xfs 在ftype = 1的情况下, ext4
aufs xfsext4
devicemapper direct-lvm
btrfs btrfs
zfs zfs
vfs 任何文件系统
  • overlay2,,aufsoverlay都在文件级别而不是块级别运行。这样可以更有效地使用内存,但是在写繁重的工作负载中,容器的可写层可能会变得非常大。
  • 块级存储驱动器,例如devicemapperbtrfszfs更好地为写繁重的工作负担(虽然不如Docker volumes)执行。
  • 对于许多小型写入或具有多层或深文件系统的容器,其性能 overlay可能比更好overlay2,但会消耗更多的inode,这可能导致inode耗尽。
  • btrfszfs需要大量内存。
  • zfs 对于高密度工作负载(例如PaaS)是一个不错的选择。


如果docker 数据目录是一块单独的磁盘分区而且是xfs格式的,那么需要在格式化的时候加上参数 -n ftype=1,否则后期在启动容器的时候会报错不支持dtype 。

报错界面:

修改更换存储引擎

配置 Docker 存储驱动非常简单,只需要修改配置文件即可。

注意:如果你原先有不同存储驱动的层数据,更换存储驱动后将不可用,建议备份镜像并清除 /var/lib/docker 下所有数据。

备份镜像可以用 docker save 导出镜像,之后用 docker load 导入镜像。

修改前现先fdisk -l查看文件系统类型

摘掉挂载umount /var/lib/docker

注意:可能会出现umount: /var/lib/docker: target is busy.

关闭占用进程fuser -km /var/lib/docker(慎用fuser -km)。在psmisc包中yum install psmisc -y

或者systemctl stop docker再次进行卸载

对文件系统进行类型格式化mkfs.xfs -n ftype=1 /dev/sdX ormkfs.ext4 /dev/sdX

再次进行挂载mount /dev/sdX /var/lib/docker

创建或修改文件 /etc/docker/daemon.json 并添加

{
  "storage-driver": "overlay2"
}

然后重启 Docker

systemctl restart docker

或者

#修改/lib/systemd/system/docker.service 
......
ExecStart=/usr/bin/dockerd -s=overlay2
......

然后重启 Docker

systemctl daemon-reload
systemctl restart docker
原文地址:https://www.cnblogs.com/Gmiaomiao/p/13174618.html