谁用光了磁盘?Docker System命令详解

Docker镜像,容器,数据卷以及网络都会占用主机的磁盘空间,这样的话,磁盘很容易就会被用完。这篇博客介绍了一个简单的解决方案 - Docker System命令docker

用了一段时间Docker后,会发现它占用了很多硬盘空间。还好Docker 1.13引入了解决方法,它提供了简单的命令来查看/清理Docker使用的磁盘空间。缓存

本文经过一个简单的示例,能够证实Docker可以很快地将磁盘占满。该示例经过play-with-docker.com运行。点击Add new instance便可建立新的实例,该实例安装了最新版的Docker 17.03。这篇博客主要讨论磁盘空间,那么不妨使用df命令查看磁盘的初始状态:网络

$ df -h
Filesystem           Size       Used Available Use% Mounted on
/dev/mapper/...      10.0G    443.3M      9.6G   4% /
tmpfs                60.0G         0     60.0G   0% /dev
tmpfs                60.0G         0     60.0G   0% /sys/fs/cgroup
/dev/xvda1           49.1G      3.7G     43.3G   8% /etc/resolv.conf
/dev/xvda1           49.1G      3.7G     43.3G   8% /etc/hostname
/dev/xvda1           49.1G      3.7G     43.3G   8% /etc/hosts
shm                  64.0M         0     64.0M   0% /dev/shm
/dev/mapper/...      10.0G    443.3M      9.6G   4% /graph/overlay2

可知,一共有10GB磁盘空间,其中接近500MB已被占用。app

接下来编写Dockerfile来建立一个镜像。这个镜像基于Alpine镜像;镜像将写入3个随机的文件,每一个文件1GB,文件由dd命令生成;由于这个镜像并无实际做用,所以CMD设为/bin/trueide

FROM alpine
RUN dd if=/dev/zero of=1g1.img bs=1G count=1
RUN dd if=/dev/zero of=1g2.img bs=1G count=1
RUN dd if=/dev/zero of=1g3.img bs=1G count=1
CMD /bin/true

运行   docker build -t test .   便可建立镜像,执行完成后将生成一个3GB的镜像。ui

$ docker image ls
REPOSITORY          TAG                CREATED             SIZE
test                latest             38 seconds ago      3.23GB
alpine              latest             5 weeks ago         3.99MB

不难理解,该镜像占用了相应大小的磁盘空间。atom

$ df -h
Filesystem        Size       Used Available Use% Mounted on
/dev/mapper/...   10.0G      3.4G      6.5G  34% /

若只写入2个随机文件,则须要修改Dockerfile,删掉一行。为了不构建镜像时使用缓存,我在dd命令以前添加了一行echo命令。spa

FROM alpine
RUN echo foo
RUN dd if=/dev/zero of=1g1.img bs=1G count=1
RUN dd if=/dev/zero of=1g2.img bs=1G count=1
# RUN dd if=/dev/zero of=1g3.img bs=1G count=1
CMD /bin/true

原本觉得这样能够节省1GB磁盘空间,然而实际状况更加糟糕!blog

$ df -h
Filesystem        Size       Used Available Use% Mounted on
/dev/mapper/...   10.0G      5.4G      4.5G  54% /

旧的Docker镜像一直存在,最终磁盘空间会很快被用完。Docker 1.13引入了docker system df命令,相似于Linux上的df命令,用于查看Docker的磁盘使用状况。ci

$ docker system df
TYPE                TOTAL     ACTIVE    SIZE          RECLAIMABLE
Images              3         0         5.373GB       5.373GB (100%)
Containers          0         0         0B            0B
Local Volumes       0         0         0B            0B

可知,实例上一共有3个Docker镜像: apline镜像,包含3个1GB随机文件的镜像以及包含2个1GB随机文件的镜像。这些镜像占用了超过5GB磁盘空间。因为咱们并无基于这些镜像运行容器,因此它们均可以被删除,因此可回收的(RECLAIMABLE)磁盘空间为100%。使用docker run test运行test镜像再查看:

$ docker system df
TYPE                TOTAL     ACTIVE    SIZE          RECLAIMABLE
Images              3         1         5.373GB       3.225GB (60%)
Containers          1         0         0B            0B
Local Volumes       0         0         0B            0B

如今状况就不一样了,我运行了一个容器,它执行/bin/true以后就很快退出了。这个容器绑定了test镜像,test镜像被标记为活跃(active)于是不能被删除,这致使可回收的磁盘空间变少了。

如今来清理一下磁盘空间。Docker提供了:docker system prune,能够用于清理dangling镜像(参考What are Docker : images?)和容器,以及失效的数据卷和网络。

$ docker system prune
WARNING! This will remove:
        - all stopped containers
        - all volumes not used by at least one container
        - all networks not used by at least one container
        - all dangling images
Are you sure you want to continue? [y/N] y
Deleted Containers:
1cdf866157b4a97e151125af3c2a7f186a59b6f63807e2014ce1a00d68f44e1d
Deleted Images:
deleted: sha256:f59bb277...
deleted: sha256:695b8e70...
deleted: sha256:93b1cceb...
deleted: sha256:c74d6bcd...
deleted: sha256:df8b9bb1...
deleted: sha256:dfe8340f...
deleted: sha256:ce1ee654...
Total reclaimed space: 3.221GB

根据警告信息可知,这个命令会删除全部关闭的容器以及dangling镜像。示例中,含有3个1GB随机文件的镜像的名称被占用了,名称为:,为dangling镜像,所以会被删除。同时,全部的中间镜像也会被删除。这样的话,一共3GB的磁盘空间被回收了!

更进一步,使用-a选项能够作深度清理。这时咱们会看到更加严重的WARNING信息:

$ docker system prune -a
WARNING! This will remove:
        - all stopped containers
        - all volumes not used by at least one container
        - all networks not used by at least one container
        - all images without at least one container associated to them
Are you sure you want to continue? [y/N] y
Deleted Images:
untagged: test:latest
deleted: sha256:c515ebfa2...
deleted: sha256:07302c011...
deleted: sha256:37c0c6474...
deleted: sha256:5cc2b6bc4...
deleted: sha256:b283b9c35...
deleted: sha256:8a8b9bd8b...
untagged: alpine:latest
untagged: alpine@sha256:58e1a1bb75db1...
deleted: sha256:4a415e366...
deleted: sha256:23b9c7b43...
Total reclaimed space: 2.151GB

这个命令将清理整个系统,而且只会保留真正在使用的镜像,容器,数据卷以及网络,所以须要格外谨慎。好比,咱们不能在生产环境中运行  prune -a  命令,由于一些备用镜像(用于备份,回滚等)有时候须要用到,若是这些镜像被删除了,则运行容器时须要从新下载。

此时,全部未绑定容器的镜像将会被删除。因为第一次prune命令删除了全部容器,所以全部镜像(它们没有绑定任何容器)都会被删除。

$ df -h
Filesystem          Size      Used Available Use% Mounted on
/dev/mapper/...    10.0G    442.5M      9.6G   4% /

如今,已使用的磁盘空间又变成了4%。本文的示例只是冰山一角,由于一旦咱们运行了真正的容器,而且使用了Docker数据卷和Docker网络,则磁盘空间将会更快用完。

相关文章
相关标签/搜索