清理docker环境:devicemapper

Posted

技术标签:

【中文标题】清理docker环境:devicemapper【英文标题】:Clean docker environment: devicemapper 【发布时间】:2016-10-06 22:08:20 【问题描述】:

我有一个带有 2 个容器(Jenkins 和 Nexus,都有自己的命名卷)的 docker 环境。 我每天都有一个删除未使用的容器和图像的 cron 作业。这工作正常。但问题出在我的设备映射器内部:

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

码头工人信息:

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

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

【问题讨论】:

你使用的是哪个 rhel 和 docker 版本? 我使用的是 Ubuntu 14.04 和 docker 版本 1.11.1。为什么它使用基于 (rhel/centos) 的 devicemapper Ubuntu 14.04 在标准内核中没有 AUFS。你需要linux-image-extra 内核。在任何情况下,您都不应该使用环回设备映射器。我会回答的... @Matt 感谢您的信息。但是对于使用 RHEL 的人来说呢?您的设备映射器是否有可能以“好”的方式使用? 是的,see direct lvm thin pool in the answer 【参考方案1】:

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 精简池。如果您无法更改存储驱动程序,则相同的过程至少会清除您无法回收的所有已分配稀疏空间。

更改 docker 存储驱动程序

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

    导出数据

    停止 Docker

    删除/var/lib/docker

    修改 docker 启动以使用新的存储驱动程序。 在/lib/systemd/system/docker.service/etc/systemd/system/docker.service/etc/default/docker/etc/sysconfig/docker中设置--storage-driver=<name>

    启动 Docker

    导入数据

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/内核问题,它正被推为标准驱动程序。

Direct LVM Thin Pool

您可以直接使用 LVM 精简池来代替 devicemapper 循环文件。 RHEL 使用随 EPEL docker 软件包分发的 docker-storage-setup 实用程序使这一切变得容易。 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 卷中的空间。您最终会得到一个无响应的 Docker 守护程序,需要被杀死,然后是仍在使用且难以清理的 LVM 资源。

【讨论】:

谢谢。很好的解释。一个小细节可以改善您的答案。我必须编辑 /etc/default/docker 并添加 DOCKER_OPTS="--storage-driver=aufs" (可能取决于您的操作系统) 我已经添加了 ubu 路径和 rhel 路径。谢谢 只是好奇当空间用完时会发生什么/如何解决由此引起的问题? Docker 守护程序变得无响应并停止工作。最快的解决方法是删除所有卷和/var/lib/docker 并重新开始。如果你必须杀死 docker,你最终可能会导致 devicemapper 资源保持打开状态,让一切变得困难。 @Matt CentOS7 在哪个包中?【参考方案2】:

定期docker system prune -a 在我使用devicemapper 而非LVM 瘦池的系统上为我工作。我使用的模式是:

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

标签示例:

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

通用 Docker label documentation

【讨论】:

【参考方案3】:

首先,what is devicemapper (official documentation)

Device Mapper 自 2.6.9 版起已包含在主线 Linux 内核中。它是 RHEL 系列 Linux 发行版的核心部分。

devicemapper 驱动程序将每个图像和容器存储在它自己的虚拟设备上。这些设备是精简配置的写时复制快照设备。 Device Mapper 技术在块级别而不是文件级别工作。这意味着 devicemapper 存储驱动程序的精简配置和写时复制操作适用于块而不是整个文件。

devicemapper 是某些 Linux 发行版上的默认 Docker 存储驱动程序。

运行 devicemapper 存储驱动程序的 Docker 主机默认使用称为 loop-lvm 的配置模式。此模式使用稀疏文件构建镜像和容器快照使用的精简池

Docker 1.10 及更高版本不再将映像层 ID 与 /var/lib/docker 中的目录名称匹配。 但是,有两个关键目录。

/var/lib/docker/devicemapper/mnt 目录包含映像和容器层的挂载点。 /var/lib/docker/devicemapper/metadata 目录为每个镜像层和容器快照包含一个文件。

如果您的docker info 确实显示您的Storage Driverdevicemapper(而不是aufs),请谨慎处理这些文件夹。 参见例如issue 18867。

【讨论】:

没有明确的方法可以在不丢失现有容器的情况下减小 devicemapper 的大小吗? 有一些关于删除后修剪稀疏文件的旧错误:github.com/docker/docker/issues/3182。它应该被修复,但人们仍然报告问题。【参考方案4】:

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

做了一些谷歌搜索,发现“数据”文件是环回挂载的稀疏文件,docker 使用它来存储挂载位置和我们将存储在容器中的其他文件。

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

警告:删除所有 docker 容器

docker rm $(docker ps -aq)

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

【讨论】:

这并没有改变我的 devicemapper 文件的大小。之前:19G,之后:19G docker rm $(docker ps -aq) 将删除所有现有容器。不知道为什么会这样做。

以上是关于清理docker环境:devicemapper的主要内容,如果未能解决你的问题,请参考以下文章

如何清理Docker占用的磁盘空间?

docker的日志清理

Docker 镜像仓库为什么要分库分权限?

Docker 镜像仓库为什么要分库分权限?

清除docker无用镜像

清除docker无用镜像