GitLab 15.8.1 → 16.10.10 跨OS升级与迁移全流程实战(CentOS7 → Rocky9.5)

前言:在企业运维中,GitLab 版本升级与服务器迁移是高频且关键的操作。本文基于真实生产场景,完整记录了从 CentOS7 上的 GitLab 15.8.1,通过 5 步合规升级(含额外安全过渡节点)到 16.10.10,再将全量数据迁移至 Rocky9.5 新服务器*的全流程。

本次操作严格遵循 GitLab 官方升级规范,重点补充了「后台迁移检查」「维护模式双应急退出方案」「UI 界面进度核验」等生产环境极易踩坑的隐形细节,并针对跨操作系统(CentOS7 → Rocky9.5)带来的潜在风险(如 PostgreSQL 索引损坏)进行了重点排错。所有步骤通用化,无任何业务敏感信息,可直接用于企业生产环境落地。


一、环境与版本路径说明

1.1 环境定义

  • 旧环境 :CentOS 7,GitLab 15.8.1,数据存储于系统盘 /var/opt/gitlab
  • 新环境 :Rocky Linux 9.5,目标版本 16.10.10,规划独立存储以提升性能与可扩展性

1.2 官方升级路径查询(必做前置)

在开始任何升级前,必须通过 GitLab 官方工具查询唯一合规的升级路径,避免因版本跳跃导致数据损坏。

官方查询链接

GitLab Upgrade Path Tool

查询步骤
  1. 打开上述链接。
  2. 在表单中填写:
    • Current version15.8.1
    • Target version16.10.10
    • Linux distribution:根据你的系统选择(如 AlmaLinux 或 CentOS/Rocky)
    • GitLab editionCE(社区版)或 EE(企业版)
  3. 点击查询,获取官方推荐路径。
升级路径可视化(Mermaid 流程图)

15.8.1

CentOS7
15.11.13

CentOS7
16.1.5

CentOS7

额外过渡节点
16.3.9

CentOS7
16.10.10

CentOS7
全量备份

配置+数据
16.10.10

Rocky9.5

全新安装
恢复备份

权限修复
PostgreSQL索引重建

glibc兼容修复
验证同步

业务上线

官方推荐升级路径(15.8.1 → 16.10.10)
复制代码
15.8.1 → 15.11.13 → 16.3.9 → 16.7.10 → 16.10.10
实际执行升级路径(含额外安全过渡)
复制代码
15.8.1 → 15.11.13 → 16.1.5 → 16.3.9 → 16.10.10
为何额外增加 16.1.5 节点?

官方路径是推荐的稳定中继,但在生产实践中,从 15.11.x 直接跨到 16.3.x 存在一定风险:

  1. 兼容性风险:16.x 系列引入了大量架构变更,直接跳至 16.3.x 可能导致配置不兼容。
  2. 数据库风险:跨大版本升级可能触发 PostgreSQL 索引损坏,尤其在后续还要跨 OS 迁移的场景下,风险被放大。
  3. 保守实践 :我们选择 16.1.5 作为额外过渡节点,它是 16.x 系列的首个稳定分支,能有效平滑过渡,降低升级风险,是更稳妥的生产级选择。

二、旧环境(CentOS7)5步完整升级

2.1 升级前置准备(解决CentOS7 GPG签名过期问题)

CentOS 7 系统中 GitLab 官方仓库的 GPG 签名密钥在 2024 年完成更新,未更新密钥会导致 yum install 时报签名验证失败,需提前执行以下命令:

bash 复制代码
# 导入GitLab最新GPG签名密钥,预防安装失败
rpm --import https://packages.gitlab.com/gitlab/gitlab-ce/gpgkey
rpm --import https://packages.gitlab.com/gitlab/gitlab-ce/gpgkey/gitlab-gitlab-ce-3D645A26AB9FBD22.pub.gpg

2.2 升级通用前置操作(每步升级前必执行)

bash 复制代码
# 1. 停止核心业务服务,避免写入冲突
gitlab-ctl stop sidekiq puma geo-logcursor mailroom

# 2. 开启维护模式(只读),禁止业务写入(替代原只读命令,更通用)
gitlab-ctl deploy-page up

