我做了一个Docker课程来实现它,我正在尝试迁移我的第一个应用程序。在日常使用中,我发现很难跟踪我的磁盘可用空间。我注意到每次运行图像并删除时,它都不会返回原始可用空间量。
生活的循环我给我的容器,从头到尾都是: docker build ...
自定义的容器从节点和标准redis运行。我的操作系统是OSX 10.11.6
在一天结束时,我看到我一直在失去Mbs。我究竟做错了什么? Docker这个缓存可能是我在路上错过的东西吗?
答案 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
标志:
答案 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命令(或DISCARD
或UNMAP
),文件系统可以向磁盘发出信号,表明一定范围的扇区包含陈旧数据,可以将它们遗忘。这样可以:
那我们如何做这项工作?
在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实用程序脚本以解决此问题:
答案 5 :(得分:2)
有关如何限制泊坞磁盘空间的几个选项,我首先限制/旋转日志:Docker container logs taking all my disk space
E.g。如果您有最近的docker版本,则可以使用每个容器--log-opt max-size=50m
选项启动它。
此外 - 如果您有旧的未使用的容器,您可以考虑查看位于/var/lib/docker/containers/*/*-json.log
答案 6 :(得分:2)
还值得一提的是,使用以下命令时,docker.qcow2(或带Apple Filesystem的High Sierra上的Docker.raw)的文件大小看起来非常大(〜64GiB),比实际大小大:>
ls -klsh Docker.raw
这可能会引起误解,因为它将输出文件的逻辑大小而不是其物理大小。
要查看文件的物理大小,可以使用以下命令:
du -h Docker.raw
答案 7 :(得分:0)
$ sudo docker system prune
警告!这将删除: