Docker目录解析与清理

Posted by 刘勇 on 2020-03-21

Docker目录解析与清理

背景

  • gitlab-runner服务提供的docker executor经常会出现docker lib目录空间占用大等问题。本文主要分享一下docker目录的解析与清理,尽量在清理后不影响原服务的情况下进行。

目录解析

  • docker的数据默认存放在/var/lib/docker下,容易导致导致根分区空间大,所以需要转移到数据盘。转移方式参考下文。
  • 不同存储驱动目录结构也不太一样,下面以aufs存储驱动来分析,一般的目录结构如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/var/lib/docker/
├── aufs # Storage area for AUFS driver
│ ├── diff # Branch directory of layer
│ ├── layers # Infomation about docker layer
│ └── mnt # Mount point of aufs, root of containers
├── containers # Container configurations
│ (both LXC and Docker-specific)
├── graph # Storage for the images
├── init
│ └── dockerinit-0.7.3 # Used as /sbin/init in containers
├── linkgraph.db # SQLite database storing links
│ and names.
├── lxc-start-unconfined -> /usr/bin/lxc-start # When starting a privileged
│ container, this is used in
│ lieu of lxc-start, to evade
│ AppArmor confinement (which
│ matches by exact path).
├── repositories-aufs # repository infomation
└── volumes # Storage for "anonymous" volumes
(those which are not bind-mounts)

layer目录

  • layer中镜像ID对应的是一个普通文件,文件的内容是就是该镜像的祖先镜像列表。

diff目录

  • diff目录中,包含了若干子目录,对应了Docker镜像的不同子镜像。每个目录中,包含了子镜像存储的真实文件和目录。

mnt目录

  • mnt目录中,也包含了若干子目录,对应了Docker镜像的不同子镜像。当使用该镜像创建一个容器后,在该层又会多出容器对应的层,以及该容器的init层。

容器的可写层存储在目录 /var/lib/docker/aufs/diff/,即使容器停止了,容器对应的目录依然存在。只有删除容器时,对应的目录才会删除。

目录迁移

  • 停止docker进程
1
2
systemctl disable docker.service
systemctl stop docker.service
  • umount命令卸载docker挂载的分区,如有些目录无法卸载则需使用lsof分析。
  • 移动数据目录到非根分区。
1
2
mv /var/lib/docker /home/ 
ln -s /home/docker /var/lib/
  • 启动docker进程
1
2
systemctl enable docker.service
systemctl start docker.service

深度清理

镜像清理

删除所有关闭的容器

1
docker ps -a | grep Exit | cut -d ' ' -f 1 | xargs docker rm

删除所有无tag的镜像

1
docker rmi $(docker images | grep "^<none>" | awk "{print $3}")

删除所有当前未使用的镜像

1
docker images|awk '{print $3}'|xargs docker image rm

深度清理

  • 首先执行docker system prune命令清理磁盘,它删除关闭的容器、无用的数据卷和网络,以及无tag的镜像。docker system prune -a命令清理得更加彻底,可以将没有容器使用Docker镜像都删掉。所以清理之前要三思。
1
2
docker system df
docker system prune -a
  • 如果空间是否还不够多,则删除存储驱动所在目录,以aufs为例。
1
rm -rf /var/lib/docker/aufs/
  • 如果以上目录执行时报出目录占用或者设备繁忙,则用命令cat /proc/mounts | grep "docker"查找设备加载情况并尝试卸载再删除。
1
2
3
cat /proc/mounts | grep "docker"
umount /var/lib/docker/aufs
rm -rf /var/lib/docker/aufs/

卸载重装

  • 如果以上的深度清理后,发现docker常用命令使用异常,则尝试卸载docker,再进行重装。重装后之前的目录迁移可能会失效,需要重新转移目录。
1
2
3
rm -rf /var/lib/docker/
apt-get remove docker-engine
apt-get install docker-engine


支付宝打赏 微信打赏

赞赏一下