[分享]gitlab&Geo 零停机升级

今天给使用gitlab数据量特别大的朋友,分享一个短停机方法~

描述

在您升级前,请务必阅读以下重要信息:

  • 您一次只能升级一个次要版本,所以从13.9到13.10,而不是14.0。如果您尝试升级多个次要版本,升级可能会失败。

  • 在单节点Omnibus部署中,当使用Puma时,不需要停机的更新是不可能的,因为Puma总是需要完全重启(除非特别禁用,否则用Puma取代Unicorn作为GitLab 13.0的默认选项)。这是因为Puma的阶段性重启功能与它在GitLab all-in-one包中配置的方式不同(集群模式,应用程序预加载)。

  • 虽然按照这些说明可以最大限度减少单节点实例的停机时间,但不可能始终实现真正的零停机时间升级。用户可能会看到一些连接超时或被拒绝几分钟,具体取决于哪些服务需要重新启动。

1. Geo安装配置

这部分详细内容,请参考极狐Geo部署文档。

2. 升级路径

  • 例子:13.12.9-ee->13.12.9-jh->13.12.15-jh>14.0.12-jh>14.1.8-jh>14.2.7-jh>14.3.6-jh>14.4.5-jh>14.5.4-jh>14.6.7-jh>14.7.7-jh>14.8.6-jh>14.9.5-jh>14.10.5 -jh>15.0.5-jh>15.1.6-jh

3. 更新 Geo 主站点

登录到您的节点,执行以下命令:

  1. /etc/gitlab/skip-auto-reconfigure创建一个空文件。这可以防止升级运行GitLab -ctl reconfigure,默认情况下会自动停止GitLab,运行所有的数据库迁移,并重新启动GitLab:

    sudo touch /etc/gitlab/skip-auto-reconfigure
    
  2. 编辑/etc/gitlab/gitlab.rb

    gitlab_rails['auto_migrate'] = false
    
  3. 重新配置gitlab

    sudo gitlab-ctl reconfigure
    
  4. 更新Gitlab包:

    包管理器:

    # 安装极狐包管理器
    curl -fsSL https://packages.gitlab.cn/repository/raw/scripts/setup.sh | /bin/bash
    
    # Debian/Ubuntu
    sudo apt-get update && sudo apt-get install gitlab-jh=13.12.9
    
    # Centos/RHEL
    sudo yum install gitlab-jh
    

    每次升级跨一个次要版本页面会报500,执行下一步会恢复。

    安装包下载:

    https://packages.gitlab.cn/
    
  5. 要获取数据库迁移和最新代码,请运行:

    sudo SKIP_POST_DEPLOYMENT_MIGRATIONS=true gitlab-ctl reconfigure
    

    执行后会短暂502。

3.2 更新Geo次要站点

如果从节点已经安装同版本极狐gitlab则跳过

登录到节点,执行以下命令

  1. 在/etc/gitlab/skip-auto-reconfigure创建一个空文件。这可以防止升级运行GitLab -ctl reconfigure,默认情况下会自动停止GitLab,运行所有的数据库迁移,并重新启动GitLab。

    sudo touch /etc/gitlab/skip-auto-reconfigure
    
  2. 编辑/etc/gitlab/gitlab.rb

    gitlab_rails['auto_migrate'] = false
    
  3. 重新配置gitlab:

    sudo gitlab-ctl reconfigure
    
  4. 更新Gitlab:

    # 安装极狐包管理器
    curl -fsSL https://packages.gitlab.cn/repository/raw/scripts/setup.sh | /bin/bash
    
    # Debian/Ubuntu
    sudo apt-get update && sudo apt-get install gitlab-ee
    
    # Centos/RHEL
    sudo yum install gitlab-jh
    

    每次升级跨一个次要版本页面会报500,执行下一步会恢复。

    安装包下载:

    https://packages.gitlab.cn/
    
  5. 要获取数据库迁移和最新代码,请运行:

    sudo SKIP_POST_DEPLOYMENT_MIGRATIONS=true gitlab-ctl reconfigure
    

    执行后会短暂502,等待一会儿恢复,能正常推拉代码。

  6. 运行特定 Geo 数据库的部署后数据库迁移:

    15.0.x以下:

    sudo gitlab-rake geo:db:migrate
    

    大于等于15.0.x:

    sudo gitlab-rake db:migrate:geo
    

3.3 完成更新

升级完所有从节点后,在主节点上完成更新:

  • 运行部署后数据库迁移

     sudo gitlab-rake db:migrate
    
  • 在主节点上完成更新后,在所有主节点和辅助节点上热重新加载puma并重启sidekiqgeo-logcursor服务:

     sudo gitlab-ctl hup puma
     sudo gitlab-ctl restart sidekiq
     sudo gitlab-ctl restart geo-logcursor
    

    执行完后页面会短暂502

更新所有节点(主节点和所有从节点)后,检查它们状态:

  • 验证Geo配置和依赖项:

     sudo gitlab-rake gitlab:geo:check
    

    如果您以后不想运行零停机升级,请确保在完成这些步骤后删除/etc/gitlab/skip-auto-reconfigure,并在/etc/gitlab/gitlab.rb删除gitlab_rails['auto_migrate'] = false

4. 特殊版本

13.9.0

