背景:
服务器磁盘满了,查看本地docker目录下占用太多,需要清除下不用的文件腾出资源,删除了/var/lib/docker/overlay2 下的文件,导致重新启动容器失败,启动新容器例如hello-world也失败
docker的overlay2存储的是什么?为什么能有这么大的占用
查询官方说明,overlay2是docker使用的文件存储驱动,也就是说,在/var/lib/docker/overlay2目录下的文件都是docker使用的存储
overlay2是分层存储,每一层通过本层的md5作为文件夹名来命名,如果要存储的两个东西【比如两个镜像】的底层几层的内容是一样的,那他们的md5就也是一样的,通过md5核验,确认他们这几层是一样的之后,在overlay2中实际存储的时候,这几层就可以只存储一份,然后由这两个东西共用,来达到节省空间的目的。
/var/lib/docker/overlay2 目录是 Docker 存储驱动程序之一
Overlay2 的默认存储目录,用于保存 Docker 容器镜像和容器数据。
Overlay2 是一个基于内核的图层存储驱动程序,可以通过将多个只读层叠加到单个可写层来创建 Docker 容器。
Overlay2 驱动程序使用了基于 inode 的存储模型,它将不同的图层都挂载到相同的文件系统目录下,同时使用不同的命名空间来进行隔离。
在 /var/lib/docker/overlay2 目录下,每个容器都对应一个文件夹,文件夹的名称是由两个长随机字符串组成的,每个字符串对应一个不同的命名空间。其中一个字符串对应于 Overlay2 驱动程序的命名空间,它用于标识这个容器的图层;另一个字符串对应于挂载点的命名空间,用于在宿主机文件系统中创建一个目录,用于挂载这个容器的可写层。
每个容器的文件夹中包含多个子目录,其中最重要的是 diff 目录,它用于存储容器的可写层。当 Docker 容器需要修改文件时,Overlay2 驱动程序会将这些修改记录在 diff 目录下的文件中。除了 diff 目录,每个容器的文件夹中还包含 merged 目录、lowerdir 目录和 upperdir 目录,用于存储容器的只读层和可写层。
具体来说,当 Docker 运行容器时,它会在 /var/lib/docker/overlay2 目录下为容器创建一个唯一的文件夹,其中包含了容器的文件系统的层级结构。该文件夹的名称以 l 开头,后跟 64 个字符的十六进制字符串,这个字符串是该容器的唯一 ID,例如:
/var/lib/docker/overlay2/l4j4t4c3k3ck0ec13c4a5798d274b16523e86029292bfb9bb9c4a4a4c3d0e4b4
在这个目录中,Overlay2 存储了容器的所有文件系统层。当容器启动时,Docker 会将这些层级结构组合在一起,形成容器的完整文件系统,使其看起来像是一个完整的文件系统,而实际上是由多个层级结构组合而成的。
解决办法:
重启docker
systemctl restart docker
然后启动一个容器试试
如果问题不能完美解决
ps: 如果不重启docker 还是会同样报错
ps:也可以将docker系统目录/var/lib/docker/下的overlay2文件夹,整个删掉,再重启docker后,会自动创建出新的overlay2文件夹目录,里边存放所必须的文件。这个时候重新run容器就会成功
如何清理docker磁盘占用
docker system df # 可查看 Docker 所占用的空间:
其中 Images 表示镜像,Containers 表示容器,Local Volumes 表示本地卷,Build Cache 表示构建缓存。
整体清理
可以通过 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]
该操作会删除所有停止的容器,所有未被至少一个容器使用的网络,所有的 dangling 镜像(在构建镜像时产生的 tag 为 none 的镜像,没有和任何其他有 tag 的镜像有关联),所有的 dangling 构建缓存(和 dangling 镜像同理)。
更激进一点,还可以执行 docker system prune -a,该操作还会删除没有和运行中的容器有关联的镜像。
docker system prune -a #
我们看到目录下被清空了
镜像清理:
docker rm <image_name> [-f]
容器清理:
docker container rm <containerid_or_name>
网络清理:
docker network ls
docker network rm <net_work_name>
数据卷清理:
docker volume ls
docker system prune -a --volumes # 是在 docker system prune -a的基础上删除所有未使用的卷。