Docker 磁盘清理

在使用 docker 的时候,经常需要下载镜像,给镜像打标签,然后又因为没有及时清理无用的镜像,久而久之,docker 就会把宿主机的磁盘空间占满,导致系统异常。对于 docker 磁盘占用的问题,可以通过 docker 自带的 prune 命令清理或者迁移 docker 下的 overlay2 文件夹来解决。

Docker 磁盘清理

通过 prune 清理

查看磁盘使用情况

1
du -sh /var/lib/docker

查看 docker 磁盘占用

1
docker system df

该命令可以用于查看 Docker 环境中的磁盘使用情况,包括镜像、容器、数据卷和网络等资源的使用情况。

1
docker system df -v

docker system df 命令不同的是,该命令可以进一步查看空间占用细节,以确定是哪个镜像、容器或本地卷占用过高空间。

清理 docker 磁盘占用

自动清理

如果您只想清理未被使用的容器、数据卷和网络等资源,可以使用以下命令:

1
docker system prune

该命令会清理未被使用的容器、数据卷和网络等资源,但不会删除未被使用的镜像。

该命令所清理的对象如下:

  • 已停止的容器
  • 未被任何容器使用的卷
  • 未被任何容器所关联的网络
  • 所有悬空的镜像

对于上面提到的一些镜像或容器的状态所代表的含义如下:

  • 已使用的镜像:指所有已被容器(包括 stop 的)关联的镜像,也就是 docker ps -a 所看到的所有容器对应的 image
  • 未引用镜像:没有被分配或使用在容器中的镜像
  • 悬空镜像(dangling image):未配置任何 tag(也就是无法被引用)的镜像。通常是由于镜像编译过程中未指定 -t 参数配置 tag 导致的。

如果想清理所有未被使用的镜像,可以使用 -a 参数:

1
docker system prune -a

该命令会提示您确认是否要清理无用资源,确认后将会删除所有无用资源(包括未被使用的镜像、已停止的容器、未被使用的数据卷和网络等),释放磁盘空间。请注意,该命令会删除所有未被使用的镜像,包括您手动下载的镜像和 Docker 官方镜像,因此请谨慎使用。

删除无用的容器:

1
docker container prune
  • 默认情况下 docker container prune 会清理掉所有处于 stopped 状态的容器

  • 如果不想都删掉,也可以使用 --filter 标志来筛选出不希望被清理掉的容器

    例子:清除掉所有停掉的容器,但24内创建的除外。

    1
    docker container prune --filter "until=24h"

删除无用的卷:

1
docker volume prune

删除无用的网络:

1
docker network prune

手动清理

(1)删除所有悬空镜像,不删除未使用镜像:

1
docker rmi $(docker images -f "dangling=true" -q)

(2)删除所有未使用镜像和悬空镜像

1
docker rmi $(docker images -q)

(3)删除所有未被容器引用的卷

1
docker volume rm $(docker volume ls -qf dangling=true)

如果卷占用空间过高,可以清除一些不使用的卷,包括一些未被任何容器调用的卷(-v 详细信息中若显示 LINKS = 0,则是未被调用)

(4)删除容器

删除所有已退出的容器:

1
docker rm -v $(docker ps -aq -f status=exited)

具体来说,该命令使用了以下参数:

  • -a:列出所有的容器,包括正在运行的容器和已经停止的容器。
  • -q:只列出容器的 ID,而不显示容器的详细信息。
  • -f status=exited:只列出状态为 "exited" 的容器,即已经退出的容器。

删除所有状态为 dead 的容器:

1
docker rm -v $(docker ps -aq -f status=dead)

如果发现是容器占用过高的空间,可以手动删除一些。

迁移 /var/lib/docker

/var/lib/docker/overlay2 占用很大,要想清理 Docker 占用的磁盘空间,可以考虑迁移 /var/lib/docker 目录。

停止 docker 服务

1
systemctl stop docker

创建新的分区目录

创建一个磁盘空间更大的分区目录,例如:/home/lib/docker

迁移 /var/lib/docker

1
rsync -avz /var/lib/docker /home/lib/docker

配置 devicemapper.conf

配置 /etc/systemd/system/docker.service.d/devicemapper.conf(查看 devicemapper.conf 是否存在,如果不存在则创建)

1
2
mkdir -p /etc/systemd/system/docker.service.d/
vim /etc/systemd/system/docker.service.d/devicemapper.conf

配置内容如下:

1
2
[Service]
ExecStart=/usr/bin/dockerd --graph=/home/lib/docker/docker

重启 docker

1
2
systemctl daemon-reload
systemctl restart docker

验证

1
docker info

命令检查 Docker 的根目录,它将被更改为 /home/lib/docker/docker

1
2
3
4
5
6
...
Docker Root Dir: /home/lib/docker/docker
Debug Mode (client): false
Debug Mode (server): false
Registry: https://index.docker.io/v1/
...

查看之前的镜像是否还在:

1
2
3
4
5
[root@localhost ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
demo 0.0.1 4fa4c5aae26d 4 months ago 378MB
adoptopenjdk/openjdk11 alpine 552165ab2add 4 months ago 343MB
registry 2.8.1 dcb3d42c1744 5 months ago 24.1MB

确定容器没问题后删除 /var/lib/docker 目录下的文件:

1
rm -rf /var/lib/docker/*