Docker正在填满我的磁盘空间

时间:2016-10-05 16:08:13

标签: macos docker containers dockerfile diskspace

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

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

  • docker运行CONTAINER_TAG
  • docker stop CONTAINER_TAG
  • rm docker CONTAINER_ID
  • rmi docker image_id

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

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

8 个答案:

答案 0 :(得分:24)

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作业中以定期清理本地磁盘。

答案 1 :(得分:8)

更新于2019-03-26

现在我们可以使用一个命令来完成

docker system prune -a --volumes

警告:

  

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

this

中的更多信息

答案 2 :(得分:6)

Mac上的Docker还有一个额外的问题,它会伤害很多人:docker.qcow2文件可能会超出比例(高达64GB)并且不会自行缩减。

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

正如djs55的一份回复中所述,这是在计划中修复,但它不是一个快速解决方案。引用:

  

.qcow2作为具有最大大小的块设备向VM公开   64GiB。由于容器在文件系统中创建了新文件,   新扇区被写入块设备。这些新部门是   附加到.qcow2文件,导致它增大,直到它   最终变得完全分配。当它击中它时它会停止增长   最大尺寸。

     

...

     

我们希望在几个阶段解决这个问题:(注意这仍然是   规划/设计阶段,但我希望它能给你一个想法)

     

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

     

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

     

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

     

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

更新2019 :已经为Docker for Mac做了很多更新,因为发布了这个答案以帮助缓解问题(特别是:支持不同的文件系统)。

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

答案 3 :(得分:5)

docker container prune
docker system prune
docker image prune
docker volume prune

答案 4 :(得分:5)

为什么文件不断增长?

如果定期使用Docker,即使删除文件,Docker.raw(或Docker.qcow2)的大小也可以保持增长。

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

$ cd ~/Library/Containers/com.docker.docker/Data/com.docker.driver.amd64-linux/
$ ls -s Docker.raw
9964528 Docker.raw

请注意-s的使用,它显示文件实际使用的文件系统块数。使用的块数不必与文件“大小”相同,因为文件可以为sparse

接下来,在单独的终端中启动一个容器,并在其中创建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

返回主机,再次检查文件大小:

$ ls -s Docker.raw 
12061704 Docker.raw

请注意,大小从9964528增加到12061704,其中2097176 512字节扇区的增加大约为1GiB。如果切换回alpine容器终端并删除文件:

/ # rm -f 1GiB
/ # sync

然后检查主机上的文件:

$ ls -s Docker.raw 
12059672 Docker.raw

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

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

$ ls -s Docker.raw 
14109456 Docker.raw

它变得更大了!看来,如果您以循环方式创建和销毁文件,则Docker.raw(或Docker.qcow2)的大小将增加到上限(当前设置为64 GiB),即使内部的文件系统虚拟机相对为空。

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

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

TRIM

通过TRIM命令(或DISCARDUNMAP),文件系统可以向磁盘发出信号,表明一定范围的扇区包含陈旧数据,可以将它们遗忘。这样可以:

    固态硬盘驱动器,用于擦除和重复使用空间,而不是花时间将其改组;和
  • 适用于Mac的Docker在主机文件系统中取消分配块,从而缩小了文件。

那我们如何做这项工作?

Mac版Docker中的自动TRIM

在Mac版Mac 11.11的Docker中,有一个名为trim-after-delete的{​​{3}}“任务”正在监听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

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

如果您删除alpine容器内的1 GiB文件,请返回上一部分的示例

/ # rm -f 1GiB

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

$ docker run --rm -it --privileged --pid=host walkerlee/nsenter -t 1 -m -u -i -n fstrim /var/lib/docker

然后检查文件大小:

$ ls -s Docker.raw 
9965016 Docker.raw

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

希望docker system prune会有所帮助,也请检查以下macos docker实用程序脚本以解决此问题:

this blog

答案 5 :(得分:2)

有关如何限制泊坞磁盘空间的几个选项,我首先限制/旋转日志:Docker container logs taking all my disk space

E.g。如果您有最近的docker版本,则可以使用每个容器--log-opt max-size=50m选项启动它。 此外 - 如果您有旧的未使用的容器,您可以考虑查看位于/var/lib/docker/containers/*/*-json.log

的docker日志

答案 6 :(得分:2)

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

  • ls -klsh Docker.raw

这可能会引起误解,因为它将输出文件的逻辑大小而不是其物理大小。

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

  • du -h Docker.raw

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

答案 7 :(得分:0)

$ sudo docker system prune

警告!这将删除:

  • 所有停止的容器
  • 至少一个容器未使用的所有网络
  • 所有悬垂的图像
  • 所有悬空构建缓存您确定要继续吗? [是/否]