# 3. 检查数据库迁移状态(必须全部显示 up)
gitlab-rake db:migrate:status

# 4. 清理系统缓存
gitlab-rake cache:clear

# 5. 全量备份(每跨一个版本必做,升级生命线)
gitlab-backup create STRATEGY=copy
cp -r /etc/gitlab /etc/gitlab_backup_$(date +%Y%m%d_%H%M)
🔥 核心补充:维护模式挂载失败的双应急方案

若执行 gitlab-ctl deploy-page up 后提示「挂载失败/服务无响应」,需根据场景选择以下方案:

方案1:强制退出维护模式(快速恢复业务)

适用于无需等待后台迁移,优先恢复业务访问的场景:

bash 复制代码
# 应急退出维护模式(强制清理挂载锁)
gitlab-ctl deploy-page down
# 若仍无效,直接删除维护模式配置文件
rm -rf /var/opt/gitlab/nginx/www/deploy.html
gitlab-ctl restart nginx
方案2:启动sidekiq完成后台迁移(保障数据一致性)

适用于维护模式挂不上,但必须完成后台迁移再升级的场景(匹配生产实战操作):

bash 复制代码
# 步骤1:启动sidekiq服务,继续后台迁移
gitlab-ctl start sidekiq
gitlab-ctl status sidekiq  # 确认显示 run 状态

# 步骤2:等待后台迁移全部完成(生产环境实际查询命令)
gitlab-psql -c "SELECT id, job_class_name, status FROM batched_background_migrations WHERE status < 3;"
# 要求:输出为空(即无未完成/运行中的迁移任务)
# 补充UI核验:后台 → 管理中心 → 监控 → 后台迁移 → 「队列中=0,失败=0」

# 步骤3:后台迁移完成后,停止sidekiq(恢复只读状态)
gitlab-ctl stop sidekiq
gitlab-ctl status sidekiq  # 确认显示 down 状态

2.3 第1步:15.8.1 → 15.11.13(15.x 最终稳定版)

bash 复制代码
yum install -y gitlab-ce-15.11.13-ce.0.el7.x86_64
gitlab-ctl reconfigure
gitlab-ctl restart

# ========== 关键检查:后台迁移进度(必须完成才能继续) ==========
# 生产环境实际查询命令(优先使用)
gitlab-psql -c "SELECT id, job_class_name, status FROM batched_background_migrations WHERE status < 3;"
# 补充CLI命令(备用)
gitlab-rake gitlab:background_migrations:status
# UI 核验:管理中心 → 监控 → 后台迁移 → 无未完成任务

# 基础状态校验
gitlab-rake db:migrate:status
gitlab-rake gitlab:check SANITIZE=true

2.4 第2步:15.11.13 → 16.1.5(额外安全过渡,核心)

bash 复制代码
yum install -y gitlab-ce-16.1.5-ce.0.el7.x86_64
gitlab-ctl reconfigure
gitlab-ctl restart

# ========== 后台迁移进度检查(必做) ==========
gitlab-psql -c "SELECT id, job_class_name, status FROM batched_background_migrations WHERE status < 3;"
# 要求:输出为空(无未完成迁移)
# UI 核验:管理中心 → 监控 → 后台迁移 → 所有任务「Completed」

gitlab-rake db:migrate:status
gitlab-rake gitlab:check SANITIZE=true

2.5 第3步:16.1.5 → 16.3.9(官方推荐中继)

bash 复制代码
yum install -y gitlab-ce-16.3.9-ce.0.el7.x86_64
gitlab-ctl reconfigure
gitlab-ctl restart

# ========== 后台迁移进度检查(必做) ==========
gitlab-psql -c "SELECT id, job_class_name, status FROM batched_background_migrations WHERE status < 3;"
# 要求:输出为空(无未完成迁移)
# UI 核验:管理中心 → 监控 → 后台迁移 → 无未完成任务

gitlab-rake db:migrate:status
gitlab-rake gitlab:check SANITIZE=true

2.6 第4步:16.3.9 → 16.10.10(最终目标版本)

bash 复制代码
yum install -y gitlab-ce-16.10.10-ce.0.el7.x86_64
gitlab-ctl reconfigure
gitlab-ctl restart

