GitLab跨版本升级并迁移到Docker环境

  GitLab 是一款开源的软件项目管理和代码托管程序,通过搭建该代码托管服务器可实现私有化软件项目和代码托管,开发人员可远程访问进行wiki和在线代码编辑,issue 跟踪、CI / CD等功能。被互联网企业、软件开发公司所广泛使用。我司当然也不例外。由于我司的 GitLab 年代久远,一直没人去动它,最近频繁宕掉,加上上月底爆出高危漏洞,因此打算对其做一次升级与迁移,同时改成 Docker 方式来部署。

前言

  GitLab 小版本的升级可以直接升级(当然别忘了做好备份),大版本的升级需要逐版本升级。所谓小版本升级,即 9.2.3 到 9.5.10 这种都算小版本升级,只需要在做好备份的情况下直接升级即可。大版本升级需要梯度升级,即先升级到当前大版本的最新版本,再升级到下个大版本的最旧版本,最后才能升级到下个大版本的最新版本。
  如果是通过 rpm 包等方式直接安装到系统中的,迁移到 docker-compose 方式会给升级省去许多麻烦,日后维护也会方便许多。

备份

  GitLab 的备份很简单,直接通过命令行执行:

1
/opt/gitlab/bin/gitlab-rake gitlab:backup:creat  

  之后会生成文件名类似 1617738463_2021_04_07_9.5.3_gitlab_backup.tar 的备份文件到 /var/opt/gitlab/backups 路径下(这个路径也可以在 /etc/gitlab/gitlab.rb 中的 gitlab_rails['backup_path'] = "/var/opt/gitlab/backups" 字段定义,修改后需要重启 GitLib 生效)
同时备份如下文件:

1
2
/etc/gitlab/gitlab.rb  
/etc/gitlab/gitlab-secrets.json

将上述文件传到新机器上即可。

迁移

  新机器上需要安装 docker 以及 docker-compose,这个过程不是重点,就省略了。(CentOS 7安装Docker)

1
2
cd ~ 
mkdir gitlab

  新建如下配置文件,其中 GITLAB_OMNIBUS_CONFIG 部分根据之前 /etc/gitlab/gitlab.rb 的实际配置来修改。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
version: '2'
services:
gitlab:
image: 'gitlab/gitlab-ce:9.5.3-ce.0' # 切记!!这里务必选择旧版本相同的版本,否则会出现无法恢复备份的情况
container_name: "gitlab"
restart: unless-stopped
privileged: true
hostname: 'docker-gitlab-01'
environment:
TZ: 'Asia/Shanghai'
# 这里的配置其实就是 /etc/gitlab/gitlab.rb 中的配置,按自己的实际需求增减
GITLAB_OMNIBUS_CONFIG: |
external_url 'http://www.iots.vip'
gitlab_rails['time_zone'] = 'Asia/Shanghai'
gitlab_rails['smtp_enable'] = true
gitlab_rails['smtp_address'] = "www.iots.vip"
gitlab_rails['smtp_port'] = 465
gitlab_rails['smtp_user_name'] = "a@qq.com"
gitlab_rails['smtp_password'] = "password"
gitlab_rails['smtp_domain'] = "www.iots.vip"
gitlab_rails['smtp_authentication'] = "login"
gitlab_rails['smtp_enable_starttls_auto'] = true
gitlab_rails['smtp_tls'] = true
gitlab_rails['gitlab_email_from'] = 'a@qq.com'
gitlab_rails['gitlab_shell_ssh_port'] = 10086
gitlab_rails['git_max_size'] = 20971520
gitlab_rails['git_timeout'] = 10
gitlab_rails['gitlab_shell_git_timeout'] = 800

# 以下三行当需要用外部nginx做代理转发的时候启用
# 其中 IP 为nginx代理所在的IP,可以为网段
nginx['real_ip_trusted_addresses'] = ['192.168.101.0/24', '192.168.202.0/24']
nginx['real_ip_header'] = 'X-Forwarded-For'
nginx['real_ip_recursive'] = 'on'

ports:
- '80:80'
- '443:443'
- '10086:10086' # 这里修改为上面配置的 gitlab_rails['gitlab_shell_ssh_port']
volumes:
- /opt/gitlab/config:/etc/gitlab
- /opt/gitlab/data:/var/opt/gitlab
- /opt/gitlab/logs:/var/log/gitlab
-

确认配置无误之后,我们启动这个容器组:

1
2
3
cd ~/gitlab
docker-compose up -d # 以daemon模式启动docker-compose
docker-compose logs -f -t --tail 100 # 动态查看容器日志的最后100行

  当容器完成初始化启动完成后,我们通过 80 端口能正常访问 GitLab 后,开始恢复我们之前生成的备份。

1
2
3
4
5
6
7
8
9
10
11
12
# 将前面的备份文件 1617738463_2021_04_07_9.5.3_gitlab_backup.tar 复制到 /opt/gitlab/data/backups 下
mv /tmp/1617738463_2021_04_07_9.5.3_gitlab_backup.tar /opt/gitlab/data/backups

