Docker Device Mapper存储驱动程序详解

Device Mapper是基于内核的框架,是Linux上许多高级卷管理技术的基础。 Docker的devicemapper存储驱动程序利用此框架的按需分配和快照功能进行镜像和容器管理。本文将Device Mapper存储驱动程序称为devicemapper,并将内核框架称为Device Mapper

对于受支持的系统,Linux内核中包含devicemapper支持。但是,将其与Docker结合使用需要特定的配置。

devicemapper驱动程序使用Docker专用的块设备,并在块级别而非文件级别运行。可以通过向Docker主机添加物理存储来扩展这些设备,它们的性能要比在操作系统(OS)级别上使用文件系统更好。

先决条件

  • devicemapper存储驱动程序是许多操作系统发行版上的Docker EE支持的存储驱动程序。有关详细信息,请参见产品兼容性列表

  • 在CentOS,Fedora,Ubuntu或Debian上运行的Docker Engine - Community也支持devicemapper

  • 更改存储驱动程序将使您已经创建的所有容器在本地系统上均不可访问。使用docker save保存容器,并将现有镜像推送到Docker Hub或私有存储库,以便您以后无需重新创建它们。

使用devicemapper存储驱动程序配置Docker

在执行这些步骤之前,您必须首先满足所有先决条件。

配置loop-lvm模式进行测试

此配置仅适用于测试。 loop-lvm模式利用loopback机制,该机制允许本地磁盘上的文件被读取和写入,就像它们是实际的物理磁盘或块设备一样。但是,额外的loopback机制以及与OS文件系统层的交互意味着IO操作可能很慢且占用大量资源。使用loopback设备也会引入竞争条件。但是,设置loop-lvm模式可以帮助识别基本问题(例如缺少用户空间软件包,内核驱动程序等),然后再尝试启用direct-lvm模式所需的更复杂的设置。因此,loop-lvm模式仅应在配置direct-lvm之前用于执行基本测试。

对于生产系统,请参见 生产环境配置direct-lvm??模式。

  1. 停止Docker。
$ sudo systemctl stop docker
  1. 编辑/etc/docker/daemon.json。如果尚不存在,请创建它。假设文件为空,请添加以下内容。
{
  "storage-driver": "devicemapper"
}

查看每个存储驱动程序的所有存储选项:

如果daemon.json文件包含格式错误的JSON,则Docker无法启动。

  1. 启动Docker。
$ sudo systemctl启动docker
  1. 验证后台程序是否正在使用“ devicemapper”存储驱动程序。使用docker info命令并寻找Storage Driver
```
$ docker info

Containers: 0
    Running: 0
    Paused: 0
    Stopped: 0
Images: 0
Server Version: 17.03.1-ce
Storage Driver: devicemapper
Pool Name: docker-202:1-8413957-pool
Pool Blocksize: 65.54 kB
Base Device Size: 10.74 GB
Backing Filesystem: xfs
Data file: /dev/loop0
Metadata file: /dev/loop1
Data Space Used: 11.8 MB
Data Space Total: 107.4 GB
Data Space Available: 7.44 GB
Metadata Space Used: 581.6 KB
Metadata Space Total: 2.147 GB
Metadata Space Available: 2.147 GB
Thin Pool Minimum Free Space: 10.74 GB
Udev Sync Supported: true
Deferred Removal Enabled: false
Deferred Deletion Enabled: false
Deferred Deleted Device Count: 0
Data loop file: /var/lib/docker/devicemapper/data
Metadata loop file: /var/lib/docker/devicemapper/metadata
Library Version: 1.02.135-RHEL7 (2016-11-16)
<output truncated>
```

该主机以loop-lvm模式运行,生产系统不支持该模式。这由以下事实表明:Data loop fileMetadata loop file位于/var/lib/docker/devicemapper下的文件中。这些是loopback-mounted的稀疏文件。对于生产系统,请参见 为生产配置直接direct-lvm。

生产环境配置direct-lvm模式

使用devicemapper存储驱动程序的生产主机必须使用direct-lvm模式。此模式使用块设备创建池。这比使用loopback设备更快,更有效地使用系统资源,并且块设备可以根据需要增长。但是,与loop-lvm模式相比,需要更多的设置。

满足 前提条件 之后,请按照以下步骤将Docker配置为在direct-lvm模式下使用devicemapper存储驱动程序。

警告:更改存储驱动程序将使您已经创建的所有容器在本地系统上均不可访问。使用docker save保存容器,并将现有镜像推送到Docker Hub或私有存储库,以便您以后无需重新创建它们。

允许Docker配置Direct-LVM模式

使用Docker 17.06及更高版本,Docker可以管理块设备,从而简化了direct-lvm模式的配置。 **这仅适用于全新的Docker设置。**您只能使用单个块设备。如果需要使用多个块设备,请改为 手动配置??direct-lvm模式 。添加了以下新的配置选项:

| 选项 | 描述 | 需要? | 默认值 | 例子 | | :-------------------------------- | :-------------- ---------------------------------------------------------------------------------------------------- ----------------------------------------------------------------- | :---------- | :-------- | :----------------------------------- | | dm.directlvm_device | 要为direct-lvm配置块设备的路径。 | 是 | dm.directlvm_device="/dev/xvdf"| | dm.thinp_percent | 传入的块设备中存储空间使用的百分比。 | 否 | 95 | dm.thinp_percent=95 | | dm.thinp_metapercent | 传入块设备用于元数据存储的空间百分比。 | 否 | 1 | dm.thinp_metapercent=1 | | dm.thinp_autoextend_threshold | 何时lvm应该自动扩展池占总存储空间的百分比的阈值。 | 否 | 80 | dm.thinp_autoextend_threshold=80 | | dm.thinp_autoextend_percent | 触发自动扩展时增加池的百分比。 | 否 |20 | dm.thinp_autoextend_percent=20 | | dm.directlvm_device_force | 是否格式化块设备,即使文件系统已经存在。如果设置为false并且存在文件系统,则会输出错误并保持文件系统完整。 | 否 | false | dm.directlvm_device_force=true |

编辑daemon.json文件并设置适当的选项,然后重新启动Docker以使更改生效。以下daemon.json配置设置了上表中的所有选项。

{
  "storage-driver": "devicemapper",
  "storage-opts": [
    "dm.directlvm_device=/dev/xdf",
    "dm.thinp_percent=95",
    "dm.thinp_metapercent=1",
    "dm.thinp_autoextend_threshold=80",
    "dm.thinp_autoextend_percent=20",
    "dm.directlvm_device_force=false"
  ]
}

查看存储驱动程序的所有存储选项:

重新启动Docker以使更改生效。 Docker调用命令为您配置块设备。

警告:在Docker为您准备好块设备后更改这些值不被支持,将会导致错误。

您仍然需要 执行定期维护任务 。

手动配置Direct-LVM模式

以下过程创建一个配置为精简池的逻辑卷,以用作存储池的后备。假设您在/dev/xvdf处有一个备用块设备,具有足够的可用空间来完成任务。设备标识符和卷大小在您的环境中可能会有所不同,因此您应该在整个过程中替换自己的值。该过程还假定Docker后台程序处于stopped状态。

  1. 确定要使用的块设备。该设备位于/dev/(例如/dev/xvdf)下,需要足够的可用空间来存储镜像和容器层,以供主机运行的工作负载使用。使用固态驱动器就更好了。

  2. 停止Docker。

$ sudo systemctl stop docker
  1. 安装以下软件包:
  • RHEL/CentOSdevice-mapper-persistent-datalvm2和所有依赖项

  • Ubuntu/Debianthin-provisioning-toolslvm2和所有依赖项

  1. 使用pvcreate命令从第1步在块设备上创建物理卷。用设备名称替换/dev/xvdf