# ========== 后台迁移最终检查(必做) ==========
gitlab-psql -c "SELECT id, job_class_name, status FROM batched_background_migrations WHERE status < 3;"
# 要求:输出为空(所有迁移完成)
# UI 核验:管理中心 → 监控 → 后台迁移 → 所有任务完成

# 关闭维护模式,恢复业务写入
gitlab-ctl deploy-page down

# 最终全量验证
gitlab-rake gitlab:env:info
gitlab-rake gitlab:check SANITIZE=true

2.7 旧环境最终备份(用于新环境迁移)

⚠️ 核心警告 :务必确保 /etc/gitlab/gitlab-secrets.json 文件被正确迁移。如果该文件丢失或与数据库内的加密数据不匹配,会导致所有加密数据(如 CI 变量、Runner Token、双重认证密钥)无法解密,且该类数据几乎无法挽回!

bash 复制代码
# 生成最终版本全量数据备份
gitlab-backup create
# 备份文件示例:1707485440_2026_02_09_16.10.10_gitlab_backup.tar
# 核心说明:备份文件名格式为「时间戳_日期_版本号_gitlab_backup.tar」

# 备份全部配置文件(重点包含gitlab-secrets.json)
cp -r /etc/gitlab /tmp/gitlab_etc_bak_161010
# 建议单独备份gitlab-secrets.json,双重保障
cp /etc/gitlab/gitlab-secrets.json /tmp/gitlab-secrets.json.bak

将以下文件传输至新服务器 /tmp 目录:

  • 数据备份包:如 1707485440_2026_02_09_16.10.10_gitlab_backup.tar
  • 配置备份目录:gitlab_etc_bak_161010
  • 单独的secrets备份:gitlab-secrets.json.bak

三、新环境(Rocky9.5)初始化与安装

3.1 新环境安装同版本 GitLab(16.10.10)

bash 复制代码
# 安装基础依赖
dnf install -y curl policycoreutils openssh-server postfix
systemctl enable --now postfix

# 配置 GitLab 官方源
curl -sS https://packages.gitlab.com/install/repositories/gitlab/gitlab-ce/script.rpm.sh | bash

# 安装与旧环境一致的最终版本
dnf install -y gitlab-ce-16.10.10-ce.0.el9.x86_64

# 初始化(自动创建 git 用户、目录结构)
gitlab-ctl reconfigure

# 初始化后立即停止所有服务
gitlab-ctl stop

四、新环境备份恢复与数据迁移

4.1 备份与配置文件权限处理

⚠️ 核心提醒 :恢复配置时优先覆盖 gitlab-secrets.json,确保与旧环境完全一致!

bash 复制代码
# 1. 移动数据备份包至指定目录
mv /tmp/1707485440_2026_02_09_16.10.10_gitlab_backup.tar /var/opt/gitlab/backups/

