通用技术 Gitlab 故障排查和数据转移

扫地僧 · 2019年10月30日 · 最后由 chris486 回复于 2019年12月26日 · 2583 次阅读

上周 ,访问 gitlab 页面突然出现 500 的错误,之后又拖垮了服务器资源。排查过程中遇到了难题,以至于采取了数据迁移的方案。在迁移过程中,因为 GitLab 自身存在的缺陷,又踩了一些坑。幸运的是,代码库最终得以保存,没有造成损失。

1. 故障排查

先介绍下 gitlab 套件组成,主要包含 nginx、postgresql、redis 等组件,任何一个进程异常都可能导致服务器内部错误。

[root@localhost gitlab]# gitlab-ctl status
run: gitlab-workhorse: (pid 32031) 594825s; run: log: (pid 32592) 597824s
run: logrotate: (pid 21999) 820s; run: log: (pid 32586) 597824s
run: nginx: (pid 32041) 594824s; run: log: (pid 32580) 597824s
run: postgresql: (pid 32046) 594824s; run: log: (pid 32582) 597824s
run: redis: (pid 32054) 594823s; run: log: (pid 32590) 597824s
run: sidekiq: (pid 1494) 442433s; run: log: (pid 32588) 597824s
run: unicorn: (pid 32062) 594822s; run: log: (pid 32584) 597824s

1.1 查看哪个组件进程异常

通过 ps 发现 redis-server 进程异常,出现了 N 多个(正常情况是 1 个)。

[root@localhost ~]# ps -ef|grep gitlab
root     13294  7787  0 10:30 ?        00:00:00 svlogd -tt /var/log/gitlab/redis
gitlab-+ 15230     1  0 10:36 ?        00:00:00 /opt/gitlab/embedded/bin/redis-server 127.0.0.1:0
gitlab-+ 15239     1  0 10:36 ?        00:00:00 /opt/gitlab/embedded/bin/redis-server 127.0.0.1:0
gitlab-+ 15243     1  0 10:36 ?        00:00:00 /opt/gitlab/embedded/bin/redis-server 127.0.0.1:0
gitlab-+ 15247     1  0 10:37 ?        00:00:00 /opt/gitlab/embedded/bin/redis-server 127.0.0.1:0
gitlab-+ 15251     1  0 10:37 ?        00:00:00 /opt/gitlab/embedded/bin/redis-server 127.0.0.1:0
gitlab-+ 15255     1  0 10:37 ?        00:00:00 /opt/gitlab/embedded/bin/redis-server 127.0.0.1:0

1.2 尝试恢复

尝试停止服务,发现无法正常关闭,redis-server 进程反而又增加了。

# 停止GitLab所有组件
sudo gitlab-ctl stop

尝试强制杀死和 gitlab 相关的所有进程,执行命令后虽然短暂性杀完,但马上又神奇的复活并快乐的增长。

ps -A|grep gitlab|grep -v grep|awk 'NR=1 {print $1}'|xargs kill -9

通过现象判断,怀疑有守护进程在运行,经调查印证了我的想法。然后就先杀守护进程,再强杀相关的所有进程,接着又观察了一段时间,终于确认已成功关闭所有 gitlab 服务。

# 守护进程
root     32572     1  0 Oct24 ?        00:00:03 runsvdir -P /opt/gitlab/service log: ....

异常进程都清理干净了,尝试正常启动服务,令人绝望的是 redis-server 进程还是会不停增长。

# 启动服务
sudo gitlab-ctl start
gitlab-+ 15230     1  0 10:36 ?        00:00:00 /opt/gitlab/embedded/bin/redis-server 127.0.0.1:0
gitlab-+ 15239     1  0 10:36 ?        00:00:00 /opt/gitlab/embedded/bin/redis-server 127.0.0.1:0
gitlab-+ 15243     1  0 10:36 ?        00:00:00 /opt/gitlab/embedded/bin/redis-server 127.0.0.1:0
gitlab-+ 15247     1  0 10:37 ?        00:00:00 /opt/gitlab/embedded/bin/redis-server 127.0.0.1:0
gitlab-+ 15251     1  0 10:37 ?        00:00:00 /opt/gitlab/embedded/bin/redis-server 127.0.0.1:0
gitlab-+ 15255     1  0 10:37 ?        00:00:00 /opt/gitlab/embedded/bin/redis-server 127.0.0.1:0
gitlab-+ 15259     1  0 10:37 ?        00:00:00 /opt/gitlab/embedded/bin/redis-server 127.0.0.1:0
gitlab-+ 15263     1  0 10:37 ?        00:00:00 /opt/gitlab/embedded/bin/redis-server 127.0.0.1:0
gitlab-+ 15267     1  0 10:37 ?        00:00:00 /opt/gitlab/embedded/bin/redis-server 127.0.0.1:0

