- VisualStudio2022插件的安装及使用-编程手把手系列文章
- pprof-在现网场景怎么用
- C#实现的下拉多选框,下拉多选树,多级节点
- 【学习笔记】基础数据结构:猫树
最近线上服务经常出现一些奇奇怪怪的问题,比如网页上的静态资源加载不出来,或者请求后端莫名报错,又或者 Redis 报错… 。
当我 SSH 登录到服务器上时,更不对劲了,敲个命令都卡顿… 。
如果是以前没经验,或许会以为遇到了疑难杂症,但作为多年的 Linux 用户,我已经知道了这种种异常的背后是「存储空间已满」在作祟! 。
那么问题就来到了「硬盘空间去哪儿了?」 。
首先是最常用的命令 。
df -h
先来看看各个磁盘和挂载点的情况 。
在我的服务器上执行这个命令之后发现,根目录的可用空间已经只剩下几百 KB 了… 。
使用 du 命令可以查看各个子目录占用的空间,然后再结合 sort 命令排个序 。
sudo du -h --max-depth=1 / | sort -hr
参数说明:
--max-depth=1
:仅显示当前目录及其下一级子目录的占用情况。sort -hr
:按照大小进行降序排列。查看目录的总占用空间:
du -sh /
前面的 du 命令,还是没那么好用,主要是列出来的数据太多了.
这次我用上了 ncdu 工具 。
ncdu 是一个更加用户友好的磁盘使用分析工具,支持交互式界面.
不过很多发行版没有内置,需要先安装:
sudo apt install ncdu
sudo 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/overlay2
5G /var/lib/docker/volumes
1G /var/lib/docker/containers
500M /var/lib/docker/images
基本就是 docker 的镜像、容器日志、卷之类的把硬盘吃掉了 。
找到了问题,那就好办了 。
首先把没用的 docker 容器停掉 。
然后执行一下 docker 提供的一些清理命令.
Docker 提供了 docker system prune 命令,能清理未使用的资源.
docker system prune -a
-a
:删除所有未使用的镜像(包括没有关联到容器的镜像)。如果是 /var/lib/docker/volumes 占用空间较多:
docker volume prune
如果是 /var/lib/docker/network 占用较多:
docker network prune
docker container prune
docker image prune -a
docker volume prune
如果在使用大量镜像,很多旧版本可能已经没有用了.
docker images --format "{{.Repository}}:{{.Tag}} {{.Size}}" | sort -k2 -h
docker rmi <image-id>
在分析存储空间的占用过程中,我还发现有个文件特别离谱,下面这个文件,500多个G… 。
/var/lib/docker/containers/e4b5a99b429a612885417460214ea40a6a49a3360c29180af800ff7aef4c03df/e4b5a99b429a612885417460214ea40a6a49a3360c29180af800ff7aef4c03df-json.log
来看看是哪个容器拉的屎.
日志文件的路径中包含了容器的 ID:e4b5a99b429a612885417460214ea40a6a49a3360c29180af800ff7aef4c03df 。
来找一下是哪个容器:
docker ps | grep e4b5a99b429a
在容器列表中找不到该容器,可能它已经被停止或删除了。在这种情况下,可以使用 docker inspect 检查具体信息:
docker inspect e4b5a99b429a
可以通过 tail 或 less 查看日志内容,检查是否有异常输出:
sudo tail -n 50 /var/lib/docker/containers/e4b5a99b429a612885417460214ea40a6a49a3360c29180af800ff7aef4c03df/e4b5a99b429a612885417460214ea40a6a49a3360c29180af800ff7aef4c03df-json.log
日志的具体内容我就不贴了,看起来应该没啥问题,就是运行久了,日积月累… 。
处理这个问题的方法,见下一小节.
如果 /var/lib/docker/containers 占用大量空间,可能是容器日志文件过大.
每个容器的日志存储在 /var/lib/docker/containers/<container-id>/<container-id>-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/<container-id>/<container-id>-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
可以将 /var/lib/docker 挂载到其他磁盘,从而缓解当前磁盘的存储压力。这是一个常见的做法,尤其在有多块磁盘的情况下.
/var/lib/docker
到新磁盘在迁移数据之前,需要先停止 Docker 服务:
sudo systemctl stop docker
/var/lib/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/docker
sudo systemctl start docker
运行以下命令确保 Docker 正常工作:
docker info
sudo systemctl stop docker
/var/lib/docker
到新磁盘将现有数据迁移到新磁盘挂载点。例如,新磁盘挂载在 /mnt/new-disk:
sudo mv /var/lib/docker /mnt/new-disk/docker
编辑 Docker 的配置文件(通常是 /etc/docker/daemon.json),指定新的存储路径:
sudo nano /etc/docker/daemon.json
添加或修改以下内容:
{
"data-root": "/mnt/new-disk/docker"
}
sudo systemctl start docker
再次检查 Docker 是否正常运行:
docker info | grep "Docker Root Dir"
你应该能看到新的路径(如 /mnt/new-disk/docker).
/var/lib/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.
/etc/fstab
确保开机自动挂载编辑 /etc/fstab 文件,添加一行挂载配置:
/dev/sdb1 /var/lib/docker ext4 defaults 0 2
数据迁移风险:在迁移或重建 /var/lib/docker 时,务必备份重要数据(如持久卷数据).
权限问题:确保新目录的权限与原始目录一致:
sudo chown -R root:root /mnt/new-disk/docker
检查挂载点:确保新磁盘挂载成功,并设置自动挂载,避免系统重启后路径丢失.
通过以上方法,可以成功将 /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 服务:
sudo systemctl start docker
在这次 Linux 服务器硬盘空间消失问题的排查过程中,我经历了一次完整的存储分析和优化实战.
du
和 ncdu
等工具,快速定位占用空间较大的目录。/var/lib/docker
目录占用了大量存储空间。docker inspect
和 docker logs
,进一步分析日志内容。truncate
命令立即释放空间。daemon.json
)限制了日志文件的大小,避免类似问题再次发生。docker system prune
清理了无用资源,并规划了日志管理策略。这次问题的解决让我深刻体会到以下几点:
du
、ncdu
和 Docker 命令等工具在排查问题中大大提升了效率。这次实践不仅解决了磁盘空间问题,也让我对 Linux 系统管理和 Docker 的运维有了更深的理解。在未来的运维工作中,我将更加注重系统的监控与优化,提前预防类似问题的发生.
最后此篇关于硬盘空间消失之谜:Linux服务器存储排查与优化全过程的文章就讲到这里了,如果你想了解更多关于硬盘空间消失之谜:Linux服务器存储排查与优化全过程的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
我正在运行一个辅助角色,并检查 Azure 上托管的存储中是否存在数据。当我将连接字符串用于经典类型的存储时,我的代码可以正常工作,但是当我连接到 V2 Azure 存储时,它会抛出此异常。 “远程服
在我的应用程序的主页上,我正在进行 AJAX 调用以获取应用程序各个部分所需的大量数据。该调用如下所示: var url = "/Taxonomy/GetTaxonomyList/" $.getJSO
大家好,我正在尝试将我的商店导入我的 Vuex Route-Gard。 路由器/auth-guard.js import {store} from '../store' export default
我正在使用 C# 控制台应用程序 (.NET Core 3.1) 从 Azure Blob 存储读取大量图像文件并生成这些图像的缩略图。新图像将保存回 Azure,并将 Blob ID 存储在我们的数
我想将 Mlflow 设置为具有以下组件: 后端存储(本地):在本地使用 SQLite 数据库存储 Mlflow 实体(run_id、params、metrics...) 工件存储(远程):使用 Az
我正在使用 C# 控制台应用程序 (.NET Core 3.1) 从 Azure Blob 存储读取大量图像文件并生成这些图像的缩略图。新图像将保存回 Azure,并将 Blob ID 存储在我们的数
我想将 Mlflow 设置为具有以下组件: 后端存储(本地):在本地使用 SQLite 数据库存储 Mlflow 实体(run_id、params、metrics...) 工件存储(远程):使用 Az
我的 Windows 计算机上的本地文件夹中有一些图像。我想将所有图像上传到同一容器中的同一 blob。 我知道如何使用 Azure Storage SDKs 上传单个文件BlockBlobServi
我尝试发出 GET 请求来获取我的 Azure Blob 存储帐户的帐户详细信息,但每次都显示身份验证失败。谁能判断形成的 header 或签名字符串是否正确或是否存在其他问题? 代码如下: cons
这是用于编写 JSON 的 NeutralinoJS 存储 API。是否可以更新 JSON 文件(推送数据),而不仅仅是用新的 JS 对象覆盖数据。怎么做到的??? // Javascript
我有一个并行阶段设置,想知道是否可以在嵌套阶段之前运行脚本,所以像这样: stage('E2E-PR-CYPRESS') { when { allOf {
我想从命令行而不是从GUI列出VirtualBox VM的详细信息。我对存储细节特别感兴趣。 当我在GUI中单击VM时,可以看到包括存储部分在内的详细信息: 但是到目前为止,我还没有找到通过命令行执行
我有大约 3500 个防洪设施,我想将它们表示为一个网络来确定流动路径(本质上是一个有向图)。我目前正在使用 SqlServer 和 CTE 来递归检查所有节点及其上游组件,只要上游路径没有 fork
谁能告诉我 jquery data() 在哪里存储数据以及何时删除以及如何删除? 如果我用它来存储ajax调用结果,会有性能问题吗? 例如: $("body").data("test", { myDa
有人可以建议如何为 Firebase 存储中的文件设置备份。我能够备份数据库,但不确定如何为 firebase 存储中的文件(我有图像)设置定期备份。 最佳答案 如何进行 Firebase 存储的本地
我最近开始使用 firebase 存储和 firebase 功能。现在我一直在开发从功能到存储的文件上传。 我已经让它工作了(上传完成并且文件出现在存储部分),但是,图像永远保持这样(永远在右侧加载)
我想只允许用户将文件上传到他们自己的存储桶中,最大文件大小为 1MB,仍然允许他们删除文件。我添加了以下内容: match /myusers/{userId}/{allPaths=**} { al
使用生命周期管理策略将容器的内容从冷访问层移动到存档。我正在尝试以下策略,希望它能在一天后将该容器中的所有文件移动到存档层,但事实并非如此在职的。我设置了选择标准“一天未使用后”。 这是 json 代
对于连接到 Azure 存储端点,有 http 和 https 两个选项。 第一。 https 会带来开销,可能是 5%-10%,但我不支付同一个数据中心的费用。 第二。 http 更快,但 Auth
有人可以帮我理解这一点吗?我创建了Virtual Machine in Azure running Windows Server 2012 。我注意到 Azure 自动创建了一个存储帐户。当我进入该存
我是一名优秀的程序员,十分优秀!