最近查看公司使用的gitlab版本,是gitlab-ee:12.1.0-ee.0
,而官方最新的稳定版本已经到了gitlb-ee:13.4.0-ee.0
。加上公司做机器机房迁移,所以趁这个机会迁移gitlab
机器,并且把gitlab
从12.1
升级到13.4
。
本次目标
使用docker
把gitlab
迁移到另外一台机器,从gitlab/gitlab-ee:12.1.0-ee.0
升级到gitlab/gitlab-ee:13.4.0-ee.0
这里把老机器称为gitlab_old
把新机器称为gitlab_new
方案选择
在网上找的资料很多,有通过docker直接升级的,有通过deb包手动升级的,各种方式比较乱。
于是我决定以官方的升级方式为准,在gitlab官方文档找到以下文档:
docker安装升级文档:https://docs.gitlab.com/omnibus/docker/README.html
gitlab版本升级建议:https://docs.gitlab.com/ee/policy/maintenance.html#upgrading-major-versions
查阅文档大致可以知道,gitlab每个月22号就会发布一个小版本(Minor版本),每年5月22号会发布一个大版本(Major版本)。当出现跨版本升级,并不能一步到位,直接升级,需要先升级到对应最近的小版本,以及一些必须升级的版本,最终才能逐步升级到目标版本。
例如我这里是12.1.0
升级到 13.4.0
,经过我的查阅和测试,我最终的升级路线是(后面解释为什么需要按路线升级):
12.1.0 -> 12.10.14 -> 13.0.12 -> 13.1.0 -> 13.2.0 -> 13.3.1 -> 13.4.0
主要步骤
- 1.从gitlab_old中备份出全量数据(开始备份的时候就通知开发人员gitlab不可用了,避免数据不一致)
- 2.在gitlab_new上拉一个新的同版本的gitlab,导入数据
- 3.基于gitlab_new上的同版本gitlab做升级,并且备份每一个版本
- 4.测试
接下来就一步一步来完成
1.备份全量的gitlab数据
1.备份数据,登陆gitlab_old机器
docker exec -it gitlab_12.1.0-ee.0 /bin/bash
cd /var/opt/gitlab/backups
# 执行备份命令
gitlab-rake gitlab:backup:create
可能报错ArgumentError: could not find a temporary directory
解决:给/var/opt/gitlab/backups/tmp赋权限
cd /var/opt/gitlab/backups
chmod +t ./tmp
然后再执行
gitlab-rake gitalb:backup:create
导出的包在/data/gitlab/data/backup下面
2.把导出的包传到gitlab_new
在容器内/var/opt/gitlab/backups
下面会有个这样的包1601429376_2020_09_30_12.1.0-ee_gitlab_backup.tar
,我对应容器外的目录是,/data/gitlab/data/backup
。需要把这个包传到gitlab_new服务器,这个包很大,我的有20多g,如果通过scp
传包,那估计传到好几个小时不一定搞得定。所以这里选择使用lz4传包。21个g我这里大概需要20分钟。
在gitlab_old上
#切换到目录
cd /data/gitlab/data/backup
#执行传包命令
tar -c 1601189945_2020_09_27_12.1.0-ee_gitlab_backup.tar |pv|lz4 -B4|ssh -p10086 -c arcfour128 -o"MACs umac-64@openssh.com" 127.0.0.1 "lz4 -d |tar -xC /data"
# 127.0.0.1应该改成gitlab_new的ip
如果上面命令报错,可能是以下几个原因:
1.没安装pv命令
解决:yum install -y pv
2.提示Cipher错误,因为ssh去掉了一些不安全的加密协议,例如上面用到的arcfour128
解决:
vim /etc/ssh/sshd_config
在末尾新增一行:Ciphers 3des-cbc,aes128-cbc,aes192-cbc,aes256-cbc,aes128-ctr,aes192-ctr,aes256-ctr,aes128-gcm@openssh.com,aes256-gcm@openssh.com,arcfour,arcfour128,arcfour256,blowfish-cbc,cast128-cbc,chacha20-poly1305@openssh.com
重启sshd:service sshd restart
两边都加上,然后再运行传包命令,下图就是正在传包的样子。
2.拉取一个新的同版本的gitlab开始数据迁移
在gitlab_new机器上操作
1.首先拉取升级过程中每个需要的版本的gitlab镜像
docker pull gitlab/gitlab-ee:12.1.0-ee.0
docker pull gitlab/gitlab-ee:12.10.14-ee.0
docker pull gitlab/gitlab-ee:13.0.12-ee.0
docker pull gitlab/gitlab-ee:13.1.0-ee.0
docker pull gitlab/gitlab-ee:13.2.0-ee.0
docker pull gitlab/gitlab-ee:13.3.1-ee.0
docker pull gitlab/gitlab-ee:13.4.0-ee.0
由于之前的版本是12.1.0-ee.0
,数据导入只能是同版本的,所以首先得在新机器上拉一个12.1.0-ee.0
的gitlab
2.搭建同版本的gitlab
1.创建目录
mkdir -p /data/gitlab-12.1.0.ee/data
mkdir -p /data/gitlab-12.1.0.ee/config
mkdir -p /data/gitlab-12.1.0.ee/logs
2.启动脚本
docker run -d --publish 443:443 --publish 80:80 --publish 22:22 --name gitlab_12.1.0-ee.0 \
--volume /data/gitlab-12.1.0.ee/config:/etc/gitlab \
--volume /data/gitlab-12.1.0.ee/logs:/var/log/gitlab \
--volume /data/gitlab-12.1.0.ee/data:/var/opt/gitlab \
gitlab/gitlab-ee:12.1.0-ee.0
3.查看日志
docker logs -f gitlab_12.1.0-ee.0
日志正常不报错,就访问http://ip,说明搭建成功
3.数据和配置恢复
把之前从gitlab_old传过来的包移动到gitlab备份目录
mv /data/1601429376_2020_09_30_12.1.0-ee_gitlab_backup.tar /data/gitlab-12.1.0.ee/data/backups/
进入容器,执行命令
docker exec -it gitlab_12.1.0-ee.0 /bin/bash
cd /var/opt/gitlab/backups/ --这里有备份文件
停应用
gitlab-ctl stop unicorn
gitlab-ctl stop sidekiq
开始恢复
gitlab-rake gitlab:backup:restore BACKUP=1601429376_2020_09_30_12.1.0-ee
这里会卡很久,要有点耐心,需要确认的地方全部选yes,是备份ssh key之类的
如果报错没权限,就执行 chmod 777 1601429376_2020_09_30_12.1.0-ee_gitlab_backup.tar,再执行备份命令
gitlab-ctl restart
gitlab-rake gitlab:check SANITIZE=true
退出容器,重启容器,观察日志
docker restart gitlab_12.1.0-ee.0
docker logs -f gitlab_12.1.0-ee.0
此时就能正常访问同版本的gitlab了,但是还有两个问题
- 第一个是进入项目setting -> cicd 页面报错500
- 第二个是目前还是ip访问,但是之前是https域名访问
提前更换之前gitlab域名的解析,从gitlab_old解析到gitlab_new。
解决:由于通过tar包只能还原数据文件,配置都不能还原,所以这里首先需要去gitlab_old去拷贝gitlab.rb,gitlab-secrets.json这两个文件以及ssl这个放https整数的文件夹。
备份gitlab_new机器上的文件,然后把这三个放在对应的位置。然后在gitlab_new上重新加载配置:
docker exec -it gitlab_12.1.0-ee.0 /bin/bash
gitlab-ctl reconfigure
gitlab-ctl restart
退出容器,重启gitlab
docker restart gitlab_12.1.0-ee.0
此时就能通过之前gitlab的域名去访问新机器搭建的gitlab了。完成了gitlab的机器迁移,然后就去在gitlab_new上进行gitlab升级。
gitlan升级
基于gitlab_new上的同版本gitlab做升级,并且备份每一个版本。我这里演示从12.1.0-ee.0升级到12.10.14-ee.0
首先停掉12.1.0
docker stop gitlab_12.1.0-ee.0
然后基于之前挂载的目录,使用12.10.14-ee.0的image去拉一个新的容器。注意容器名称最好带上版本号,易于区分。
docker run -d --publish 443:443 --publish 80:80 --publish 22:22 --name gitlab_12.10.14-ee.0 \
--volume /data/gitlab-12.1.0.ee/config:/etc/gitlab \
--volume /data/gitlab-12.1.0.ee/logs:/var/log/gitlab \
--volume /data/gitlab-12.1.0.ee/data:/var/opt/gitlab \
gitlab/gitlab-ee:12.10.14-ee.0
这一步可以理解为gitlab在自动洗数据,由于之前数据和image的版本都是12.1.0,然后使用12.10.14的image去拉起,就会把数据洗成12.10.14版本的。如果说,数据是12.1.0版本,你用13.0.0的image去拉起,那么就会报错:数据和版本不兼容。所以需要逐步在版本兼容的数据和镜像之间去逐步完成数据的版本升级,这也是为什么,从12.1.0升级到13.4.0需要经历这么多image。
知道了这一点以后,就可以重复上面的操作,按最开始的路径,去升级到13.4.0。这里有一个建议,就是每个版本都保留一个备份。如图,保存每个数据版本,然后对应image版本拉取一个容器,这样就能在升级过程中随时去切换,每个版本都是能独立启动的。
这里注意:
当我们备份数据的数据,使用cp -r -p
例如我这个目录gitlab-12.1.0.ee,用12.10.14的景象拉过,我就这样备份:
cp -r -p gitlab-12.1.0.ee gitlab-12.10.14.ee
-p 命令能够连带文件夹权限一起复制,否则,你复制后拉取容器的时候,就会提示权限错误。
然后我重复以上操作,最终就把gitlab从12.10.14升级到13.4.0
测试
我主要测试了以下几个方面
- 1.检查之前项目是否都还在
- 2.拉代码,推代码
- 3.ci-cd是否还能正常执行
- 4.以前文档和wiki内容是否还有
我这里更换了机器,所以域名对应的ip更改了,这里有一个问题,就是pull
代码会报错,是因为我们的域名更换了网址,然后在我们本地know_hosts
中有之前ip的缓存,所以key识别失败。
解决:
cat ~/.ssh/known_hosts
把之前域名对应ip的缓存删掉
我这里是mac系统,如果是windows系统,就去找对应known_hosts文件的位置
总结
- 升级方案主要还是得参考官网
- 注意备份每个版本,可能升级到中间版本会出现问题,这样可以从上个版本着手解决,不然只能从头开始。
- 整个升级过程,应该让使用gitlab的人没什么感知,我这里由于换了机器,所以需要让其他开发删除一下本地known_hosts,其他就和之前使用一样