前言
Docker 容器器长时间运行时,它产生的日志可能会占用更多的空间。如果你像我一样使用小水管级服务器,很容易爆炸。此时,您需要清理它。今天,我碰巧遇到了这种情况,如下图所示:
从上图可以看出,空间利用率已经达到了 100% 这些数据主要集中在 docker 的 overlay2 上,借此清理 Docker 回顾一下机会 Docker 一些相关知识。
查看 Docker 空间占用
有了 Docker,在大多数情况下,我们不再需要太在意环境问题,但我们也付出了一些代价,占用空间就是其中之一。
通过下面的命令,你可以知道 Docker 占用空间:
dockersystemdf
该命令列出了 docker 使用磁盘的 4 种类型:
Images: 所有镜像占用的空间,包括提取的镜像和当地建造的镜像
Containers: 运行中容器占用的空间(不运行就不占空间)实际上是每个容器读写层的空间
Local Volumes: 本地数据卷空间
Build Cache: 在镜像构建过程中产生的缓存数据
对我来说,我会加上这个命令。 - v 参数,即 docker system df -v
,如下图所示:
我在这张图中看到的主要信息是哪些容器和数据卷没有使用。此时,可以通过以下命令进行清理 Docker 占用空间。
dockersystemprune-a
该命令将删除暂停的容器、无相关容器的镜像、无相关容器 tag 简单来说,没有使用的镜像和数据卷 run 或者所有使用的东西都被清理掉了,请注意,如果你有一些暂停的容器,这个命令也会被清理掉。
为了深入了解上述命令的作用,首先讨论使用情况 docker 当镜像创建容器时,docker创建哪些目录:
我们使用 docker 当镜像创建容器时,docker例如:
/var/lib/docker/containers/<容器ID>
目录,如果容器采用默认日志模式,则容器日志将使用 JSON 形式保存在此目录下。/var/lib/docker/overlay2
该目录包含容器的读写层。如果容器使用自己的文件系统保存数据,这些数据将写入该目录。
为了更直观,弄个干净的 Linux 服务器(就在去年 11 买了 Linux 在演示创建容器的过程中,服务器),docker 占用空间的变化。
一开始,docker 不占用任何空间:
[root@clickhouse~]#dockersystemdf TYPETOTALACTIVESIZERECLAIMABLE Images000B0B Containers000B0B LocalVolumes000B0B BuildCache000B0B
拉取 busybox镜像,占用磁盘空间
BusyBox 是一个集成了一百多个最常用 Linux 命令和工具(如 cat、echo、grep、mount、telnet 等)精简工具箱,它只需要几个 MB 各种快速验证非常方便,被称为 “Linux 瑞士军刀系统。
可以发现 Images 行,有了 busybox 镜像占用空间
[root@clickhouse~]#dockersystemdf TYPETOTALACTIVESIZERECLAIMABLE Images111.24MB0B(0%) Containers110B0B LocalVolumes000B0B BuildCache000B0B
然后我们运行 busybox 并创建 100M 命令为:
[root@clickhouse~]#dockerrun-itbusybox #创建名为ayu.img的空文件 /#ddif=/dev/zeroof=ayu.imgbs=1024count=102400 102400 0recordsin 102400 0recordsout 104857600bytes(100.0MB)copied,0.403244seconds,248.0MB/s /#
占用空间如下图所示:
[root@clickhouse ~]# docker system df
TYPE TOTAL ACTIVE SIZE RECLAIMABLE
Images 1 1 1.24MB 0B (0%)
Containers 1 1 104.9MB 0B (0%)
Local Volumes 0 0 0B 0B
Build Cache 0 0 0B 0B
可以发现,Containers 行的 SIZE 变为了 104.9MB,此时这些被占用空间是不可被回收的(RECLAIMABLE 列还是为 0B)。
如果你没有修改 docker 默认的配置,此时空文件会保存在 /var/lib/docker 目录中的某个位置,可以通过 find 命令准确定位出来,命令如下:
#查找名为ayu.img的空文件
[root@clickhouse ~]# find /var/lib/docker/ -type f -name ayu.img
/var/lib/docker/overlay2/f0c37adb84cfe3ccefcb25434f374235a8d99c157be6f8eb1c8389de18c2152b/merged/ayu.img
/var/lib/docker/overlay2/f0c37adb84cfe3ccefcb25434f374235a8d99c157be6f8eb1c8389de18c2152b/diff/ayu.img
当我们停止 busybox 容器后,容器占用的空间就变得可回收了,效果如下:
[root@clickhouse ~]# docker system df
TYPE TOTAL ACTIVE SIZE RECLAIMABLE
Images 1 1 1.24MB 0B (0%)
Containers 1 0 104.9MB 104.9MB (100%)
Local Volumes 0 0 0B 0B
Build Cache 0 0 0B 0B
看到 Containers 行的 RECLAIMABLE 列,其值变为 104.9MB,即此时容器停止了,容器占用的空间可以被回收了。
然后便可以通过 docker system prune -a
删除所有不使用的镜像、容器和数据卷了,效果如下:
[root@clickhouse ~]# docker system prune -a
WARNING! This will remove:
- all stopped containers
- all networks not used by at least one container
- all images without at least one container associated to them
- all build cache
Are you sure you want to continue? [y/N] y
Deleted Containers:
c4f21e236ad67513e2d5dbe92ebaae71f5609217575b6e996d95a96ad0237450
Deleted Images:
untagged: busybox:latest
untagged: busybox@sha256:afcc7f1ac1b49db317a7196c902e61c6c3c4607d63599ee1a82d702d249a0ccb
deleted: sha256:ec3f0931a6e6b6855d76b2d7b0be30e81860baccd891b2e243280bf1cd8ad710
deleted: sha256:d31505fd5050f6b96ca3268d1db58fc91ae561ddf14eaabc41d63ea2ef8c1c6d
Total reclaimed space: 106.1MB
[root@clickhouse ~]# docker system df
TYPE TOTAL ACTIVE SIZE RECLAIMABLE
Images 0 0 0B 0B
Containers 0 0 0B 0B
Local Volumes 0 0 0B 0B
Build Cache 0 0 0B 0B
如果不希望删除镜像,而只是将无用的数据卷、容器等删除,则使用 docker system prune
命令(即不添加 - a 参数),效果如下:
[root@clickhouse ~]# docker system df
TYPE TOTAL ACTIVE SIZE RECLAIMABLE
Images 1 1 1.24MB 0B (0%)
Containers 1 0 104.9MB 104.9MB (100%)
Local Volumes 0 0 0B 0B
Build Cache 0 0 0B 0B
[root@clickhouse ~]# docker system prune
WARNING! This will remove:
- all stopped containers
- all networks not used by at least one container
- all dangling images
- all dangling build cache
Are you sure you want to continue? [y/N] y
Deleted Containers:
f751982675af0e510fde360b08e4734c8c2d0d43260b2065610e66932db44186
Total reclaimed space: 104.9MB
[root@clickhouse ~]# docker system df
TYPE TOTAL ACTIVE SIZE RECLAIMABLE
Images 1 0 1.24MB 1.24MB (100%)
Containers 0 0 0B 0B
Local Volumes 0 0 0B 0B
Build Cache 0 0 0B 0B
df 与 du 不匹配
因为我不在乎 docker 镜像数据,根据上面的讨论,通过 docker system prune -a
命令清除一下就好了,如下图所示,清理了 897.1MB
清理后,发现空间占用小了一点,但无济于事,如下图:
通过上面的操作,Docker 相关的数据应该清理干净了,但是磁盘空间却没有明显的降低,而且通过 df 命令查看,overlay2 依旧占据大量空间,这是怎么回事?
很明显,出现了意料之外的情况,简单思索,我并不在乎当前 docker 容器中的数据,既然 docker system prune -a
没啥效果,那么就上 df 命令与 du 命令,定位出占据磁盘空间最大的文件或文件夹,直接删除它就好了。
很快我发现 df 命令查询出的磁盘空间占用大小与 du 命令查询出的磁盘空间占用大小不同,如下图所示:
之所以出现这种情况,通常是因为很多删除的文件依旧被某些程序引用着,导致磁盘空间无法被回收,对于这种情况,df 命令会统计,即认为空间还是被占用着,而 du 命令不会统计,从而导致了两个命令统计出的磁盘空间其大小是不同的。
通过 lsof | grep deleted
命令查看那些引用着被删除文件的进程,发现了一堆,如下图:
将这些进程 kill 掉,再看 df 和 du 就一致了。
此时,Docker 占用的磁盘空间就被清理出来了。
docker 构建失败
因为在清理过程中,我尝试过强制删除了 overlay2 下的文件,这导致使用 docker 构建镜像时,会报 failed to create rwlayer: symlink
错误:
failed to create rwlayer: symlink ../d09af977422891715fe2ec64c353b761481337720a906228f3cdc335df1850b3/diff /volumes01/docker/overlay2/l/POZR4HXDGJ32OEJJZHXJKQMTOS: no such file or directory
此时重新启动一下 docker 便可解决这个问题
结尾
这篇文章写在周日时光,我特意去公司加班,打算研究点项目,结果被这事消耗了些时间,果然,运维类问题永远是时间杀手。
我是二两,记录就水到这,我们下篇文章见。