Docker正在填满我的磁盘空间

Fra*_*lia 19 macos containers diskspace docker dockerfile

我做了一个Docker课程来实现它,我正在尝试迁移我的第一个应用程序.在日常使用中,我发现很难跟踪我的磁盘可用空间.我注意到每次运行图像并删除时,它都不会返回原始可用空间量.

生活周期我给我的容器,从头到尾都是:docker build ...

  • docker运行CONTAINER_TAG
  • 码头停止CONTAINER_TAG
  • rm docker CONTAINER_ID
  • rmi docker image_id

自定义的容器从节点和标准redis运行.我的操作系统是OSX 10.11.6

在一天结束时,我看到我一直在失去Mbs.我究竟做错了什么?Docker这个缓存可能是我在路上错过的东西?

Elt*_*man 27

Docker存储有三个区域可以挂载,因为Docker非常谨慎 - 它不会自动删除任何区域:已退出的容器,未使用的容器卷,未使用的图像层.在具有大量构建和运行的开发环境中,可能会占用大量磁盘空间.

这三个命令清除了未使用的任何内容:

  • docker rm $(docker ps -f status=exited -aq) - 删除已停止的容器
  • docker rmi $(docker images -f "dangling=true" -q) - 删除任何图像中未使用的图像图层
  • docker volume rm $(docker volume ls -qf dangling=true) - 删除任何容器未使用的卷.

