使用Docker一段时间后,你会发现它占用了大量的硬盘空间。值得庆幸的是,Docker1.13引入了一种解决方法,它提供了简单的命令来查看/清理Docker使用的磁盘空间。本文通过一个简单的例子来证明Docker可以快速填满磁盘。该示例贯穿play-with-docker.com。单击添加新实例以创建一个新实例,该实例已安装最新版本的Docker17.03。本篇博客主要讨论磁盘空间,不妨使用df命令查看磁盘初始状态:$df-hFilesystemSizeUsedAvailableUse%Mountedon/dev/mapper/...10.0G443.3M9.6G4%/tmpfs60.0G060.0G0%/devtmpfs60。0G060.0G0%/sys/fs/cgroup/dev/xvda149.1G3.7G43.3G8%/etc/resolv.conf/dev/xvda149.1G3.7G43.3G8%/etc/hostname/dev/xvda149.1G3.7G43.3G8%/etc/hostsshm64.0M064.0M0%/dev/shm/dev/mapper/...10.0G443.3M9.6G4%/graph/overlay2显示在新创建的play-with-docker.com实例中,总共有10GB的磁盘空间,其中接近500MB已经被使用。接下来编写Dockerfile来创建镜像。此图像基于Alpine图像;镜像会被写入3个随机文件,每个文件1GB,文件由dd命令生成;因为这个镜像没有实际作用,CMD设置为/bin/true。FROMalpineRUNddif=/dev/zeroof=1g1.imgbs=1Gcount=1RUNddif=/dev/zeroof=1g2.imgbs=1Gcount=1RUNddif=/dev/zeroof=1g3.imgbs=1Gcount=1CMD/bin/truerundockerbuild-ttest.可以创建图像。执行完成后会生成一个3GB的镜像。$dockerimagelsREPOSITORYTAGCREATEDSIZEtestlatest38secondssago3.23GBalpinelatest5weeksago3.99MB不难理解,镜像占用了相应的磁盘空间。$df-hFilesystemSizeUsedAvailableUse%Mountedon/dev/mapper/...10.0G3.4G6.5G34%/如果只写了2个随机文件,需要修改Dockerfile,删除一行。为了避免在构建镜像时使用缓存,我在dd命令前加了一行echo命令。FROMalpineRUNechofooRUNddif=/dev/zeroof=1g1.imgbs=1Gcount=1RUNddif=/dev/zeroof=1g2.imgbs=1Gcount=1#RUNddif=/dev/zeroof=1g3.imgbs=1Gcount=1CMD/bin/true保存了1GB的磁盘空间,但现实更糟!$df-hFilesystemSizeUsedAvailableUse%Mountedon/dev/mapper/...10.0G5.4G4.5G54%/老的Docker镜像一直都在,最终磁盘空间会很快用完。Docker1.13引入了dockersystemdf命令,类似于Linux上的df命令,用于查看Docker的磁盘使用情况。$dockersystemdfTYPETOTALACTIVESIZERECLAIMABLEImages305.373GB5.373GB(100%)Containers000B0BLocalVolumes000B0B可以看到实例上有3个Docker镜像:apline镜像包含3个1GB的随机文件和2个1GB的随机文件。这些图像占用超过5GB的磁盘空间。由于我们不是基于这些镜像运行容器,所以它们都可以被删除,所以可回收(RECLAIMABLE)磁盘空间是100%。使用dockerruntest运行测试镜像,再次查看:$dockersystemdfTYPETOTALACTIVESIZERECLAIMABLEImages315.373GB3.225GB(60%)Containers100B0BLocalVolumes000B0B现在情况不同了。我运行了一个容器,它在执行/bin/true后很快就退出了。此容器绑定到测试镜像,该镜像被标记为活动且无法删除,导致可回收磁盘空间较少。现在让我们清理磁盘空间。Docker提供了dockersystemprune,可用于清理悬挂镜像(请参阅什么是Docker:镜像?)和容器,以及无效数据卷和网络。$dockersystempruneWARNING!Thiswillremove:-allstoppedcontainers-allvolumesnotusedbyatleastonecontainer-allnetworksnotusedbyatleastonecontainer-alldanglingimagesAreyousureyouwanttocontinue?[y/N]yDeletedContainers:1cdf866157b4a97e151125af3c2a7f186a59b6f63807e2014ce1a00d68f44e1dDeletedImages:deleted:sha256:f59bb277...deleted:sha256:695b8e70...deleted:sha256:93b1cceb...deleted:sha256:c74d6bcd...deleted:sha256:df8b9bb1...deleted:sha256:dfe8340f...deleted:sha256:ce1ee654...Totalreclaimedspace:3.221GB根据警告消息,此命令将删除所有已关闭的容器和悬挂图像。示例中占用了包含3个1GB随机文件的镜像名称,名称为:,为悬空镜像,将被删除。同时,所有中间图像也将被删除。在这种情况下,总共回收了3GB的磁盘空间!此外,使用-a选项进行深度清理。此时我们会看到更严密的警告信息:$dockersystemprune-aWARNING!这将删除:-allstoppedcontainers-allvolumesnotusedbyatleastonecontainer-allnetworksnotusedbyatleastonecontainer-allimageswithoutatleastonecontainerassociatedtothemAreyousurelettacontinuey?Deyousurelettacontinuey?:最新删除:sha256:c515ebfa2...删除:sha256:07302c011...删除:sha256:37c0c6474...删除:sha256:5cc2b6bc4...删除:sha256:b283b9c35...删除:sha256:8a8b9bd8b...未标记:alpine:latestuntagged:alpine@sha256:58e1a1bb75db1...deleted:sha256:4a415e366...deleted:sha256:23b9c7b43...Totalreclaimedspace:2.151GB此命令将清理整个系统,只保留图像、容器、数据实际使用的卷和网络,因此需要格外小心。比如我们不能在生产环境运行prune-a命令,因为有时候需要一些备份镜像(用于备份,回滚等),如果删除了这些镜像,运行容器的时候需要重新下载.此时,所有未绑定容器的镜像都会被删除。由于第一个prune命令删除了所有容器,因此所有图像(未绑定到任何容器)都被删除。$df-hFilesystemSizeUsedAvailableUse%Mountedon/dev/mapper/...10.0G442.5M9.6G4%/现在使用的磁盘空间又是4%。本文中的示例只是冰山一角,因为一旦我们运行真正的容器并使用Docker数据卷和Docker网络,磁盘空间将更快耗尽。如果您有兴趣,可以查看博客***上的视频(不要忘记订阅!)。在视频中,我介绍了一个简单的WordPress应用程序,它由几个容器、数据卷和网络组成。这个应用程序会很快耗尽磁盘空间,我将向您展示如何处理这个问题。