警告:接下来的几个步骤具有破坏性,因此请确保您已经指定正确的设备!

$ sudo pvcreate /dev/xvdf

Physical volume "/dev/xvdf" successfully created.
  1. 使用vgcreate命令在同一设备上创建docker卷组。
$ sudo vgcreate docker/dev/xvdf

Volume group "docker" successfully created
  1. 使用lvcreate命令创建两个名为thinpoolthinpoolmeta的逻辑卷。最后一个参数指定可用空间大小,以在空间不足时允许自动扩展数据或元数据,这是一个临时的权宜之计。这些是推荐值。
```
$ sudo lvcreate --wipesignatures y -n thinpool docker -l 95%VG

Logical volume "thinpool" created.

$ sudo lvcreate --wipesignatures y -n thinpoolmeta docker -l 1%VG

Logical volume "thinpoolmeta" created.
```
  1. 使用lvconvert命令将卷转换为精简池和精简池元数据的存储位置。
```
$ sudo lvconvert -y --zero n -c 512K --thinpool docker/thinpool --poolmetadata docker/thinpoolmeta

WARNING: Converting logical volume docker/thinpool and docker/thinpoolmeta to
thin pool's data and metadata volumes with metadata wiping.
THIS WILL DESTROY CONTENT OF LOGICAL VOLUME (filesystem etc.)
Converted docker/thinpool to thin pool.
```
  1. 通过lvm配置文件配置精简池的自动扩展。
```
$ sudo vi /etc/lvm/profile/docker-thinpool.profile
```
  1. 指定thin_pool_autoextend_thresholdthin_pool_autoextend_percent值。
`thin_pool_autoextend_threshold`是空间的百分比,被用在`lvm`尝试自动扩展可用空间之前(100 = disabled,不推荐)。

`thin_pool_autoextend_percent`是自动扩展时要添加到设备的空间量(0 = disabled)。

下面的示例将容量增加20%,当磁盘使用率达到80%时。

```
activation {
  thin_pool_autoextend_threshold=80
  thin_pool_autoextend_percent=20
}
```

保存文件。
  1. 使用lvchange命令应用LVM配置文件。
```
$ sudo lvchange --metadataprofile docker-thinpool docker/thinpool

Logical volume docker/thinpool changed.
```
  1. 确保启用了对逻辑卷的监视。
```
$ sudo lvs -o+seg_monitor

LV       VG     Attr       LSize  Pool Origin Data%  Meta%  Move Log Cpy%Sync Convert Monitor
thinpool docker twi-a-t--- 95.00g             0.00   0.01                             not monitored
```

如果`Monitor`列中的输出如上报告,则表明该卷未被`监视`,则需要显式启用监视。如果没有此步骤,逻辑卷的自动扩展都不会发生,配置文件中的任何设置不会生起作用。

```
$ sudo lvchange --monitor y docker/thinpool
```

通过运行`sudo lvs -o+seg_monito`命令再次检查是否已启用监视。 `Monitor`列现在应报告正在监视的逻辑卷。
  1. 如果您曾经在此主机上运行过Docker,或者存在/var/lib/docker/,请将其移走,以便Docker可以使用新的LVM池来存储镜像和容器的内容。
```
$ sudo su -
# mkdir /var/lib/docker.bk
# mv /var/lib/docker/* /var/lib/docker.bk
# exit
```

如果以下任何步骤失败并且需要恢复,则可以删除`/var/lib/docker`并将其替换为`/var/lib/docker.bk`。
  1. 编辑/etc/docker/daemon.json,配置devicemapper存储驱动程序所需的选项。如果该文件以前为空,则现在应包含以下内容:
