Docker部署项目,/var/lib/docker/overlay2目录满了如何清理?

一、问题

今天突然发现跑服务器上的项目挂了,上去看了一下原来是磁盘满了。

复制代码
df -h

看来是目录 /var/lib/docker/overlay2 下占满了磁盘,看看里面是什么。

二、解决

1、查看 /var/lib/docker 目录

这一块只是查找哪些文件占满了磁盘,不感兴趣的朋友可以不看

进去到 /var/lib/docker 目录是 docker 的默认目录,进去看看

复制代码
cd /var/lib/docker

检索文件的最大深度1,即只检索汇总计算当前目录下的文件

复制代码
du -h --max-depth=1
复制代码
(1)、containers 目录

可以看到 containers 中占磁盘空间最大,这是 docker 存储容器的目录,进去看看里面有什么

看不出什么来,继续进入

可以看到一个 -json.log 的文件很大,竟然有4G多,这是 docker 的日志文件,看看 containers 目录的其他子目录是不是也有这个类型的文件

看来也有,并且和所在目录同名,直接查看所有的 -json.log 目录吧

复制代码
du -ha /var/lib/docker/containers/ | grep "json.log" | sort -rh
复制代码

把这些日志文件里面的内容清理掉,可以节省很大一部分磁盘空间。

(2)、volumes 目录

这里接着看看 volumes 目录

看到也是类似 containers 目录的东西,先进第一个看看

其中 flow.jar 是我的jar包,目录 logs 应该就是日志文件了,进去看看

还放在我的包名命名的目录里,继续进入

这里面就是应用产生的业务日志有erro日志 和info 日志 。回到 logs 目录统计一下吧

可以看到有5G多。。。

同样的方式进入 volums 目录中的第二个子目录

可以看到也有2G多。。。

也可以直接查看目录的详细信息,命令如下:

复制代码
du -ha /var/lib/docker/volumes/ | grep "info.*.log" | sort -rh

这里也先不清,后面再清

(3)、overlay2 目录

虽然只有11G,但进去发现目录挺多,先看看各个目录的大小

复制代码
du -h --max-depth=1
复制代码

找出最大的应该目录,看看里面有什么

看看哪个文件夹比较大

复制代码
du -h --max-depth=1

可以看到 merged 和 diff 占磁盘空间比较大,work 目录可以不用管

diff :

diff 文件夹是一个只读的文件系统层,它包含了Docker镜像的变更内容。当您对容器进行修改或添加新文件时,这些变更会被记录在 diff 文件夹中。每个Docker镜像都有一个对应的 diff 文件夹,用于存储与基础镜像的差异。

merged:

merged 文件夹是一个可读写的文件系统层,它是由基础镜像和 diff 文件夹合并而成的。当您启动一个Docker容器时, merged 文件夹中的内容将作为容器的文件系统。这个文件夹是容器运行时的可写层,您可以在容器中对文件进行修改或添加新文件,这些修改将存储在 merged 文件夹中

2、清理

前面已经知道了日志在下面三个路径里面

/var/lib/docker/containers
/var/lib/docker/volumes
/var/lib/docker/overlay2

(1)清理 /var/lib/docker/containers 目录

先创建清理脚本文件,这里名为 docker_logs_clean.sh ,可以自定义,命令如下:

复制代码
touch docker_logs_clean.sh

查看文件可以发现 docker_logs_clean.sh 是只读的

赋予读写权限,命令如下:

复制代码
chmod +777 docker_logs_clean.sh
复制代码

然后在加入如下脚本:

bash 复制代码
echo "======== start clean docker containers logs ========"
logs=$(find /var/lib/docker/containers/ -name *-json.log)
for log in $logs
        do
                echo "clean containers logs : $log"
                cat /dev/null > $log
        done
echo "======== end clean docker containers logs ========"

很多博客都说这个脚本可以清除还在运行的docker日志,保险起见,我这里就先把运行的容器给停了

之后执行脚本文件,命令如下:

bash 复制代码
sh docker_logs_clean.sh start

再看一下磁盘空间:

可以看到清理出一些空间了

如果保存时报如下错:

"docker_logs_clean.sh" E514: write error (file system full?)

这是因为磁盘已满,先手动清理一些空间出来。

(2)清理 /var/lib/docker/volumes 目录

假如不更新项目,只是想清一下日志,前面已经查到 /var/lib/docker/volumes 目录下的日志,这里重新查一下,命令如下:

bash 复制代码
find /var/lib/docker/volumes -name "*.log"

使用如下命令清除

bash 复制代码
find /var/lib/docker/volumes -type f -name "*.log" -delete
复制代码

可以看到那些日志文件都清除了。

假如要更新项目,则清除所有的镜像,命令如下:

bash 复制代码
docker system prune -a 

这个命令要慎用,这个命令会删除: 停止的容器、没有使用的网络、没有启动容器的镜像、还有镜像构建的缓存

复制代码

输入 y 回车就可以删除了。

删除所有的卷,命令如下:

bash 复制代码
docker volume prune

这个命令没有被使用的挂载卷

复制代码

输入 y 回车就可以删除了。

