Docker容器镜像存在哪儿,怎么存放?


Docker容器在运行的过程中,只有小部分的数据可能需要写到容器可写层,因为大部分场景下,我们可以通过Docker volumes来写数据, 但是某些场景下,就是需要往容器可写层写数据,这就是Docker存储驱动Storage Driver出现的原因,这些存储驱动必须是采用层堆叠以及copy-on-write策略。

Docker采用可插拔的方式支持一些不同的存储驱动,存储驱动控制了镜像和容器在宿主机上如何管理以及存储。如果系统内核支持多种存储驱动,在没有明确设置 存储驱动时,Docker会根据优先级(btrfs,zfs,overlay2,aufs,overlay,devicemapper,vfs)顺序进行选择,排在前面的储存驱动并不总是会被Docker采用, 因为有些存储驱动对文件系统或者内核有硬性要求。


Docker支持如下storage driver:

  • overlay2
    Docker优先采用的存储驱动,对于已支持该驱动的Linux发行版,不需要任何进行任何额外的配置。
  • aufs
    Docker 18.06以下版本运行在Ubuntu 14.04以及kernel 3.13上,不支持overlay2,首选aufs
  • devicemapper
    默认的配置模式是loopback-lvm,但是在生产环境时Docker不推荐这种模式,它的性能非常差,我们需要将其配置成direct-lvm。 对于早期的CentOS和RHEL,devicemapper是推荐的存储驱动,因为它们对应的内核版本不支持overlay2,不过,我们现在版本的CentOS与RHEL均已支持overlay2
  • btrfs and zfs
    Docker安装所在的宿主机文件系统是btrfs或者zfs,则Docker优先使用它们作为存储驱动,这些文件系统具有一些高级的选项配置,比如创建快照(snapshots)等。
  • vfs
    Docker不推荐用于生产环境,只用于测试,性能比较差,可能无法支持copy-on-write策略。

  • 注意一些存储驱动要求使用特殊版本的文件系统,比如aufs仅在Ubuntu或者Debian系统被支持, 并且需要安装一些额外的依赖包,而btrfs仅在SLES被支持。

我们大多数人使用的应该都是Docker社区版本,下面列举了社区版Docker引擎在各Linux发行版中推荐的存储驱动。

Linux发行版 推荐的存储驱动 备选存储驱动
Ubuntu overlay2
aufs(运行在内核3.13上的Ubuntu 14.04)
overlaydevicemapper
zfsvfs
Debian overlay2(Debian扩展版本)、
aufsdevicemapper(老版本)
overlayvfs
CentOS overlay2 overlaydevicemapper
zfsvfs
Fedora overlay2 overlaydevicemapper
zfsvfs
  • overlay storage driver已经在Docker引擎(企业版)18.09中被废弃,它在未来的发行包中将被移除,Docker推荐使用overlay存储驱动的用户迁移到overlay2
  • devicemapper storage driver已经在Docker引擎18.09版本中被废弃,它在未来的发行包中将被移除,Docker推荐使用devicemapper存储驱动的用户迁移到overlay2

总之,Docker推荐使用的storage driver是overlay2,Docker安装时默认选择overlay2,对于Docker不推荐使用的storage driver,可以通过强制手动设置使用,可能会出现一些 意想不到的错误,上面介绍的这些都是基于Linux平台,不可能支持Windows或Mac平台。


Docker存储驱动需要文件系统结构的支持:

存储驱动 支持的文件系统
overlay2、 overlay xfs(with ftype=1)、ext4
aufs xfsext4
devicemapper direct-lvm
btrfs btrfs
zfs zfs
vfs any filesystem

Docker各存储驱动的一些特点:

  • overlay2aufsoverlay 基于文件级操作,使用内存效率高,在大量写场景下容器可写层会变得非常大。
  • devicemapperbtrfszfs 基于block级操作,在大量写场景下性能更好。
  • 很少发生写操作同时镜像层数又很多的场景下,overlay表现的比overlay2更好,但是overlay会消耗更多的inodes,可能导致inode瓶颈。
  • btrfszfs需要大量的内存支持。

查看当前Docker的存储驱动