# 2. 修正备份文件权限(必须为 git:git)
chown git:git /var/opt/gitlab/backups/*.tar
chmod 600 /var/opt/gitlab/backups/*.tar

# 3. 恢复配置文件(优先恢复secrets文件)
cp /tmp/gitlab-secrets.json.bak /etc/gitlab/gitlab-secrets.json
cp -r /tmp/gitlab_etc_bak_161010/* /etc/gitlab/
chown -R root:root /etc/gitlab

4.2 执行备份恢复

📌 关键说明BACKUP= 后仅需填写备份文件名的「时间戳部分」,而非完整文件名!

示例:备份文件为 1707485440_2026_02_09_16.10.10_gitlab_backup.tarBACKUP=1707485440_2026_02_09_16.10.10

bash 复制代码
# 1. 启动PostgreSQL(恢复操作依赖数据库服务)
gitlab-ctl start postgresql

# 2. 停止其他依赖服务
gitlab-ctl stop puma sidekiq geo-logcursor

# 3. 执行恢复(输入 yes 确认)
gitlab-backup restore BACKUP=1707485440_2026_02_09_16.10.10

# 4. 恢复完成后重载配置+启动所有服务
gitlab-ctl reconfigure
gitlab-ctl start
📢 补充提醒:外部存储数据同步

若你的 GitLab 开启了外部存储(LFS、CI 制品、Artifacts 存储在 S3/MinIO/对象存储),需注意:

  • gitlab-backup create 不会备份外部存储数据;
  • 需手动同步外部存储的文件至新环境,或在新环境配置相同的外部存储访问权限。

五、跨OS迁移后的高频排错(重点)

问题1:PostgreSQL 索引损坏(官方警告场景)

现象 :数据库查询缓慢、报错,对应官方警告 "Potential PostgreSQL index corruption when upgrading OS"。
原因 :从 CentOS7(glibc 2.17)迁移到 Rocky9.5(glibc 2.34),locale 数据变化导致索引损坏。
修复

bash 复制代码
# 1. 停止 PostgreSQL
gitlab-ctl stop postgresql

# 2. 重新索引(针对所有受影响的表,核心操作)
gitlab-ctl reindex --all

# 3. 启动服务并验证
gitlab-ctl start postgresql
gitlab-rake db:migrate:status

问题2:PostgreSQL/Redis 权限问题

现象 :服务启动失败,报错 Permission denied
原因 :跨 OS 迁移后,目录属主与权限丢失。
修复

bash 复制代码
# 修复 PostgreSQL 权限
gitlab-ctl stop postgresql
chown -R gitlab-psql:gitlab-psql /var/opt/gitlab/postgresql/data
chmod -R 700 /var/opt/gitlab/postgresql/data
gitlab-ctl start postgresql

# 修复 Redis 权限
gitlab-ctl stop redis
chown -R git:git /var/opt/gitlab/redis
chmod -R 700 /var/opt/gitlab/redis
chmod 600 /var/opt/gitlab/redis/redis.conf
gitlab-ctl start redis

问题3:服务启动异常

现象 :部分服务(如 Puma, Sidekiq)启动失败。
修复

bash 复制代码
# 重新配置并重启所有服务
gitlab-ctl reconfigure
gitlab-ctl restart

# 检查服务状态
gitlab-ctl status

六、生产级数据一致性验证

6.1 服务状态验证

bash 复制代码
gitlab-ctl status                # 所有服务均为 run 状态
gitlab-rake gitlab:check SANITIZE=true  # 无红色报错,所有项为 yes

6.2 核心业务数据计数验证(新老环境必须完全一致)

bash 复制代码
# 用户总数
gitlab-rails runner "puts '用户总数:' + User.count.to_s"
# 活跃用户数
gitlab-rails runner "puts '活跃用户数:' + User.active.count.to_s"
# 项目总数
gitlab-rails runner "puts '项目总数:' + Project.count.to_s"
# 分组总数
gitlab-rails runner "puts '分组总数:' + Group.count.to_s"
# MR 总数
gitlab-rails runner "puts 'MR 总数:' + MergeRequest.count.to_s"
# Issues 总数
gitlab-rails runner "puts 'Issues 总数:' + Issue.count.to_s"

6.3 仓库可用性验证

bash 复制代码
# 统计仓库文件总数
find /var/opt/gitlab/git-data/repositories/ -type d -name "*.git" | wc -l

# 验证首个项目仓库是否存在(输出 true 即为正常)
gitlab-rails runner "puts Project.first.repository.exists?"

七、附录:GitLab 迁移速查 Cheat Sheet (CentOS7 → Rocky9)

markdown 复制代码
### 1. 旧环境升级循环 (每一步)
# 停止服务 → 开启维护模式 → 备份 → 安装 → 刷新 → 检查后台迁移 → 基础校验
gitlab-ctl stop sidekiq puma geo-logcursor
gitlab-ctl deploy-page up
gitlab-backup create
yum install -y gitlab-ce-<VERSION>-ce.0.el7.x86_64
gitlab-ctl reconfigure
gitlab-ctl restart
gitlab-psql -c "SELECT id, job_class_name, status FROM batched_background_migrations WHERE status < 3;"  # 必须无输出
gitlab-rake db:migrate:status
gitlab-rake gitlab:check SANITIZE=true

### 2. 维护模式挂载失败的双应急方案
# 方案1:强制退出维护模式
gitlab-ctl deploy-page down
rm -rf /var/opt/gitlab/nginx/www/deploy.html
gitlab-ctl restart nginx

# 方案2:启动sidekiq完成后台迁移
gitlab-ctl start sidekiq
gitlab-psql -c "SELECT id, job_class_name, status FROM batched_background_migrations WHERE status < 3;"
gitlab-ctl stop sidekiq

### 3. 最终打包 (旧环境)
gitlab-backup create
tar -czvf /tmp/gitlab_config_backup.tar.gz /etc/gitlab
# 将上面两个文件 scp 到新服务器

### 4. 新环境恢复 (Rocky9)
# 必须先安装同版本 GitLab 16.10.10
dnf install -y gitlab-ce-16.10.10-ce.0.el9.x86_64
gitlab-ctl reconfigure
gitlab-ctl stop

# 放置文件
cp <backup_file> /var/opt/gitlab/backups/
chown git:git /var/opt/gitlab/backups/*
tar -xzvf gitlab_config_backup.tar.gz -C /
chown -R root:root /etc/gitlab

# 执行恢复(BACKUP=时间戳部分)
gitlab-ctl start postgresql
gitlab-backup restore BACKUP=<TIMESTAMP>

### 5. 关键修复 (新环境)
# 修复 PostgreSQL 索引 (glibc 变更必做)
gitlab-ctl reindex --all

# 修复权限
chown -R gitlab-psql:gitlab-psql /var/opt/gitlab/postgresql
chown -R git:git /var/opt/gitlab/redis

### 6. 重启与验证
gitlab-ctl reconfigure
gitlab-ctl restart
gitlab-rake gitlab:check SANITIZE=true

八、总结与经验

  1. 官方工具优先 :升级前务必使用 GitLab Upgrade Path Tool 查询合规路径,这是避免灾难的第一步。
  2. 后台迁移是隐形杀手 :15.x→16.x 升级中,未完成的后台迁移会直接导致数据库损坏,生产环境优先用 gitlab-psql 命令核验,确保无未完成任务。
  3. 维护模式有双兜底方案:挂载失败时,可选择「强制退出恢复业务」或「启动sidekiq完成迁移」,适配不同生产场景。
  4. 密钥绝不丢失gitlab-secrets.json 是 GitLab 加密数据的核心,迁移时必须单独备份、优先恢复,丢失会导致加密数据永久失效。
  5. CentOS7 特殊处理:提前更新 GPG 密钥,避免安装时签名验证失败。
  6. 跨OS迁移核心坑 :glibc 版本差异会导致 PostgreSQL 索引损坏,必须执行 reindex --all 修复。
  7. 备份参数别填错gitlab-backup restoreBACKUP= 仅需填写时间戳部分,而非完整文件名。
  8. 版本升级保守化:额外增加 16.1.5 过渡节点,能大幅降低跨大版本升级的兼容性风险,生产环境优先选择"慢但稳"的路径。

相关推荐
我就是你毛毛哥1 天前
Docker 安装 GitLab
docker·容器·gitlab
雨声不在3 天前
gitlab中的repo删除特定commit
gitlab
vpk1124 天前
Docker Compose 部署 GitLab
docker·容器·gitlab
Irene19915 天前
什么是 DevOps
gitlab·devops
蓝天星空5 天前
GitLab上传项目到新的分支
gitlab
1candobetter8 天前
GitLab 项目创建与分支管理全流程
gitlab
JuckenBoy8 天前
Linux环境安装SGLang框架运行自选大模型(以Rocky9.7为例)
linux·运维·大模型·qwen·rocky·deepseek·sglang
林鸿群9 天前
Ubuntu 26.04 本地安装 GitLab CE 完整教程(非 Docker 方式)
linux·ubuntu·gitlab·私有部署·代码托管·ubuntu 26.04·omnibus
ascarl201010 天前
IDEA 一直弹 GitLab 登录,VS Code 却能正常 `git push`?问题排查记录
git·gitlab·intellij-idea
企鹅郁金香12 天前
Gitlab和Confluence和Svn的备份
svn·gitlab·confluence·gitlab备份·svn备份·confluence备份