1. 问题现场还原与快速诊断
那天下午3点,我正在处理一个常规的GitLab合并请求,突然收到监控系统发来的警报——服务器磁盘使用率达到100%!整个GitLab界面开始变得异常缓慢,部分用户反馈无法提交代码。作为运维人员,这种红色警报就是最高级别的战斗号角。
第一步必须确认问题范围:通过SSH连入服务器执行df -h命令,发现是/var分区被占满,这正是GitLab默认安装的数据存储位置。此时任何需要写入磁盘的操作(包括新代码提交、CI/CD流水线运行)都会失败。
快速排查命令组合(建议收藏):
bash复制# 查看磁盘整体使用情况
df -hT
# 定位大文件目录(按大小降序)
du -sh /* 2>/dev/null | sort -rh | head -10
# 查找大于100MB的文件(可根据实际情况调整大小)
find /var -type f -size +100M -exec ls -lh {} + | sort -k5 -rh
关键提示:在磁盘爆满情况下,某些命令可能因无法创建临时文件而报错。此时添加
2>/dev/null屏蔽错误输出,或使用/bin/ls替代ls这类基础命令更可靠。
2. 罪魁祸首定位与清理策略
通过上述命令组合,很快在/var/opt/gitlab目录下发现了异常——gitlab-rails/uploads文件夹体积达到惊人的120GB!进一步分析发现是用户上传的附件(主要是CI构建产物和代码片段)没有自动清理。
GitLab磁盘占用四大常见原因(按出现频率排序):
- 失控的CI/CD产物(占70%案例)
- 容器镜像仓库膨胀(Docker Registry数据)
- PostgreSQL数据库WAL日志堆积
- 老版本仓库的残留数据
针对性清理方案:
2.1 CI产物清理(最有效手段)
bash复制# 进入GitLab管理命令行
gitlab-rails console
# 执行清理命令(保留最近5天的产物)
Projects::BuildArtifacts::ExpireService.new.execute
2.2 Docker镜像仓库瘦身
bash复制# 查看Registry存储用量
du -sh /var/opt/gitlab/gitlab-rails/shared/registry
# 执行垃圾回收(需停止服务)
gitlab-ctl registry-garbage-collect
2.3 数据库维护
sql复制-- 进入PostgreSQL命令行
gitlab-psql
-- 清理过期WAL日志
VACUUM FULL;
血泪教训:曾经有团队在业务高峰时段执行
VACUUM FULL导致数据库锁死。建议在低峰期操作,或改用VACUUM (VERBOSE, ANALYZE)轻量级维护。
3. 紧急腾挪空间技巧
当磁盘完全写满时,连删除操作都可能失败(需要空间记录文件系统变更)。这时候需要一些特殊技巧:
技巧1:创建临时空文件后删除
bash复制# 在剩余空间较多的分区操作
dd if=/dev/zero of=/tmp/cleaner bs=1M count=1024
rm -f /tmp/cleaner
技巧2:优先清理日志文件
bash复制# 清空GitLab各组件日志(保留最新)
echo "" > /var/log/gitlab/gitlab-rails/production.log
技巧3:扩展临时文件系统
bash复制# 将/tmp挂载到内存中(临时方案)
mount -t tmpfs -o size=1G tmpfs /tmp
4. 长效预防机制建设
经历过这次惊险救援后,我建立了三层防御体系:
4.1 监控预警规则
yaml复制# Prometheus告警规则示例
- alert: GitLabDiskCritical
expr: 100 - (node_filesystem_avail_bytes{mountpoint="/var"} * 100 / node_filesystem_size_bytes{mountpoint="/var"}) > 90
for: 5m
labels:
severity: critical
annotations:
summary: "GitLab磁盘即将爆满 ({{ $value }}%)"
4.2 自动化清理策略
ruby复制# GitLab配置示例(/etc/gitlab/gitlab.rb)
gitlab_rails['manage_backup_path'] = true
gitlab_rails['backup_keep_time'] = 604800 # 保留7天
registry['storage']['delete'] = { 'enabled' => true }
registry['storage']['maintenance'] = { 'readonly' => { 'enabled' => false } }
4.3 存储架构优化
- 将
gitlab-data挂载到独立磁盘 - CI构建产物使用S3兼容存储
- PostgreSQL数据与日志分离存储
5. 故障恢复后的必要检查
清理完成后,必须验证核心功能:
- 代码推送/拉取测试
- CI流水线触发测试
- 数据库完整性检查
bash复制gitlab-rake gitlab:check
特别容易遗漏的点:
- 检查Sidekiq队列是否积压
- 验证Webhook是否正常触发
- 确认容器镜像推送/拉取功能
那次事故后,我们团队制定了《GitLab存储管理SOP》,规定每周五下午执行预防性维护。三个月过去了,磁盘使用率始终稳定在65%以下。记住:好的运维不是救火队员,而是防火专家。