```json
{
    "storage-driver": "devicemapper",
    "storage-opts": [
    "dm.thinpooldev=/dev/mapper/docker-thinpool",
    "dm.use_deferred_removal=true",
    "dm.use_deferred_deletion=true"
    ]
}
```
  1. 启动Docker。
**systemd:**:

```
$ sudo systemctl start docker
```

**service:**:

```
$ sudo service docker start
```
  1. 使用docker info验证Docker是否正在使用新配置。
```
$ docker info

Containers: 0
 Running: 0
 Paused: 0
 Stopped: 0
Images: 0
Server Version: 17.03.1-ce
Storage Driver: devicemapper
 Pool Name: docker-thinpool
 Pool Blocksize: 524.3 kB
 Base Device Size: 10.74 GB
 Backing Filesystem: xfs
 Data file:
 Metadata file:
 Data Space Used: 19.92 MB
 Data Space Total: 102 GB
 Data Space Available: 102 GB
 Metadata Space Used: 147.5 kB
 Metadata Space Total: 1.07 GB
 Metadata Space Available: 1.069 GB
 Thin Pool Minimum Free Space: 10.2 GB
 Udev Sync Supported: true
 Deferred Removal Enabled: true
 Deferred Deletion Enabled: true
 Deferred Deleted Device Count: 0
 Library Version: 1.02.135-RHEL7 (2016-11-16)
<output truncated>
```

如果Docker配置正确,则`Data file`和`Metadata file`为空,池名称为`docker-thinpool`。
  1. 在确认配置正确后,可以删除包含先前配置的/var/lib/docker.bk目录。
```
$ sudo rm -rf /var/lib/docker.bk
```

管理devicemapper

监视精简池

不要仅依靠LVM自动扩展。卷组自动扩展,但是该卷仍然可能被写满。您可以使用lvslvs -a监视卷上的可用空间。考虑使用操作系统级别的监视工具,例如Nagios。

要查看LVM日志,可以使用journalctl

$ sudo journalctl -fu dm-event.service

如果您在精简池中反复遇到问题,可以在/etc/docker/daemon.json中将存储选项dm.min_free_space设置为一个值(代表百分比)。例如,将其设置为10可确保在可用空间为10%或接近10%时操作失败并发出警告。请参阅引擎后台程序参考中的存储驱动程序选项

增加正在运行的设备上的容量

您可以在运行的精简池设备上增加池的容量。如果数据的逻辑卷已满并且卷组已满,这将很有用。具体过程取决于您使用的是loop-lvm精简池还是direct-lvm精简池。

调整loop-lvm精简池的大小

调整loop-lvm精简池大小的最简单方法是使用device_tool实用程序,但是您可以使用操作系统实用程序

使用device_tool实用程序

moby/mobyGithub存储库中,有一个名为device_tool.go的社区贡献脚本。您可以使用此工具来调整loop-lvm精简池的大小,从而避免了上述漫长的过程。不能保证该工具可以工作,但是您只能在非生产系统上使用loop-lvm

如果您不想使用device_tool,则可以手动调整精简池的大小。

  1. 要使用该工具,请克隆Github仓库,更改为contrib/docker-device-tool,然后按照README.md中的说明进行编译。

  2. 使用该工具。以下示例将精简池的大小调整为200GB。

```
$ ./device_tool resize 200GB
```
使用操作系统实用程序

如果您不想使用device_tool实用程序,则可以使用以下过程手动调整loop-lvm精简池的大小。

loop-lvm模式下,一个loopback设备用于存储数据,另一个用于存储元数据。loop-lvm模式仅支持测试,因为它具有明显的性能和稳定性缺点。

如果您使用的是loop-lvm模式,则docker info的输出将显示Data loop fileMetadata loop file的文件路径:

$ docker info |grep 'loop file'

 Data loop file: /var/lib/docker/devicemapper/data
 Metadata loop file: /var/lib/docker/devicemapper/metadata

请按照以下步骤增加精简池的大小。在此示例中,精简池为100 GB,并增加到200 GB。

  1. 列出设备的大小。
