GitLab 升级与迁移
GitLab 升级失败常见原因是跳过中间版本、未停 Sidekiq 或未备份 secrets。升级前必须阅读当前版本到目标版本之间的 Release Notes,确认 PostgreSQL 版本要求、废弃功能和必需迁移步骤。
必须遵循官方 Upgrade Path:不能从 14.x 直接跳到 17.x,需按 GitLab 升级路径工具 逐跳升级。
1. 升级前准备
# 记录当前版本
sudo gitlab-rake gitlab:env:info | grep -E 'Version|DB version'
# 全量备份
sudo gitlab-ctl stop puma
sudo gitlab-ctl stop sidekiq
sudo gitlab-backup create STRATEGY=copy
sudo gitlab-ctl start
# 备份配置与 secrets
sudo cp /etc/gitlab/gitlab.rb /backup/gitlab.rb.$(date +%F)
sudo cp /etc/gitlab/gitlab-secrets.json /backup/
检查清单:
| 项 | 说明 |
|---|---|
| 磁盘空间 | 至少预留当前数据目录 2 倍空闲 |
| PostgreSQL | 目标 GitLab 版本支持的 PG 大版本 |
| 维护窗口 | 通知用户停写;大型实例可能数小时 |
| Runner / Integrations | 确认 API 无 breaking change |
| 自定义 hook / plugin | 对照 Release Notes 是否废弃 |
在 staging 用生产备份还原后先试升一级,记录耗时与命令输出,再在生产重复。
2. 版本升级路径 (must follow upgrade path)
GitLab 每个大版本通常只支持从前一个大版本的最新补丁升级。示例路径 15.11.x → 16.0.x → 16.11.x → 17.0.x → 17.5.x:
# 查询可用版本(Omnibus)
apt-cache madison gitlab-ce | head -20
# 或 yum list gitlab-ce --showduplicates
不要 apt install gitlab-ce=17.5.0 当实例还在 15.x。正确做法:每次只升到一个允许的下一版本,升完执行:
sudo gitlab-rake gitlab:background_migrations:status
sudo gitlab-rake db:migrate:status
所有 background migrations 完成后再升下一跳。Geo 环境先升 secondary,再升 primary。
3. Omnibus升级
Debian/Ubuntu 单跳升级示例(15.11.13 → 16.0.10):
sudo gitlab-ctl stop
# 指定版本安装
sudo apt-get install -y gitlab-ce=16.0.10-ce.0
sudo gitlab-ctl reconfigure
sudo gitlab-ctl restart
sudo gitlab-rake gitlab:check SANITIZE=true
sudo gitlab-rake gitlab:env:info
RHEL/CentOS:
sudo gitlab-ctl stop
sudo yum install -y gitlab-ce-16.0.10-ce.0.el8
sudo gitlab-ctl reconfigure
sudo gitlab-ctl restart
若 reconfigure 报错,查看 /var/log/gitlab/reconfigure/ 和 gitlab-rails/production.log。常见问题:磁盘满、PG 扩展缺失、自定义 gitlab.rb 键已废弃——按日志提示注释旧键并重新 reconfigure。
4. 大版本升级
大版本(如 16 → 17)除 Omnibus 包升级外,还需关注:
- PostgreSQL 自动升级:Omnibus 可能 bundled PG 大版本跃迁,耗时最长;
- Gitaly 协议变更:客户端需兼容;
- CI/CD 语法废弃:
only/except等; - Ruby/Node 运行时变化:自定义 hook 可能失效。
大版本维护窗口内操作顺序:
sudo gitlab-ctl stop puma
sudo gitlab-ctl stop sidekiq
sudo gitlab-ctl stop gitlab-workhorse
# 安装目标大版本首个推荐补丁
sudo apt-get install -y gitlab-ce=<target-version>
sudo gitlab-ctl reconfigure
# 等待 postgresql 升级完成(勿中断)
sudo gitlab-ctl start
sudo gitlab-rake gitlab:background_migrations:status
直到 gitlab:background_migrations:status 无 pending 再开放用户访问。大型实例 background migrations 可能运行数天,期间可只读或限流。
5. 数据迁移
5.1 同实例版本迁移(备份还原)
已在新服务器安装与备份同版本 GitLab 后:
sudo gitlab-backup restore BACKUP=<timestamp> force=yes
sudo gitlab-rake gitlab:check SANITIZE=true
5.2 跨实例迁移(export/import)
单项目迁移可用 UI Export project,或通过 API:
curl --request POST --header "PRIVATE-TOKEN: $GITLAB_TOKEN" \
"https://old-gitlab.example.com/api/v4/projects/$PROJECT_ID/export"
# 下载 export 后导入新实例
curl --request POST --header "PRIVATE-TOKEN: $NEW_TOKEN" \
--form "path=my-project" --form "file=@export.tar.gz" \
"https://new-gitlab.example.com/api/v4/projects/import"
Export 不含 Runner 注册、部分 CI 变量和 Container Registry 全部历史;Registry 需 docker pull/tag/push 或存储层复制。群组级迁移考虑 GitLab Group Transfer 或第三方工具(如 gitlab-housekeeper),大规模迁移优先备份还原整实例。
6. 数据库迁移
外置 PostgreSQL 时,升级前确认扩展与版本:
sudo gitlab-rake db:migrate:status
sudo gitlab-psql -c "SELECT version();"
sudo gitlab-psql -c "\dx"
GitLab 需要 pg_trgm、btree_gist 等扩展。外置 PG 大版本升级与 GitLab 升级解耦时,先升 PG(兼容当前 GitLab),再升 GitLab。从 bundled PG 迁到外置 PG:
# 在 gitlab.rb 配置 gitlab_rails['db_*']
sudo gitlab-ctl reconfigure
sudo gitlab-rake gitlab:db:configure
sudo gitlab-rake db:migrate
迁移期间停写。验证 gitlab-rails runner 'puts ActiveRecord::Base.connection.execute("select 1")' 与应用登录、MR 列表。
7. 服务器迁移
典型流程:新主机安装同版本 → 恢复 backup + secrets → 验证 → DNS 切换。
# 旧服务器最后增量备份
sudo gitlab-backup create STRATEGY=copy
# 新服务器
sudo cp gitlab.rb gitlab-secrets.json /etc/gitlab/
sudo gitlab-ctl reconfigure
sudo gitlab-backup restore BACKUP=<timestamp> force=yes
sudo gitlab-ctl restart
切换前对比:
sudo gitlab-rails runner 'puts Project.count'
curl -I https://new-host/users/sign_in
DNS TTL 提前调低(如 300s)。切换后旧机保留只读数天,确认无回连再下线。IP 变更时更新防火墙、Runner gitlab_url 和 Webhook 地址。
8. 回滚方案
Omnibus 不支持 apt downgrade 后直接运行;回滚依赖备份还原:
# 升级失败且服务无法启动
sudo gitlab-ctl stop
sudo apt-get install -y gitlab-ce=<previous-exact-version>
sudo cp /backup/gitlab-secrets.json.pre-upgrade /etc/gitlab/gitlab-secrets.json
sudo gitlab-backup restore BACKUP=<pre-upgrade-timestamp> force=yes
sudo gitlab-ctl reconfigure
sudo gitlab-ctl restart
| 场景 | 回滚手段 |
|---|---|
| 升级后逻辑错误但服务运行 | 应用层修复或还原 DB 快照(需维护窗口) |
| reconfigure 失败 | 修复 gitlab.rb,不继续升下一跳 |
| PG 自动升级失败 | 从升级前 VM 快照或 backup 还原整节点 |
| 已跑 background migrations | 通常不能降版本;只能 forward fix |
每次升级保留:升级前 exact 包版本号、gitlab-backup tar、secrets 副本、gitlab.rb 副本。生产至少保留一级可回退介质,并在 Runbook 中写明决策树:何时 forward fix、何时全量还原。