它们可以安全运行,它们不会删除图像引用的图像层或容器使用的数据卷.您可以为它们添加别名,和/或将它们放在CRON作业中以定期清理本地磁盘.

  • 这些命令与docker system prune相比如何? (3认同)
  • 我尝试运行这 3 个命令,但它们都不起作用,相反 Docker 显示了此示例消息“dockervolume rm”需要至少 1 个参数。请参阅“dockervolume rm --help”。用法: docker volume rm [OPTIONS] VOLUME [VOLUME...] 删除一个或多个卷` (2认同)

zho*_*jie 26

更新于2019-03-26

现在我们可以使用一个命令来执行该操作

docker system prune -a --volumes
Run Code Online (Sandbox Code Playgroud)

警告:

默认情况下,如果当前没有使用该卷的容器,则不会删除卷以防止重要数据被删除。--volumes在运行命令以修剪卷时也使用该标志:

更多相关信息,

  • 今天的官方和最佳解决方案。不理想,但工作!感谢您为社区@zhongjiajie 更新此内容 (4认同)

小智 22

还值得一提的是,当使用以下命令时,docker.qcow2(或 High Sierra 上的 Docker.raw 与 Apple 文件系统)的文件大小可能看起来非常大(~64GiB),比实际大:

  • ls -klsh Docker.raw

这在某种程度上可能会产生误导,因为它将输出文件的逻辑大小而不是其物理大小。

要查看文件的物理大小,您可以使用以下命令:

  • du -h Docker.raw

来源:https : //docs.docker.com/docker-for-mac/faqs/#disk-usage


Dav*_*vid 15

为什么文件一直在增长?

如果经常使用 Docker ,即使文件被删除,Docker.raw (或 Docker.qcow2)的大小 也会继续增长。

为了演示效果,首先检查 主机上文件的 当前大小:

$ cd ~/Library/Containers/com.docker.docker/Data/com.docker.driver.amd64-linux/
$ ls -s Docker.raw
9964528 Docker.raw
Run Code Online (Sandbox Code Playgroud)

注意使用 -s which 显示文件实际使用的文件系统块的数量。使用的块数不一定与文件“大小”相同,因为文件可以是 稀疏的

接下来在单独的终端中启动一个容器并在其中创建一个 1GiB 文件:

$ docker run -it alpine sh
# and then inside the container:
/ # dd if=/dev/zero of=1GiB bs=1048576 count=1024
1024+0 records in
1024+0 records out
/ # sync
Run Code Online (Sandbox Code Playgroud)

回到主机上再次检查文件大小:

$ ls -s Docker.raw 
12061704 Docker.raw
Run Code Online (Sandbox Code Playgroud)

请注意大小从 996452812061704的增加,其中2097176 512-byte 扇区的增加 约为 1GiB,正如预期的那样。如果您切换回 alpine 容器终端并删除文件:

/ # rm -f 1GiB
/ # sync
Run Code Online (Sandbox Code Playgroud)

然后检查主机上的文件:

$ ls -s Docker.raw 
12059672 Docker.raw
Run Code Online (Sandbox Code Playgroud)

文件没有变小!无论 VM 内的文件发生了什么,主机似乎都不知道。

接下来,如果您再次1GiB 在容器中重新创建“相同” 文件,然后再次检查大小,您将看到:

$ ls -s Docker.raw 
14109456 Docker.raw
Run Code Online (Sandbox Code Playgroud)

它变得更大了!看起来,如果你在一个循环中创建和销毁文件,即使虚拟机内部的文件系统比较空,Docker.raw (或 Docker.qcow2)的大小 也会增加到上限(目前设置为 64 GiB)。

这种奇怪行为的解释在于文件系统通常如何管理块。当要创建或扩展文件时,文件系统会找到一个空闲块并将其添加到文件中。当一个文件被删除时,从文件系统的角度来看,这些块变得“空闲”,但没有人告诉磁盘设备。更糟糕的是,新释放的块可能不会立即重新使用——这完全取决于文件系统的块分配算法。例如,该算法可能被设计为有利于为文件连续分配块:最近释放的块不太可能位于扩展文件的理想位置。

由于块分配器在实践中倾向于支持未使用的块,结果是 Docker.raw (或 Docker.qcow2)将不断累积新块,其中许多包含陈旧数据。主机上的文件变得越来越大,即使 VM 内的文件系统仍然报告有足够的可用空间。

修剪

TRIM 命令(或一 DISCARDUNMAP)允许文件系统信号到磁盘,一系列扇区包含陈旧的数据,它们可以被遗忘。这允许:

  • 一个 SSD 驱动器来擦除和重用空间,而不是花时间四处移动;和
  • Docker for Mac 释放主机文件系统中的块,缩小文件。

那么我们如何进行这项工作呢?

Docker for Mac 中的自动修剪

在 Docker for Mac 17.11 中有一个 容器化的 “任务”,称为 trim-after-delete 侦听 Docker 镜像删除事件。可以通过 ctr 命令查看:

$ docker run --rm -it --privileged --pid=host walkerlee/nsenter -t 1 -m -u -i -n ctr t ls
TASK                    PID     STATUS    
vsudd                   1741    RUNNING
acpid                   871     RUNNING
diagnose                913     RUNNING
docker-ce               958     RUNNING
host-timesync-daemon    1046    RUNNING
ntpd                    1109    RUNNING
trim-after-delete       1339    RUNNING
vpnkit-forwarder        1550    RUNNING
Run Code Online (Sandbox Code Playgroud)

当收到图像删除事件时,该进程会等待几秒钟(以防其他图像被删除,例如作为 docker 系统 prune 的一部分 ),然后fstrim 在文件系统上运行 。

回到上一节的例子,如果你删除了alpine 容器内的 1 GiB 文件

/ # rm -f 1GiB
Run Code Online (Sandbox Code Playgroud)

然后fstrim 从主机中的终端手动运行 :

$ docker run --rm -it --privileged --pid=host walkerlee/nsenter -t 1 -m -u -i -n fstrim /var/lib/docker
Run Code Online (Sandbox Code Playgroud)

然后检查文件大小:

$ ls -s Docker.raw 
9965016 Docker.raw
Run Code Online (Sandbox Code Playgroud)

文件恢复到(大约)原始大小——空间终于被释放了!

希望这篇博客会有所帮助,还可以查看以下针对此问题的 macos docker 实用程序脚本:

https://github.com/wanliqun/macos_docker_toolkit


小智 12

我不确定它是否与当前主题相关,但这对我个人来说是一个解决方案

打开 docker 设置 -> 资源 -> 磁盘映像大小 - 16gb

  • 这是最好的答案。 (2认同)

Gim*_*mby 8

Mac上的Docker还有一个困扰很多人的问题:docker.qcow2文件可以按比例增长(最大64gb),并且永远不会缩小。

https://github.com/docker/for-mac/issues/371

如djs55的答复之一所述,这正在解决中,但不是快速解决方案。引用:

.qcow2作为最大大小为64GiB的块设备公开给VM。当容器在文件系统中创建新文件时,新扇区将被写入块设备。这些新扇区被附加到.qcow2文件中,导致其大小增加,直到最终被完全分配。当达到此最大大小时,它将停止增长。

...

我们希望在几个阶段中解决此问题:(请注意,这仍处于计划/设计阶段,但我希望它能给您一个想法)

1)我们将切换到支持TRIM的连接协议,并在qcow2旁边的元数据文件中实现自由块跟踪。我们将创建一个压缩工具,该工具可以脱机运行以缩小磁盘(有点像qemu-img convert,但是没有dd if = / dev / zero,它应该很快,因为它已经知道了空闲空间在哪里) )

2)假设压缩工具足够快,我们将在VM重新启动时自动运行压缩工具

3)我们将切换到在线压缩器(有点像编程语言中的GC)

我们还正在考虑使.qcow2的最大大小可配置。也许对于某些环境而言64GiB太大了,而较小的上限会有所帮助吗?


2019年更新:自发布此答案以帮助缓解问题(尤其是:支持其他文件系统)以来,Mac版Docker已完成了许多更新。

不过,清理仍不是完全自动的,您可能需要不时修剪。有关可以帮助清理磁盘空间的单个命令,请参阅zhongjiajie的答案

  • Docker桌面现在支持调整磁盘映像的大小。它实际上以不同的大小重新创建它,从而丢失了其中的所有内容,但仍然有帮助。 (2认同)

Ser*_*nci 8

它一直阻塞我的 120\xc2\xa0GB。由于我只使用 256\xc2\xa0GB MacBook Air,这造成了很大的困扰。

\n

我认为这是最简单且持久的解决方案:

\n

\xe2\x9a\xa0\xef\xb8\x8f 这会删除所有内容,包括卷!\xe2\x9a\xa0\xef\xb8\x8f

\n

在此输入图像描述

\n

在此输入图像描述

\n


Ber*_*oer 7

由于这里没有任何东西对我有用,所以这就是我所做的。检查文件大小:

ls -lhks ~/Library/Containers/com.docker.docker//Data/vms/0/data/Docker.raw
Run Code Online (Sandbox Code Playgroud)

然后在docker桌面中只需减小磁盘映像的大小(我使用的是原始格式)。它会说它将删除所有内容,但当您阅读本文时,您可能已经删除了。这样就创建了一个全新的空文件。


小智 5

docker container prune
docker system prune
docker image prune
docker volume prune
Run Code Online (Sandbox Code Playgroud)

  • 这会做什么?请详细说明。 (2认同)