```
$ sudo ls -lh /var/lib/docker/devicemapper/

total 1175492
-rw------- 1 root root 100G Mar 30 05:22 data
-rw------- 1 root root 2.0G Mar 31 11:17 metadata
```
  1. 使用truncate命令将data文件的大小增加到200 G,该命令用于增大或减小文件的大小。请注意,减小大小是一种破坏性操作。
```
$ sudo truncate -s 200G /var/lib/docker/devicemapper/data
```
  1. 确认文件大小已更改。
```
$ sudo ls -lh /var/lib/docker/devicemapper/

total 1.2G
-rw------- 1 root root 200G Apr 14 08:47 data
-rw------- 1 root root 2.0G Apr 19 13:27 metadata
```
  1. loopback文件已在磁盘上被更改,但在内存中未更改。以GB为单位列出内存中loopback设备的大小。重新加载,然后再次列出大小。重新加载后,大小为200 GB。
```
$ echo $[ $(sudo blockdev --getsize64 /dev/loop0) / 1024 / 1024 / 1024 ]

100

$ sudo losetup -c /dev/loop0

$ echo $[ $(sudo blockdev --getsize64 /dev/loop0) / 1024 / 1024 / 1024 ]

200
```
  1. 重新加载devicemapper精简池。
a. 首先获取池名称。池名称是第一个字段,以`:`分隔。此命令将其提取。

```
$ sudo dmsetup status | grep ' thin-pool ' | awk -F ': ' {'print $1'}

docker-8:1-123141-pool
```

b. 转储精简池的设备映射器表。

```
$ sudo dmsetup table docker-8:1-123141-pool

0 209715200 thin-pool 7:1 7:0 128 32768 1 skip_block_zeroing
```

c. 使用输出的第二个字段计算精简池的总扇区数。该数字以512-k扇区计数。 100G文件具有209715200个512-k扇区。如果将此数字加倍到200G,则会得到419430400个512-k扇区。

d. 使用以下三个`dmsetup`命令,用新的扇区数重新加载精简池。

```
$ sudo dmsetup suspend docker-8:1-123141-pool

$ sudo dmsetup reload docker-8:1-123141-pool --table '0 419430400 thin-pool 7:1 7:0 128 32768 1 skip_block_zeroing'

$ sudo dmsetup resume docker-8:1-123141-pool
```

调整direct-lvm精简池的大小

要扩展direct-lvm精简池,您需要首先将新的块设备附加到Docker主机,并记下内核分配给它的名称。在这个例子中,新的块设备是/dev/xvdg

按照此流程扩展direct-lvm精简池,根据您的实际情况替换块设备和其他参数。

  1. 收集有关您的卷组的信息。
使用`pvdisplay`命令查找您的精简池当前正在使用的物理块设备以及卷组的名称。

```
$ sudo pvdisplay |grep 'VG Name'

PV Name               /dev/xvdf
VG Name               docker
```

在以下步骤中,根据您的实际情况替换块设备或卷组名称。
  1. 扩展卷组,对上一步使用带有vG Name的vgextend命令和** new **块设备的名称。
```
$ sudo vgextend docker /dev/xvdg

Physical volume "/dev/xvdg" successfully created.
Volume group "docker" successfully extended
```
  1. 扩展docker/thinpool逻辑卷。此命令立即使用100%的卷,而不会自动扩展。要扩展元数据精简池,请使用docker/thinpool_tmeta
```
$ sudo lvextend -l+100%FREE -n docker/thinpool

Size of logical volume docker/thinpool_tdata changed from 95.00 GiB (24319 extents) to 198.00 GiB (50688 extents).
Logical volume docker/thinpool_tdata successfully resized.
```
  1. 使用docker info输出中的Data Space Available字段,确认新的精简池大小。如果改为扩展了docker/thinpool_tmeta逻辑卷,请查找Metadata Space Available