# 进入容器
docker-compose exec gitlab /bin/bash

gitlab-ctl stop unicorn # 停止相关的服务
gitlab-ctl stop sidekiq
cd /var/opt/gitlab/backups
ls # 可以看到 1617738463_2021_04_07_9.5.3_gitlab_backup.tar 备份文件
gitlab-rake gitlab:backup:restore BACKUP=1617738463_2021_04_07_9.5.3 # 这里注意,不是完整的备份文件名,而是文件名去掉_gitlab_backup.tar后缀
# 之后便会开始恢复备份,过程中会需要输入两次yes

  这里插一句: 如果这里你没有注意到我前面提示的用相同版本容器镜像,而是使用了与备份包不同版本的容器镜像,在恢复备份时则会出现如下错误:

1
2
3
4
5
6
root@docker-gitlab-01:/var/opt/gitlab/backups# gitlab-rake gitlab:backup:restore BACKUP=1617911251_2021_04_09_9.5.3
Unpacking backup ... done
GitLab version mismatch:
Your current GitLab version (13.7.4) differs from the GitLab version in the backup!
Please switch to the following version and try again:
version: 9.5.3

这个时候只能删除 /opt/gitlab 下的所有文件,重新启动与备份包相同版本的容器。

恢复备份完成后,我们需要重启一下容器。

1
2
3
4
5
# 这时候你应该还在容器中,需要退回到宿主机:
exit

# 重启
docker-compose restart

  重启完成后,需要通过网页查看我们的仓库数据是否正常,仓库推拉、邮件等功能是否正常。 确认一切正常后,就开始升级了。

升级

  GitLab 的升级,遵循小版本直接升,大版本需要升级到上一个大版本的最新版本,才能升级,否则会出错。 我当前的版本为 9.5.3,最新版本为 13.10.2,则升级路线应该为:

1
2
# 具体哪个版本是大版本的最新版本,一种方式是直接通过 dockerhub 中的 TAG 来查看,另外一种是直接通过官网的 release log 来查看。  
9.5.3 -> 9.5.10 -> 10.0.3 -> 10.8.7 -> 11.11.8 -> 12.0.12 -> 12.10.14 -> 13.0.14 -> 13.10.2

Docker 化的 GitLab 升级过程相对来说比较简单,我们仅仅需要做的就是,停止容器,然后修改 docker-compose.yml 中的 image 为新版本即可。

1
2
3
4
5
6
7
8
9
10
11
# 停止
docker-compose stop

# 我当前的版本为 9.5.3,下个版本应该先升级到 9.5.10
# 则修改 docker-compose.yml 中的 images 为 9.5.10

# 重新启动一下
docker-compose up -d

# 看看容器日志有没有什么异常或报错
docker-compose logs -f -t --tail 100

等待升级完成即可开始验证功能。

依此类推,按照升级路线逐级升级即可。

其他配置

nginx代理转发

由于我们的 GitLab 所在的服务器是没有分配公网 IP 的,所有需要利用 NGINX 做代理转发,配置文件中需要配置如下的 location

1
2
3
4
5
6
7
8
9
10
11
12
13
location / {
# docker gitlab 所在的IP
proxy_pass http://1.1.1.1:80;

# 由于部分仓库有比较大的文件,这里需要配置,否则在推拉大文件时会出错
client_max_body_size 1024m;

# 让后端获取真实的client IP
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}

gitlab-runner

升级完 GitLab 后,旧的版本的 runner 会无法连接,需要更新 runner 重新 register:

1
2
3
4
5
6
7
8
9
10
curl -L https://packages.gitlab.com/install/repositories/runner/gitlab-runner/script.rpm.sh | sudo bash

yum install gitlab-runner -y

gitlab-runner register
# 输入 gitlab 服务器地址
# 输入 token,可在 gitlab 管理后台获取
# 输入该 runner 的描述,例如 runner-ali-npm-build
# 输入该 runner 的 tag,例如 npm 或 backend
# 输入该 runner 的 executor,例如 shell

gitlab-shell hooks

公司有利用 gitlab-shell hooks 做内部 commit message 校验的,也需要将之前的 hooks 脚本手动迁移过来。
docker-compose.yml 文件的 volumes 字段添加如下映射:

1
2
# 当配置了hooks的时候,需要映射出来,否则不用:
- /opt/data/gitlab/hooks:/opt/gitlab/embedded/service/gitlab-shell/hooks

再将旧的文件全部迁移过来即可。

gitlab webhook

升级迁移后,发现与 Jenkins 集成时使用的 webhook 无法使用,提示 Url is blocked: Requests to the local network are not allowed,这种情况需要使用管理员账号前往设置中:
依次进入: Admin area => Settings => Network
展开 Outbound requests,勾选 Allow requests to the local network from web hooks and services 即可。

定时备份

docker-compose 跑的 GitLab 如果需要用 crontab 方式来进行备份的话,docker-compose exec 后面记得加 -T

1
2
# -T 为不分配 TTY,如果不加的话,利用 crontab 来运行会报: the input device is not a TTY 
docker-compose exec -T gitlab gitlab-backup create