摘要:最近线上服务经常出现一些奇奇怪怪的问题,比如网页上的静态资源加载不出来,或者请求后端莫名报错,又或者 Redis 报错…
最近线上服务经常出现一些奇奇怪怪的问题,比如网页上的静态资源加载不出来,或者请求后端莫名报错,又或者 Redis 报错…
当我 SSH 登录到服务器上时,更不对劲了,敲个命令都卡顿…
如果是以前没经验,或许会以为遇到了疑难杂症,但作为多年的 Linux 用户,我已经知道了这种种异常的背后是「存储空间已满」在作祟!
那么问题就来到了「硬盘空间去哪儿了?」
首先是最常用的命令
df -h先来看看各个磁盘和挂载点的情况
在我的服务器上执行这个命令之后发现,根目录的可用空间已经只剩下几百 KB 了…
使用 du 命令可以查看各个子目录占用的空间,然后再结合 sort 命令排个序
sudo du -h --max-depth=1 / | sort -hr参数说明:
因为要直接统计根目录,所以需要有 root 权限--max-depth=1:仅显示当前目录及其下一级子目录的占用情况。sort -hr:按照大小进行降序排列。查看目录的总占用空间:
du -sh /前面的 du 命令,还是没那么好用,主要是列出来的数据太多了。
这次我用上了 ncdu 工具
ncdu 是一个更加用户友好的磁盘使用分析工具,支持交互式界面。
不过很多发行版没有内置,需要先安装:
sudo apt install ncdusudo ncdu -x /使用 -x 参数可以限制扫描范围为当前文件系统,不跨越挂载点。因为根目录下有很多其他硬盘的挂载点,根据前面使用 df 命令的分析,是主硬盘满了,所以我只要看主硬盘的就行。
ncdu 启动之后会扫描各个文件的存储空间,然后进入一个交互式界面,可以很直观的看到各个目录的占用空间大小,从大到小排序。
罪魁祸首#在 ncdu 里可以很直观看到 /var/lib/Docker 这个目录占用了 70% 以上的存储空间,妥妥的答辩啊!
使用 du 分析
sudo du -h --max-depth=1 /var/lib/docker | sort -hr之后大概的占用情况是这样(只是例子,不是真实数据)
10G /var/lib/docker/overlay25G /var/lib/docker/volumes1G /var/lib/docker/containers500M /var/lib/docker/images基本就是 docker 的镜像、容器日志、卷之类的把硬盘吃掉了
找到了问题,那就好办了
首先把没用的 docker 容器停掉
然后执行一下 docker 提供的一些清理命令。
Docker 提供了 docker system prune 命令,能清理未使用的资源。
docker system prune -a-a:删除所有未使用的镜像(包括没有关联到容器的镜像)。注意:这个命令不会删除被正在运行的容器依赖的资源,请小心操作。如果是 /var/lib/docker/volumes 占用空间较多:
如果是 /var/lib/docker/network 占用较多:
删除无用的镜像#删除无用的卷#在分析存储空间的占用过程中,我还发现有个文件特别离谱,下面这个文件,500多个G…
/var/lib/docker/containers/e4b5a99b429a612885417460214ea40a6a49a3360c29180af800ff7aef4c03df/e4b5a99b429a612885417460214ea40a6a49a3360c29180af800ff7aef4c03df-json.log来看看是哪个容器拉的屎。
日志文件的路径中包含了容器的 ID:e4b5a99b429a612885417460214ea40a6a49a3360c29180af800ff7aef4c03df
来找一下是哪个容器:
docker ps | grep e4b5a99b429a在容器列表中找不到该容器,可能它已经被停止或删除了。在这种情况下,可以使用 docker inspect 检查具体信息:
可以通过 tail 或 less 查看日志内容,检查是否有异常输出:
sudo tail -n 50 /var/lib/docker/containers/e4b5a99b429a612885417460214ea40a6a49a3360c29180af800ff7aef4c03df/e4b5a99b429a612885417460214ea40a6a49a3360c29180af800ff7aef4c03df-json.log日志的具体内容我就不贴了,看起来应该没啥问题,就是运行久了,日积月累…
处理这个问题的方法,见下一小节。
每个容器的日志存储在 /var/lib/docker/containers//-json.log。
使用以下命令找到最大的日志文件:
sudo find /var/lib/docker/containers/ -type f -name "*.log" -exec du -h {} + | sort -hr | head -n 10清空一个特定容器的日志文件:
sudo truncate -s 0 /var/lib/docker/containers//-json.log在 Docker 的配置文件中限制日志大小(推荐):
编辑 Docker 配置文件(通常是 /etc/docker/daemon.json):sudo nano /etc/docker/daemon.json添加或修改以下配置:{ "log-driver": "json-file", "log-opts": { "max-size": "10m", "max-file": "3" } }max-size:单个日志文件最大 10 MB。max-file:保留 3 个日志文件。重新加载 Docker:sudo systemctl restart docker在迁移数据之前,需要先停止 Docker 服务:
假设新磁盘挂载在 /mnt/new-disk,执行以下命令:
sudo mv /var/lib/docker /mnt/new-disk/docker将新的路径链接回 /var/lib/docker,让 Docker 继续按默认路径工作:
sudo ln -s /mnt/new-disk/docker /var/lib/dockersudo systemctl start docker运行以下命令确保 Docker 正常工作:
docker info方法二:修改 Docker 配置文件,指定新存储位置#停止 Docker 服务#将现有数据迁移到新磁盘挂载点。例如,新磁盘挂载在 /mnt/new-disk:
编辑 Docker 的配置文件(通常是 /etc/docker/daemon.json),指定新的存储路径:
sudo nano /etc/docker/daemon.json添加或修改以下内容:
{"data-root": "/mnt/new-disk/docker"}验证#再次检查 Docker 是否正常运行:
docker info | grep "Docker Root Dir"你应该能看到新的路径(如 /mnt/new-disk/docker)。
如果想直接将新磁盘作为 /var/lib/docker 的挂载点,可以使用以下方法
格式化新磁盘#假设新磁盘为 /dev/sdb1,先格式化并创建文件系统(如 ext4):
sudo mkfs.ext4 /dev/sdb1挂载新磁盘#将新磁盘挂载到 /var/lib/docker:
sudo mount /dev/sdb1 /var/lib/docker迁移现有数据#如果 /var/lib/docker 目录下已有数据,需要先复制到新磁盘:
sudo rsync -a /var/lib/docker/ /mnt/new-disk/然后再将新磁盘挂载回 /var/lib/docker。
/dev/sdb1 /var/lib/docker ext4 defaults 0 2通过以上方法,可以成功将 /var/lib/docker 挂载到其他磁盘,缓解存储压力并优化存储布局。
如果清理后空间仍然不足,可以重建 Docker 的存储目录(会删除所有容器、镜像和数据)
停止 Docker 服务:
sudo systemctl stop docker备份现有 Docker 数据(可选):
sudo mv /var/lib/docker /var/lib/docker.bak创建一个新的空目录:
sudo mkdir /var/lib/docker启动 Docker 服务:
在这次 Linux 服务器硬盘空间消失问题的排查过程中,我经历了一次完整的存储分析和优化实战。
初步排查存储占用情况使用 du 和 ncdu 等工具,快速定位占用空间较大的目录。发现 /var/lib/docker 目录占用了大量存储空间。深入定位具体问题找到具体的容器日志文件路径,通过容器 ID 确认了是哪个容器产生了大量日志。使用 docker inspect 和 docker logs,进一步分析日志内容。解决问题清空了过大的容器日志文件,通过 truncate 命令立即释放空间。修改 Docker 配置文件(daemon.json)限制了日志文件的大小,避免类似问题再次发生。验证与优化重启 Docker 服务后,验证了服务正常运行。使用 docker system prune 清理了无用资源,并规划了日志管理策略。系统监控的重要性:及时监控存储使用情况,可以避免问题扩大化。日志管理最佳实践:过度增长的日志文件是常见的存储占用原因,必须设置合理的日志大小限制。工具的高效使用:du、ncdu 和 Docker 命令等工具在排查问题中大大提升了效率。日常维护习惯:定期清理无用的容器资源(例如停止的容器、未使用的镜像),可以保持系统健康运行。这次实践不仅解决了磁盘空间问题,也让我对 Linux 系统管理和 Docker 的运维有了更深的理解。在未来的运维工作中,我将更加注重系统的监控与优化,提前预防类似问题的发生。
出处:https://www.cnblogs.com/deali/p/18612139
来源:科技前沿