```
Storage Driver: devicemapper
 Pool Name: docker-thinpool
 Pool Blocksize: 524.3 kB
 Base Device Size: 10.74 GB
 Backing Filesystem: xfs
 Data file:
 Metadata file:
 Data Space Used: 212.3 MB
 Data Space Total: 212.6 GB
 Data Space Available: 212.4 GB
 Metadata Space Used: 286.7 kB
 Metadata Space Total: 1.07 GB
 Metadata Space Available: 1.069 GB
<output truncated>
```

重新启动后激活devicemapper

如果重启主机后发现docker服务无法启动,请查找错误“Non existing device”。您需要使用以下命令重新激活逻辑卷:

sudo lvchange -ay docker/thinpool

devicemapper存储驱动程序如何工作

警告:请勿直接在/var/lib/docker/中操作任何文件或目录。这些文件和目录由Docker管理。

使用lsblk命令查看设备及其池,从操作系统的视角:

$ sudo lsblk

NAME                    MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT
xvda                    202:0    0    8G  0 disk
└─xvda1                 202:1    0    8G  0 part /
xvdf                    202:80   0  100G  0 disk
├─docker-thinpool_tmeta 253:0    0 1020M  0 lvm
│ └─docker-thinpool     253:2    0   95G  0 lvm
└─docker-thinpool_tdata 253:1    0   95G  0 lvm
  └─docker-thinpool     253:2    0   95G  0 lvm

使用mount命令查看Docker正在使用的挂载点:

$ mount |grep devicemapper
/dev/xvda1 on /var/lib/docker/devicemapper type xfs (rw,relatime,seclabel,attr2,inode64,noquota)

当使用devicemapper时,Docker将镜像和层内容存储在thinpool中,将它们暴露给容器,通过将它们挂载在/var/lib/docker/devicemapper/的子目录下。

磁盘上的镜像和容器层

/var/lib/docker/devicemapper/metadata/目录包含元数据,这些元数据是有关Devicemapper配置本身以及存在的每个镜像和容器层的。devicemapper存储驱动程序使用快照,并且此元数据包括有关那些快照的信息。这些文件为JSON格式。

/var/lib/docker/devicemapper/mnt/目录包含每个镜像和容器层的挂载点。镜像层挂载点为空,但是容器的挂载点显示容器的文件系统就像他是在容器中。

镜像分层和共享

devicemapper存储驱动程序使用专用的块设备而不是格式化的文件系统,并在块级别对文件进行操作,以在写时复制(CoW)操作期间获得最佳性能。

快照

devicemapper的另一个特性是使用快照(有时也称为thin devicesvirtual devices),它们将在每一层中引入的差异存储为非常小的,轻量级的精简池。快照具有许多优点:

  • 容器之间共有的共享层仅在磁盘上存储一次,除非它们是可写的。例如,如果您有10个都基于alpine的不同镜像,则alpine镜像及其所有父镜像仅在磁盘上存储一次。

  • 快照是写时复制(CoW)策略的实现。这意味着仅当给定文件或目录被该容器修改或删除时,该文件或目录才被复制到该容器的可写层。

  • 由于devicemapper在块级别运行,因此可同时修改可写层中的多个块。

  • 可以使用标准的操作系统级备份实用程序来备份快照。只需复制/var/lib/docker/devicemapper/

Devicemapper工作流程

当您启动使用devicemapper存储驱动程序的Docker时,与镜像和容器层相关的所有对象都存储在/var/lib/docker/devicemapper/中,该文件由一个或多个块级设备支持,无管是loop设备(仅测试)或物理磁盘。

  • 基本设备是最低级别的对象。这就是精简池本身。您可以使用docker info对其进行检查。它包含一个文件系统。此基本设备是每个镜像和容器层的起点。基本设备是Device Mapper实施细节,而不是Docker层。

  • 有关基本设备以及每个镜像或容器层的元数据以JSON格式存储在/var/lib/docker/devicemapper/metadata/中。这些层是写时复制快照,这意味着它们是空的,直到它们和父层存在差异。

  • 每个容器的可写层都挂载在/var/lib/docker/devicemapper/mnt/中的挂载点上。每个只读镜像层和每个停止的容器都存在一个空目录。