Docker的storage driver是overlay2,文件系统是ext4,可通过命令cat /etc/fstab查看有效的文件系统详细信息。 Docker以插拔式结构支持多种storage driver,但是各storage driver都使用镜像层叠以及copy-on-write策略来达到相同的效果, 下面具体介绍Docker推荐的overlay2工作原理,了解overlay2之后,便能理解Docker镜像以及容器的组织结构。

OverlayFS是一种比较先进的联合文件系统,比起AUFS,它的速度更快,实现起来相对更简单。Docker提供了两种实现,overlay是最初的版本实现, overlay2是新版本实现,更稳定。overlay2要求内核4.0以上,或者RHEL、CentOS 3.10.0-514以上版本,通过命令uname -a查看。


Docker在运行一段时间之后,如果手动修改了storage driver,那本地系统中的Docker镜像以及容器均无法进入,无法查看,当storage driver再次切换回来时, 之前的镜像与容器可再次使用,Docker根目录下的文件系统,我们不应该进行任何手动操作,它应该被Docker自动管理。


overlay2工作原理

OverlayFS在单台Linux上将两个目录进行层叠处理,最终将他们显示为另外一个单独的目录视图,这些被处理的每个目录都被称为层,视图统一的过程则称为联合挂载。 多个目录进行层叠,肯定具有上下层关系,OverlayFS将下层的目录称为lowerdir,上层的目录称为upperdir,被暴露的统一视图目录称为merged。 overlay2支持OverlayFS中的下层数目最大为128,通过docker build或者docker commit命令构建镜像时勿设置过多层。

docker_data

下面以拉取ubuntu:latest镜像为例,讲解其在本地存储结构。


 

ubuntu:latest镜像一共有4层,那么在Docker的层文件系统中则会生成5个文件夹。


这个l目录中都是对应镜像层id的短标识符,都是对镜像层内容目录diff的一个符号链接,作用就是防止在使用mount命令时参数过长,这取决于你的Docker根目录长度, 默认/var/lib/docker

 

每个镜像层目录中包含了一个文件link,文件内容则是当前层对应的短标识符,镜像层的内容则存放在diff目录,查看ubuntu:latest第一层,也就是最下层目录。

 

从镜像最底层的往上每一层,都包含一个文件lower指向了其所有的父层,其文件内容则是父层id的短标识符。 其中diff目录包含了镜像层内容,work目录被OverlayFS内部使用。

 

最上层镜像4a00cadd4488f55ad2378a9d2d915dcff733244fc96217b89f827c5f8959b34b的lower文件内容

 

下面启动一个运行ubuntu:latest镜像的容器

 

容器启动之后,查看/var/lib/docker/overlay2目录,发现多了两个目录。

 

首先进入init目录,查看其lower文件内容,正是4个镜像层短标识符,但是这一层并不是容器层,而是Docker在启动容器时默认加的一个辅助层, 用于给容器配置host等运行时的相关信息。

 

再查看不带init尾缀的目录

 

这个目录比镜像层目录多了一个子目录merged,这个merged目录则是这些镜像层以及容器层挂载之后的统一视图目录, 也就是进入容器之后能看见的文件系统了。为了验证一下,我这里手动在当前merged目录新建一个youendless.txt文本(这里仅用于测试,请勿手动操作Docker存储目录), 然后进入容器中查看是否存在。

 

在上面容器中通过命令touch okk.txt新增一个文本文件,然后查看8985decfb3a78124f061c6d5995a158ca7126c7ccdf4ab7d66853107fb55b4a0的diff目录,

 

很显然,这个目录才是真正的容器层目录,到这里,想必已经深刻理解了Docker镜像以及容器组织结构关系了, 当然不同的Docker版本在处理方式有差别,有些版本可能在每一层包括容器层就生成一个merged目录,作为当前层与其父层的统一视图。

执行命令查看overlay联合挂载信息

 

查看容器信息(忽略无关信息)

 

转自:https://www.youendless.com/post/docker_storage_driver/

Categories: 未分类

0 Comments

Leave a Reply

Avatar placeholder

Your email address will not be published. Required fields are marked *