关于docker:Docker容器和镜像存储机制介绍

7次阅读

共计 2051 个字符,预计需要花费 6 分钟才能阅读完成。

本文次要介绍 Docker 容器(Container)和镜像(Image)是如何进行数据存储的。

容器如何读写文件

镜像(Image)是由若干个层(Layer)所组成的,当用户应用 image 运行了一个 container 之后,就会在这个 image 的最下面再加上一个可读可写的 layer,如下图所示:

除了最下面那一个 layer 是可读写的之外,上面的所有 layer 都是属于 image 的,都是只读的。
在 container 运行时,任何在 container 文件系统中写入和批改的数据都会被写入到最上层的可读写 layer(这里不包含 volume、bind mount 和 tmpfs 这些长久化存储伎俩),并不会影响到上面的那些只读 layer。当 container 运行完结的时候,最上层的可读写 layer 就会被抛弃,而上面的那些只读 layer 是属于 image 的,并不会受到影响。
这也就是为什么应用同一个 image 运行 container,该 container 完结之后,从新应用该 image 启动一个新的 container,上一个 container 写入和批改的数据全都不见了,用户能看见的仍旧是当初编写 Dockerfile 时写入该 image 的那些数据的起因。
如果应用同一个 image 启动了多个 container,那么这些 container 会有各自的最上层的可读写 layer,然而上面的那些只读 layer 是共用的,如下图所示:

镜像的 layer 治理

一个 image 的多个 layer 并不是绑定和存储在一起的,它们之间是低耦合的。
应用 docker pull 命令拉取一个 image 的时候,并不是一次性拉取的,而是一个 layer 一个 layer 地拉取,而后存储在本机(在 linux 上默认是 /var/lib/docker/<storage-driver>/ 下)。
一台主机中存在多个 image 时,有可能会呈现多个 image 的某些 layer 雷同的状况,那么此时在主机中就只会存储一份该 layer,而不是存储多个。
那么问题来了:既然多个 layer 是离开存储的,那么用户在 container 中却能够看到所有的 layer 中存储的文件,这又是怎么做到的呢?这就波及到了 union file system 和 union mount。
能够通过 docker image history 以及 docker image inspect 来查看某个 image 的所有 layer。

Copy On Write

当 container 想要更改本来就存在于 image 中的那些数据的时候该怎么办呢?那些数据是位于下面那些属于 image 的只读层的,因而必定不能间接批改。Docker 采纳的解决方案个别是 copy-on-write。
当 container 想要读取本来就存在于 image 中的数据时,间接从数据所在的只读 layer 读取即可。而如果想要批改本来就存在于 image 中的数据时,Docker 就会先把要被批改的文件拷贝到最上层的属于 container 的可读写 layer 中,而后再在这个可读写的 layer 中进行数据的批改即可。
值得一提的是,哪怕是对文件的元数据(meta data)的批改(例如批改文件权限、所属用户等等),也会触发 copy-on-write 机制。
Docker 有多种存储引擎(storage driver),不同的 storage driver 对 copy-on-write 的具体实现是不一样的。
留神:并不是所有的 Docker 存储引擎都反对 copy on write 的,例如 vfs 就不反对!

查看容器占用磁盘大小

应用 docker ps -s 来查看一个 container 在运行时占用的磁盘大小,例如:

SIZE指的是该 container 最上层的可读写 layer 的大小,而 virtual 指的是启动了该 container 的 image 的那些只读 layer 的大小。
须要留神的是,通过这个命令失去的 container 磁盘空间大小是不包含以下这些的:

  • log 文件所应用的磁盘空间
  • volume 和 bind mount 所应用的磁盘空间
  • container 的配置文件所应用的磁盘空间
  • 内存交换所应用的磁盘空间
  • Checkpoints 所应用的磁盘空间

Docker 存储引擎

Docker 在 linux 下提供了如下的存储引擎选项:

存储引擎 形容
overlay2 在 linux 上首选的存储引擎,不须要额定的配置
fuse-overlayfs 举荐在运行 rootless 的 Docker 时应用
btrfs 和 zfs 能够提供更多的性能,例如快照等等,然而须要额定的配置
vfs 目前仍处于测试中,用于不反对 copy on write 的文件系统中,性能堪忧,不举荐应用在生产环境中
devicemapper 在生产环境中须要 direct-lvm 的反对

能够通过 docker info 命令来查看本人应用的 Docker 用的是哪一个 storage driver:

上图中应用的 storage driver 是 overlay2。

参考资料

https://docs.docker.com/storage/storagedriver/

正文完
 0