网上搜了许多资料,也问了资深运维,实在找不到原因。
个人推断,很可能是某个不经意的操作,触发了 gitlab 隐藏的缺陷,而且这个隐患很可能就藏在守护进程内部。既然无法修复,比较靠谱的方案就是数据迁移了。

2. 数据迁移

先准备好一台 Gitlab 服务器,版本跨度不要太大,尽量保持一致,因为数据库结构可能存在的差异,会导致数据导入失败。

2.1 数据备份

#全量备份
[root@localhost ~]# gitlab-rake gitlab:backup:create
#备份路径和文件
[root@localhost ~]# ls /var/opt/gitlab/backups/
1571845560_gitlab_backup.tar

2.2 备份数据和配置文件传送至新服务器

配置文件、备份的数据传送到新服务器对应的目录。
gitlab-secrets.json 文件也要替换掉目标服务器的同名文件,否则进入项目页会报 500 的错误。

scp /etc/gitlab/gitlab.rb root@hostAddr:/etc/gitlab/
scp /etc/gitlab/gitlab-secrets.json root@hostAddr:/etc/gitlab/
scp /var/opt/gitlab/backups/1571845560_gitlab_backup.tar root@hostAddr:/var/opt/gitlab/backups/

2.3 导入数据

#修改属组和属主权限
chown git.root /var/opt/gitlab/backups/ -R
#进入备份目录
cd /var/opt/gitlab/backups
#执行数据导入
#BACKUP=1571845560,这串数字是1571845560_gitlab_backup.tar的文件前缀
#导入过程中需输入几次yes,即可完成数据恢复
gitlab-rake gitlab:backup:restore BACKUP=1571845560 

2.4 修复 GitLab 数据迁移的缺陷

这个缺陷会导致进入项目页报 500 的错误。
EE 版和 CE 版修复命令不一样,我们用的是 CE 版本(可以从 rpm 包名辨别)

#EE版本执行命令
sudo gitlab-rails runner "Project.where(mirror: false).where.not(import_url: nil).each { |p| p.import_data.destroy if p.import_data }"
#CE版本执行命令
sudo gitlab-rails runner "Project.where.not(import_url: nil).each { |p| p.import_data.destroy if p.import_data }"

2.5 更新配置

因为配置文件是备份过来的,所以要更新 external_url,保存后需重载配置

[root@localhost ~]# vi /etc/gitlab/gitlab.rb
## Url on which GitLab will be reachable.
## For more details on configuring external_url see:
## https://gitlab.com/gitlab-org/omnibus-gitlab/blob/master/doc/settings/configuration.md#configuring-the-external-url-for-gitlab
external_url 'http://xx.xx.xx.xx'

#重载配置,可能时间较长,需耐心等待
[root@localhost ~]# gitlab-ctl reconfigure

2.6 重启服务

gitlab-ctl restart

至此,GitLab 迁移工作顺利完成,祝好!

如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
共收到 4 条回复 时间 点赞

这种从跟踪问题到分析到定位到解决的工作方式非常赞!

simple 回复

平时喜欢把过程经验记录下来,养成习惯了。写的比较平淡,希望能帮助到需要的人

这也是 QA 的活儿么?😂 叹服

最近我也在做 gitlab 的迁移,gitlab 是 docker 搭建的,数据迁移后,管理中心--runner 打不开,按照说明在容器内执行 gitlab-rails console production 后 执行 ApplicationSetting.current.reset_runners_registration_token! 但是 runner 依旧还是打不开,怎么整?请问有没有其他解决方案

需要 登录 后方可回复, 如果你还没有账号请点击这里 注册