我们已经检测到一个列重命名的问题,当遵循零停机步骤时,阻止升级到GitLab 13.9.0, 13.9.1, 13.9.2和13.9.3。为了实现零停机升级,需要执行以下额外步骤:

  1. 在部署节点上运行最终sudo gitlab-rake db:migrate命令之前,使用 PostgreSQL 控制台(或)sudo gitlab-psql执行以下查询来删除有问题的触发器:

    drop trigger trigger_e40a6f1858e6 on application_settings;
    drop trigger trigger_0d588df444c8 on application_settings;
    drop trigger trigger_1572cbc9a15f on application_settings;
    drop trigger trigger_22a39c5c25f3 on application_settings;
    
  2. 运行最终的迁移命令:

    sudo gitlab-rake db:migrate
    

如果你已经在部署节点上运行了sudo gitlab-rake db:migrate命令,并且遇到了列重命名问题,你会看到以下错误:

-- remove_column(:application_settings, :asset_proxy_whitelist)
rake aborted!
StandardError: An error has occurred, all later migrations canceled:
PG::DependentObjectsStillExist: ERROR: cannot drop column asset_proxy_whitelist of table application_settings because other objects depend on it
DETAIL: trigger trigger_0d588df444c8 on table application_settings depends on column asset_proxy_whitelist of table application_settings

要解决这个问题参考这个 issue.

14.4.4

对于具有独立Web和API节点的GitLab集群的零停机升级,在将GitLab Web节点升级到14.4之前,必须启用paginated_tree_graphql_query特性标志。这是因为我们在14.4中默认启用了paginated_tree_graphql_query,所以如果GitLab UI在14.4,它的API在14.3,前端启用了这个特性,但后端禁用了它。这将导致以下错误:

bundle.esm.js:63 Uncaught (in promise) Error: GraphQL error: Field 'paginatedTree' doesn't exist on type 'Repository'

5. 后台任务检查(import)

这是必须执行的检查,如果忽略将会导致后续升级失败。

5.1 后台检查

  • 如果您的 GitLab JH 版本 >= 15.1 ,执行如下命令:
sudo gitlab-rails runner -e production 'puts Gitlab::BackgroundMigration.remaining'
sudo gitlab-rails runner -e production 'puts Gitlab::Database::BackgroundMigration::BatchedMigration.queued.count'
  • 如果您的 GitLab JH 版本 >= 14.8 ,执行如下命令:
sudo gitlab-rails runner -e production 'puts Gitlab::BackgroundMigration.remaining'
sudo gitlab-rails runner -e production 'puts Gitlab::Database::BackgroundMigrationJob.pending.count'
  • 如果您的 GitLab JH 版本 = 14.7 ,执行如下命令:
sudo gitlab-rails runner -e production 'puts Gitlab::BackgroundMigration.remaining'
sudo gitlab-rails runner -e production 'puts Gitlab::Database::BackgroundMigrationJob.pending'
  • 如果您的 GitLab JH 版本 = 14.6,执行如下命令:
sudo gitlab-rails runner -e production 'puts Gitlab::BackgroundMigration.remaining'
sudo gitlab-rails runner -e production 'puts Gitlab::BackgroundMigration.pending'

sudo gitlab-rails runner -e production 'puts Gitlab::BackgroundMigration.remaining'
sudo gitlab-rails runner -e production 'puts Gitlab::BackgroundMigration.pending'
  • 如果您的 GitLab JH 版本 12.9 <= version <= 14.5,执行如下命令:
sudo gitlab-rails runner -e production 'puts Gitlab::BackgroundMigration.remaining'
  • 如果您的 GitLab EE 版本 <= 12.8,执行如下命令:

首先进入 Rails console:

sudo gitlab-rails c

然后,在 Rails console 中执行如下命令:

puts Sidekiq::Queue.new("background_migration").size
Sidekiq::ScheduledSet.new.select { |r| r.klass == 'BackgroundMigrationWorker' }.size
  • 如果后台迁移卡住未能完成,可以通过以下命令重新执行后台迁移命令:
# Start the rails console
sudo gitlab-rails c

# Execute the following in the rails console
scheduled_queue = Sidekiq::ScheduledSet.new
pending_job_classes = scheduled_queue.select { |job| job["class"] == "BackgroundMigrationWorker" }.map { |job| job["args"].first }.uniq
pending_job_classes.each { |job_class| Gitlab::BackgroundMigration.steal(job_class) }

或者通过以下命令重新调用这些作业:

# https://docs.gitlab.com/ee/update/#background-migrations-stuck-in-pending-state
# Start the rails console
sudo gitlab-rails c

# Execute the following in the rails console
Gitlab::Database::BackgroundMigrationJob.pending.find_each do |job|
  puts "Running pending job '#{job.class_name}' with arguments #{job.arguments}"
  result = Gitlab::BackgroundMigration.perform(job.class_name, job.arguments)
  puts "Result: #{result}"
end

详细参考:

5.2 页面检查

  • 如果您的 GitLab JH 版本>=14.0.1,可以通过以下路径检查:

    Menu> Monitoring> Background Migrations

    查看选项卡是否所有Migration都已经Finished,如果没有请必须等待所有任务完成!!!否则会导致升级异常!

  • 检查Geo状态是否健康、复制是否正常!