每个镜像层都是其下一层的快照。每个镜像的最低层是池中存在的基本设备的快照。运行容器时,它是容器所基于的镜像的快照。以下示例显示了具有两个正在运行的容器的Docker主机。第一个是ubuntu容器,第二个是busybox容器。

ubuntu和busybox镜像层

容器如何使用devicemapper进行读写

读取文件

使用devicemapper,读取发生在块级别。下图显示了在示例容器中读取单个块(0x44f)的高级别的过程。

使用devicemapper读取块

应用程序对容器中的块0x44f发出读取请求。因为容器是镜像的精简快照,所以它没有块,但是它有一个指向存在它的最近父镜像上的块的指针,并从那里读取该块。

写入文件

写入新文件:使用devicemapper驱动程序,通过按需分配操作可以将新数据写入容器。新文件的每个块都分配在容器的可写层中,并将该块写入那里。

更新现有文件:从文件所在的最近的层读取文件的相关块。当容器写入文件时,仅将修改后的块写入容器的可写层。

删除文件或目录:当您删除容器可写层中的文件或目录时,或者当镜像层删除其父层中存在的文件时,devicemapper存储驱动程序会拦截对该文件或目录的读取尝试,并响应该文件或目录不存在。

先写入然后删除文件:如果容器先写入文件,然后再删除文件,则所有这些操作都会在容器的可写层进行。在这种情况下,如果您使用的是direct-lvm,则释放块。如果使用loop-lvm,可能无法释放这些块。这是在生产中不使用loop-lvm的另一个原因。

设备映射器和Docker性能

  • allocate-on demand对性能的影响

    devicemapper存储驱动程序使用allocate-on-demand操作将精简池中的新块分配到容器的可写层中。每个块为64KB,因此这是用于写入的最小空间量。

  • 写时复制性能影响:容器第一次修改特定块时,该块将被写入容器的可写层。由于这些写操作发生在块级别而不是文件级别,因此对性能的影响最小。但是,写入大量块仍然会对性能产生负面影响,在这种情况下,devicemapper存储驱动程序的性能实际上可能会比其他存储驱动程序差。对于写繁重的工作负载,应使用数据卷,该数据卷会完全绕过存储驱动程序。

性能最佳实践

在使用devicemapper时,请牢记这些事项以最大化性能存储驱动程序。

  • 使用direct-lvmloop-lvm模式性能差,切勿在生产中使用。

  • 使用快速存储:固态驱动器(SSD)提供比旋转磁盘更快的读写速度。

  • 内存使用devicemapper比其他一些存储驱动程序使用更多的内存。每个启动的容器都将其文件的一个或多个副本加载到内存中,具体取决于同时修改同一文件的多少块。由于内存压力,对于高密度的某些工作负载,devicemapper存储驱动程序可能不是正确的选择。

  • 将卷用于繁重的工作负载:卷为繁重的工作负载提供最佳和最可预测的性能。这是因为它们绕过了存储驱动程序,并且不会产生任何按需分配和写入时复制所带来的潜在开销。卷还有其他好处,例如,允许您在容器之间共享数据,并且即使使用卷的容器已停止运行,它们也可以持久存储。

  • 注意:当使用devicemapperjson-file日志驱动程序时,由容器生成的日志文件仍存储在Docker的dataroot目录中,默认为/var/lib/docker。如果您的容器生成大量日志消息,则可能导致磁盘使用率增加或由于磁盘已满而无法管理系统。您可以配置日志驱动程序在外部存储容器日志。

相关信息