(3)清理 /var/lib/docker/overlay2 目录

经过前面的清理只剩下 /var/lib/docker/overlay2 目录占磁盘空间大一些了,使用删除镜像和容器的命令清理

bash 复制代码
docker system prune -a
复制代码

清除了2G的空间,再看一下docker磁盘占用

复制代码

可以看到 /var/lib/docker/overlay2 目录也清理得差不多了。

(4)限制docker日志大小

按照前面的方式清理,隔一段时间后磁盘又会被docker日志占满,这里设置一下日志上限

编辑 /etc/docker/daemon.json 文件,第一次应该是没有的,创建就好了,加入如下配置:

bash 复制代码
{
	"registry-mirrors": ["http://hub-mirror.c.163.com"],
	"storage-driver": "overlay2",
	"storage-opts": [
		"overlay2.override_kernel_check=true",
		"overlay2.size=15G"
	],
	"log-driver": "json-file",
	"log-opts": {
		"max-size": "1024m",
		"max-file": "3"
	}
}

解释:

registry-mirrors:设置镜像加速。

storage-driver:指定Docker的存储驱动,常见的选项包括 "overlay2"、"aufs"、"btrfs"、"devicemapper" 和 "zfs",一般为 "overlay2"。

storage-opts:存储驱动程序选项。

log-driver:容器日志的默认驱动程序,默认为 "json-file" 。

log-opts:容器默认日志驱动程序选项。

然后重新加载一下docker的配置文件

bash 复制代码
systemctl daemon-reload

再重启一下docker

bash 复制代码
systemctl restart docker

注意,重启之后原来的镜像和容器要删除,不然重新启动是报错的!!!

如果启动容器时报如下错就是因为没有重新拉取镜像。

docker: Error response from daemon: open /var/lib/docker/overlay2/2ef38eb701745d5e944dd8c04d404347cd1d7d87140ff48817c935901bcd9550/committed: no such file or directory.

复制代码

假如重启docker失败

报错如下:

docker.socket: Failed with result 'service-start-limit-hit'.

只要把 daemon.json 的改为 daemon.conf ,命令如下:

mv /etc/docker/daemon.json /etc/docker/daemon.conf

再次重启就好了。

(5)、限制docker-compose的单个容器日志

这个只有使用docker-compose部署项目的小伙伴才能用到,在每个容器配置下加入如下配置:

bash 复制代码
logging:
  driver: "json-file"
  options:
    max-size: "256m"
    max-file: "3"

然后再使用docker-compose命令启动容器。

3 、快速清理

步骤2是常规清理,docker占用磁盘太多一般无非2种情况:无用的镜像 和容器太多

我们可以使用以下命令大致看下情况

bash 复制代码
docker system df -v

# 用于清理磁盘,删除关闭的容器、无用的数据卷和网络,以及无tag的镜像。

docker system prune

# 可以将没有容器使用 Docker 镜像都删掉。注意,这两个命令会把你暂时关闭的容器,以及暂时没有用到的Docker镜像都删掉了 -a 参数建议慎用

docker system prune -a

容器输出的日志太大

这种情况往往是容器长时间运行,容器打印了大量的日志未清理,占据了大量磁盘空间。比如之前运行的一个Jenkins容器,运行几个月后,打印的日志占了近10个G的磁盘。这种情况下清理日志文件就行了。

容器的日志文件在/var/lib/docker/containers /{containerId}下:

root@i-h8v5dv1n 55406a3ac6f4a59555897c606677201853973f4266c32284eeb8274682fd099d# ls -al total 512 drwx-----x 4 root root 4096 Feb 8 17:57 . drwx-----x 4 root root 4096 Feb 8 17:54 .. # -json.log就是日志文件 -rw-r----- 1 root root 478546 Feb 8 18:05 55406a3ac6f4a59555897c606677201853973f4266c32284eeb8274682fd099d-json.log drwx------ 2 root root 4096 Oct 28 15:01 checkpoints -rw------- 1 root root 4911 Feb 8 17:57 config.v2.json -rw-r--r-- 1 root root 1782 Feb 8 17:57 hostconfig.json -rw-r--r-- 1 root root 13 Feb 8 17:57 hostname -rw-r--r-- 1 root root 174 Feb 8 17:57 hosts drwx-----x 2 root root 4096 Oct 28 15:01 mounts -rw-r--r-- 1 root root 131 Feb 8 17:57 resolv.conf -rw-r--r-- 1 root root 71 Feb 8 17:57 resolv.conf.hash

可以删除日志文件,也可调整应用程序让打印的日志保持在某种大小。

日志、大文件占用了 /dev/vda1 分区

还有一种情况就是 一些日志文件,大文件占用了 /dev/vda1 分区。这个分区一般是挂载在 "/" 下面。

所以我们可以重点关注下面几个目录:

  • /var/tmp

  • /var/log

  • /root

三、总结

docker 容器占用磁盘空间多的情况,大部分因为是因为长时间没有清理日志或者没有的镜像容器太多占了磁盘空间。可以删除日志之后限制日志文件大小。或者使用

docker system prune或者 docker system prune -a 命令删除不用的镜像与容器。