手把手带你排查遇到服务器无可用磁盘空间问题与处理
背景
在端午期间,突然收到消息说,sentry 服务无法访问了,请求总是出现 502 页面响应。揣着忐忑不安的心情 ♥ 开始了排查之旅。
查因
- 从哪下手?
服务器的内存满了吗?
a. 如果没有内存了,那么服务器也登录不上。
b. 如果没有内存,那么访问也将不会出现 502 响应,而是打不开服务了。
c. 登录服务器后执行free -h
查看,服务器的内存还有一定的剩余,好的👌,这个确认安全。为啥会突然停止运行呢?
sentry 服务是采用官方提供的搭建方案中的 docker 方式作为服务运行于服务器上,前几天都还好好的。
- 先检查一下服务器的相关 sentry 服务是否正常运行。
docker ps -a
得到如下结果,sentry 相关的服务中,有 3 个相关容器处于 Restaring 状态。
- 服务为啥无法启动,为啥一直处于 Restaring 状态?
通过对容器的进行日志的逐个查看,初探端倪
docker-compose logs -tail 200 postgres
: No space left on device,重启服务时,因无可用剩余空间,所以无法启动了。
- 服务器真的没有可用剩余空间了吗?
通过运行命令 df -h /
,得知服务器的磁盘空间使用接近 100%,真的没有空间了。
知果
通过一番排查,我们知道了 sentry 服务无法运行的原因了。那接下来该对服务器磁盘进行清理了。
- docker 服务是否有限制日志输出选项?
通过 cat /etc/docker/daemon.json
查看服务器启动配置得知,日志驱动使用的是 json-file,日志配置选项为每个容器保留 3份日志文件,每份文件最大大小为 100M。
{
"registry-mirrors": ["https://oifw9ovt.mirror.aliyuncs.com"],
"exec-opts": ["native.cgroupdriver=systemd"],
"log-driver": "json-file",
"log-opts": {"max-size": "50m", "max-file": "3"}
}
- sentry 服务是否有配置日志输出选项?
通过 cat /path/to/onpremise/docker-compose.yml
查看 sentry 服务的 docker-compose 编排文件,可以得知与 docker 服务一致,日志驱动使用的是 json-file,日志配置选项为每个容器保留 3份日志文件,每份文件最大大小为 100M。
- 是 docker 相关的服务输出的日志太多吗?
a. 是 sentry 运行时间过长,报错太多导致数据库中的数据过多吗?
通过一番搜索,找到了文章 Sentry 服务磁盘占满 清除postgresql方法
对文章的阅读后发现,sentry 已无法运行,不能通过手动清理日志来减少磁盘空间,不过关于自动清理超过七天的记录还是有点用处,遂参考文章加上了相关配置。
b. 配置 docker 服务器日志轮转
又一番搜索后,似乎看到了希望,Kubernetes之容器数据写满磁盘解决方法
参考文章中的具体优化方法,检查 docker 服务,已有相关配置。
- 到底是什么占用了服务器 40G 的磁盘空间?
a. 文件系统磁盘被谁使用了?
通过 df -lh | sort -h
查看磁盘当前占用情况排序
得知 /var/lib/docker/aufs/mnt/
占用了大多数的空间。
b. 磁盘中哪些目录占用了较大的空间?
通过 du -hd 2 / | sort -hr
查看磁盘使用情况
得知 /var 目录占用了 23G 的磁盘空间。
c. 对每个空间占用大于 1G 的目录进行子一级目录的目录使用情况统计
得知 /var/log 目录日志使用了 17G 的空间,单单事件记录监控程序日志就达到了 16G 的空间。
- 开始清理日志吧
因 log 目录下部分日志有点特殊,不是存文本文件,故参考 linux log 及如何清除log,对日志做了一些清理:
a. 删除 /var/log 下的日志压缩包rm -rf /var/log/*.gz
b. 删除 /var/log 轮转日志rm -rf /var/log/*.1
c. 清空内核日志cat /dev/null > /var/log/dmesg
d. 清空 Linux 操作系统常见的系统和服务错误信息cat /dev/null > /var/log/messages
e. 清空事件记录监控程序日志cat /dev/null > /var/log/syslog
f. 清理 journal 日志
# 查看磁盘占用
du -hd 2 /var/log | sort -hr
journalctl --disk-usage
# 清理日志
journalctl --vacuum-size=10M
# 只保留一周的日志
journalctl --vacuum-time=1w
# 再次查看磁盘占用
journalctl --disk-usage
du -hd 2 /var/log | sort -hr
g. 删除 24小时前下载的镜像docker image prune -a --filter "until=24h"
末:单服务器释放了 17G 的磁盘空间
最后,一番操作后,单服务器释放了 17G 的磁盘空间。
总结
- 操作需谨慎
- 多多利用排序,能便于排查问题。
- 提早做好相应工作,能减少临时处理问题的可能性
给大家几个方便使用的小命令:
# 查看服务器内存使用情况
free -h
# 查看磁盘当前占用情况
df -h /
# 查看磁盘当前占用情况排序
df -lh | sort -h
# 查看磁盘使用统计
du -hd 2 / | sort -hr
composer clearcache
yarn clean cache --all
npm clean cahce --force
snap list --all | awk '/disabled/{print $1, $3}' |
while read snapname revision; do
snap remove "$snapname" --revision="$revision"
done