清洁 docker 环境:devicemapper

Clean docker environment: devicemapper

我有一个包含 2 个容器的 docker 环境(Jenkins 和 Nexus,它们都有自己的命名卷)。 我有一个每日 cron-job,它删除未使用的容器和图像。这工作正常。但问题出在我的设备映射器中:

du -sh /var/lib/docker/
30G docker/

我可以在 docker 文件夹中查看每个文件夹: 体积(很大,但对我来说这很正常):

/var/lib/docker# du -sh volumes/
14G volumes/

容器:

/var/lib/docker# du -sh containers/
3.2M    containers/

图片:

/var/lib/docker# du -sh image/
5.8M    image/

设备映射器:

/var/lib/docker# du -sh devicemapper/
  16G   devicemapper/

/var/lib/docker/devicemapper/mnt是7.3G /var/lib/docker/devicemapper/devicemapper是8.1G

Docker 信息:

Storage Driver: devicemapper
 Pool Name: docker-202:1-xxx-pool
 Pool Blocksize: 65.54 kB
 Base Device Size: 10.74 GB
 Backing Filesystem: ext4
 Data file: /dev/loop0
 Metadata file: /dev/loop1
 Data Space Used: 5.377 GB
 Data Space Total: 107.4 GB
 Data Space Available: 28.8 GB
 Metadata Space Used: 6.148 MB
 Metadata Space Total: 2.147 GB
 Metadata Space Available: 2.141 GB
 Udev Sync Supported: true

这是什么space,我可以在不破坏东西的情况下清理它吗?

首先,what is devicemapper (official documentation)

Device Mapper has been included in the mainline Linux kernel since version 2.6.9 [in 2005]. It is a core part of RHEL family of Linux distributions.

The devicemapper driver stores every image and container on its own virtual device. These devices are thin-provisioned copy-on-write snapshot devices.

Device Mapper technology works at the block level rather than the file level. This means that devicemapper storage driver's thin provisioning and copy-on-write operations work with blocks rather than entire files.

The devicemapper is the default Docker storage driver on some Linux distributions.

Docker hosts running the devicemapper storage driver default to a configuration mode known as loop-lvm. This mode uses sparse files to build the used by image and container snapshots

Docker 1.10 [from 2016] and later no longer matches image layer IDs with directory names in /var/lib/docker.

However, there are two key directories.

  • The /var/lib/docker/devicemapper/mnt directory contains the mount points for image and container layers.
  • The /var/lib/docker/devicemapper/metadatadirectory contains one file for every image layer and container snapshot.

If your docker info does show your Storage Driver is devicemapper (and not aufs), proceed with caution with those folders.

See for instance issue 18867.

Don't use a devicemapper loop file for anything serious! Docker 对此有很大的警告。

/var/lib/docker/devicemapper/devicemapper 目录包含稀疏循环文件,这些文件包含 docker 安装的所有数据。所以你需要使用 lvm 工具来绕过它们并做一些事情。读一读 the remove issues with devicemapper,它们有点解决了,但也许没有。

我会尽可能远离 devicemapper 或在任何基于 RHEL 的系统上使用 LVM 精简池。如果您不能更改存储驱动程序,则相同的过程至少会清除您无法回收的任何分配的稀疏 space。

更改 docker 存储驱动程序

更改存储驱动程序需要转储包含所有 docker 数据的 /var/lib/docker 目录。有一些方法可以保存它的一部分,但这涉及弄乱 Docker 内部结构。最好提交并导出您想要保留的任何容器或卷,并在更改后导入它们。否则,您将获得全新的空白 Docker 安装!

  1. 导出数据

  2. 停止Docker

  3. 删除/var/lib/docker

  4. 修改您的 docker 启动以使用新的存储驱动程序。 在/lib/systemd/system/docker.service/etc/systemd/system/docker.service/etc/default/docker/etc/sysconfig/docker

  5. 中设置--storage-driver=<name>
  6. 开始Docker

  7. 导入数据

AUFS

AUFS 不在主线内核中(而且永远不会),这意味着发行版必须以某种方式主动包含它。对于 Ubuntu,它在 linux-image-extra 包中。

apt-get install linux-image-extra-$(uname -r) linux-image-extra-virtual

然后将存储驱动选项更改为--storage-driver=aufs

OverlayFS

OverlayFS 已在 Ubuntu 中可用,如果您仍在使用 3.x 内核

,只需将存储驱动程序更改为 --storage-driver=overlay2--storage-driver=overlay

我现在不确定这个想法有多好。它不能比循环文件差很多但是 overlay2 驱动程序非常适合开发人员使用,但尚未被视为生产就绪(例如 Docker Enterprise 不提供支持),但由于 AUFS/Kernel 问题。

Direct LVM Thin Pool

您可以直接使用 LVM 精简池来代替 devicemapper 循环文件。 RHEL 使用 docker-storage-setup utility that distributed with their EPEL docker package. Docker have detailed steps for setting up the volumes manually 使这变得容易。

--storage-driver=devicemapper \
--storage-opt=dm.thinpooldev=/dev/mapper/docker-thinpool \
--storage-opt dm.use_deferred_removal=true

Docker 17.06+ 支持 managing simple direct-lvm block device setups for you.

永远不要 运行 超出 LVM 卷中的 space。您最终会得到一个无响应的 Docker 守护进程,需要将其终止,然后是仍在使用且难以清理的 LVM 资源。

我遇到了同样的问题,我的 /var/lib/docker/devicemapper/devicemapper/data 文件已达到根卷的 ~91%(50G 中的~45G)。我尝试删除所有不需要的图像、删除的卷,但对减少此文件没有任何帮助。

谷歌搜索了一下,了解到“数据”文件是环回挂载的稀疏文件,docker 使用它来存储挂载位置和我们本应存储在容器内的其他文件。

最后我删除了之前 运行 的所有图像并停止了

警告:删除所有 docker 个容器

docker rm $(docker ps -aq)

显着减少了 devicemapper 文件。希望这可以帮助你 .

定期 docker system prune -a 在我使用 devicemapper 而不是 LVM thinpool 的系统上对我有用。我使用的模式是:

  • 如果我想让它们免于清理,我会用标签“protected”标记任何容器、图像等
  • 然后我定期 运行 docker system prune -a --filter=label!=protected(手动或在 cron 上使用 -f

标签示例:

  • docker run --label protected ...
  • docker create --label=protected=true ...
  • 对于图像,Docker文件的 LABEL,例如 LABEL protected=true
  • 要为我无法轻易重建的现有图像添加标签,我用上面的内容制作了一个 2 行 Docker 文件,构建一个新图像,然后将新图像切换为旧图像(标签).

一般Dockerlabel documentation