{{< details >}}
- Tier: 基础版、专业版、旗舰版
- Offering: 私有化部署
{{< /details >}}
通过零停机升级,可以在不使极狐GitLab环境下线的情况下进行升级。本指南将带您完成执行此类升级的核心流程。
从总体上来看,这个过程是通过按顺序升级极狐GitLab节点来完成的,利用负载均衡、高可用系统和优雅的重载来将中断最小化。
本指南仅适用于极狐GitLab核心组件的升级或管理第三方服务(如 AWS RDS)时,请参考相应的文档。
在您开始之前
作为升级的一部分,实现真正的零停机对于任何分布式应用程序来说都是非常困难的。本指南中详细介绍的过程已经根据我们的高可用参考架构进行了测试,发现结果基本上没有明显的停机,但请注意,具体效果可能会因具体系统组成而有所不同。
为了增加信心,一些客户发现使用进一步的技术,例如使用特定负载均衡器或基础设施功能手动排空节点很成功。这些技术很大程度上依赖于底层基础设施功能,因此在本指南中不涉及。有关任何其他信息,请联系您的极狐GitLab代表或支持团队。
要求和注意事项
零停机升级过程有以下要求:
- 零停机升级仅支持使用 Linux 软件包构建的多节点极狐GitLab环境,配置了负载均衡和可用的高可用机制,如下所示:
- 为 Rails 节点配置了外部负载均衡器,并启用了针对Readiness(
/-/readiness
)端点的健康检查。 - 为任何 PgBouncer 和 Praefect 组件配置了内部负载均衡器,并启用了 TCP 健康检查。
- 为 Consul、Postgres、Redis 组件配置了高可用机制(如果存在)。
- 如果这些组件中的任何一个不是以高可用方式部署的,则需要单独进行停机升级。
- 对于数据库,Linux 软件包仅支持极狐GitLab主数据库的高可用。对于任何其他数据库,例如 Praefect 数据库,需要第三方数据库解决方案来实现高可用,从而避免停机。
- 为 Rails 节点配置了外部负载均衡器,并启用了针对Readiness(
-
您只能一次升级一个次要版本。所以从
16.1
升级到16.2
,不能升级到16.3
。如果您跳过版本,数据库修改可能会按错误的顺序运行并使数据库模式处于损坏状态。 - 您必须使用部署后迁移。
- 零停机升级无法与极狐GitLab Charts一起使用。可以通过极狐GitLab Operator获得支持,但此部署方法存在已知限制,因此本指南目前不涉及。
除了上述要求之外,请注意以下注意事项:
- 大多数情况下,如果补丁版本不是最新的,您可以安全地从补丁版本升级到下一个次要版本。例如,从
16.3.2
升级到16.4.1
应该是安全的,即使16.3.3
已发布。您应该验证与您的升级路径相关的版本特定升级说明,并注意任何所需的升级停靠点: - 某些版本可能包括后台迁移。这些迁移由 Sidekiq 在后台执行,通常用于迁移数据。后台迁移仅在每月发布的版本中添加。
- 零停机升级可以为Gitaly执行,因为它已经在其集群或分片设置中设置了优雅重载机制。对于 Praefect (Gitaly Cluster) 组件,也可以直接升级而无需停机,但是极狐GitLab Linux 软件包不提供其数据库的高可用和零停机支持 - 需要第三方数据库解决方案来避免停机。
- PostgreSQL 主要版本升级是一个单独的过程,不包括在零停机升级中(较小的升级包含在内)。
- 零停机升级支持您通过极狐GitLab Linux 软件包部署的极狐GitLab组件。如果您通过支持的第三方服务(如 AWS RDS 中的 PostgreSQL 或 GCP Memorystore 中的 Redis)部署了选定组件,则需要按照标准流程单独执行这些服务的升级。
- 作为一般指南,您拥有的数据量越大,完成升级所需的时间越长。在测试中,任何小于 10 GB 的数据库通常不应超过一个小时,但具体效果可能会有所不同。
{{< alert type=”note” >}}
如果您想升级多个版本或不符合这些要求,应探索停机升级。
{{< /alert >}}
升级顺序
我们建议采用“从后到前”的方法来按顺序升级组件以实现零停机。通常是先升级有状态后端,然后是其依赖项,然后是前端。虽然部署顺序可以更改,但最好将运行极狐GitLab应用程序代码的组件(Rails、Sidekiq)一起部署。如果可能,请单独升级支持基础设施(PostgreSQL、PgBouncer、Consul、Gitaly、Praefect、Redis),因为这些组件在主要版本更新中没有依赖关系。因此,我们通常推荐以下顺序:
- Consul
- PostgreSQL
- PgBouncer
- Redis
- Gitaly
- Praefect
- Rails
- Sidekiq
多节点 / 高可用部署
在本节中,我们将按升级顺序依次升级每个节点,通过负载均衡器 / 高可用机制处理每个节点的停机,从而升级多节点极狐GitLab环境。
为本指南目的,我们将使用 Linux 软件包升级一个200 RPS 或 10,000 参考架构。
Consul、PostgreSQL、PgBouncer 和 Redis
Consul、PostgreSQL、PgBouncer 和 Redis 组件都遵循相同的底层过程来实现无停机升级。
在每个组件的节点上按顺序运行以下步骤以执行升级:
-
在
/etc/gitlab/skip-auto-reconfigure
创建一个空文件。这可以防止升级运行gitlab-ctl reconfigure
,默认情况下会自动停止极狐GitLab,运行所有数据库迁移并重新启动极狐GitLab:sudo touch /etc/gitlab/skip-auto-reconfigure
-
重新配置并重新启动以获取最新代码:
sudo gitlab-ctl reconfigure sudo gitlab-ctl restart
Gitaly
Gitaly 在升级时遵循相同的核心流程,但有一个关键区别,即 Gitaly 进程本身不会重新启动,因为它内置了一个尽快优雅重载的功能。请注意,任何其他组件仍然需要重新启动。
{{< alert type=”note” >}}
升级过程尝试优雅地交接到新的 Gitaly 进程。在升级前启动的现有长时间运行的 Git 请求可能会随着交接的发生最终被丢弃。
{{< /alert >}}
此过程适用于 Gitaly 分片和集群设置。在每个 Gitaly 节点上按顺序运行以下步骤以执行升级:
-
在
/etc/gitlab/skip-auto-reconfigure
创建一个空文件。这可以防止升级运行gitlab-ctl reconfigure
,默认情况下会自动停止极狐GitLab,运行所有数据库迁移并重新启动极狐GitLab:sudo touch /etc/gitlab/skip-auto-reconfigure
-
运行
reconfigure
命令以获取最新代码并指示 Gitaly 在下一个机会优雅重载:sudo gitlab-ctl reconfigure
-
最后,虽然 Gitaly 将优雅地重载,但任何已部署的其他组件仍需要重新启动:
# 获取除 Gitaly 外其他已部署组件的列表 sudo gitlab-ctl status # 重新启动除 Gitaly 外的每个组件。示例以 Consul、节点导出器和日志轮换为例 sudo gitlab-ctl restart consul node-exporter logrotate
Praefect (Gitaly Cluster)
对于 Gitaly Cluster 设置,您必须通过使用优雅重载来部署和升级 Praefect。
{{< alert type=”note” >}}
升级过程尝试优雅地交接到新的 Praefect 进程。在升级前启动的现有长时间运行的 Git 请求可能会随着交接的发生最终被丢弃。
{{< /alert >}}
{{< alert type=”note” >}}
本节专注于 Praefect 组件,而不是其所需的 PostgreSQL 数据库。极狐GitLab Linux 软件包不提供高可用,因此 Praefect 数据库没有零停机支持。需要第三方数据库解决方案来避免停机。
{{< /alert >}}
不过,Praefect 的一个额外步骤是它还需要运行其数据库迁移以升级其数据。迁移只需要在一个 Praefect 节点上运行,以避免冲突。最佳做法是选择一个节点作为部署节点。这个目标节点将配置为运行迁移,而其他节点则不运行。我们将在下面称之为Praefect 部署节点:
-
在Praefect 部署节点上:
-
在
/etc/gitlab/skip-auto-reconfigure
创建一个空文件。这可以防止升级运行gitlab-ctl reconfigure
,默认情况下会自动停止极狐GitLab,运行所有数据库迁移并重新启动极狐GitLab:sudo touch /etc/gitlab/skip-auto-reconfigure
-
确保在
/etc/gitlab/gitlab.rb
中设置praefect['auto_migrate'] = true
以运行数据库迁移。 -
运行
reconfigure
命令以获取最新代码、应用 Praefect 数据库迁移并优雅重载:sudo gitlab-ctl reconfigure
-
-
在所有其余 Praefect 节点上:
-
在
/etc/gitlab/skip-auto-reconfigure
创建一个空文件。这可以防止升级运行gitlab-ctl reconfigure
,默认情况下会自动停止极狐GitLab,运行所有数据库迁移并重新启动极狐GitLab:sudo touch /etc/gitlab/skip-auto-reconfigure
-
确保在
/etc/gitlab/gitlab.rb
中设置praefect['auto_migrate'] = false
,以防止reconfigure
自动运行数据库迁移。 -
运行
reconfigure
命令以获取最新代码并优雅重载:sudo gitlab-ctl reconfigure
-
-
最后,虽然 Praefect 将优雅地重载,但任何已部署的其他组件仍需要重新启动。 在所有Praefect 节点上:
# 获取除 Praefect 外其他已部署组件的列表 sudo gitlab-ctl status # 重新启动除 Praefect 外的每个组件。示例以 Consul、节点导出器和日志轮换为例 sudo gitlab-ctl restart consul node-exporter logrotate
Rails
作为 Web 服务器的 Rails 主要包括 Puma、Workhorse 和 NGINX。
每个组件在进行实时升级时都有不同的行为。虽然 Puma 可以允许优雅重载,但 Workhorse 不允许。最佳做法是通过其他方式优雅地排空节点,例如通过使用负载均衡器。您也可以通过使用节点上的 NGINX,通过其优雅关闭功能来实现。这一节解释了 NGINX 方法。
除了上述内容之外,Rails 是需要执行主要数据库迁移的地方。与 Praefect 一样,最佳做法是使用部署节点。如果当前使用 PgBouncer,它也需要绕过,因为 Rails 在尝试运行迁移时使用顾问锁来防止在同一数据库上运行并发迁移。这些锁不跨事务共享,导致 ActiveRecord::ConcurrentMigrationError
和其他问题在使用 PgBouncer 在事务池模式下运行数据库迁移时。
-
在Rails 部署节点上:
-
优雅地排空节点流量。您可以通过多种方式实现,但一种方法是通过发送
QUIT
信号给 NGINX 然后停止服务来实现。 例如,您可以通过以下 shell 脚本来实现:# 发送 QUIT 信号给 NGINX 主进程以排空并退出 NGINX_PID=$(cat /var/opt/gitlab/nginx/nginx.pid) kill -QUIT $NGINX_PID # 等待排空完成 while kill -0 $NGINX_PID 2>/dev/null; do sleep 1; done # 停止 NGINX 服务以防止自动重启 gitlab-ctl stop nginx
-
在
/etc/gitlab/skip-auto-reconfigure
创建一个空文件。这可以防止升级运行gitlab-ctl reconfigure
,默认情况下会自动停止极狐GitLab,运行所有数据库迁移并重新启动极狐GitLab:sudo touch /etc/gitlab/skip-auto-reconfigure
- 在
/etc/gitlab/gitlab.rb
配置文件中设置gitlab_rails['auto_migrate'] = true
来配置运行常规迁移。- 如果部署节点当前通过 PgBouncer 到达数据库,则必须绕过它并直接连接到数据库领导者以运行迁移。
- 要找到数据库领导者,您可以在任何数据库节点上运行以下命令 -
sudo gitlab-ctl patroni members
。
-
运行常规迁移并获取最新代码:
sudo SKIP_POST_DEPLOYMENT_MIGRATIONS=true gitlab-ctl reconfigure
- 现在将此节点保留下来,稍后您将返回运行部署后迁移。
-
-
在每个其他 Rails 节点上按顺序:
-
优雅地排空节点流量。您可以通过多种方式实现,但一种方法是通过发送
QUIT
信号给 NGINX 然后停止服务来实现。 例如,您可以通过以下 shell 脚本来实现:# 发送 QUIT 信号给 NGINX 主进程以排空并退出 NGINX_PID=$(cat /var/opt/gitlab/nginx/nginx.pid) kill -QUIT $NGINX_PID # 等待排空完成 while kill -0 $NGINX_PID 2>/dev/null; do sleep 1; done # 停止 NGINX 服务以防止自动重启 gitlab-ctl stop nginx
-
在
/etc/gitlab/skip-auto-reconfigure
创建一个空文件。这可以防止升级运行gitlab-ctl reconfigure
,默认情况下会自动停止极狐GitLab,运行所有数据库迁移并重新启动极狐GitLab:sudo touch /etc/gitlab/skip-auto-reconfigure
-
确保在
/etc/gitlab/gitlab.rb
中设置gitlab_rails['auto_migrate'] = false
,以防止reconfigure
自动运行数据库迁移。 -
运行
reconfigure
命令以获取最新代码并重新启动:sudo gitlab-ctl reconfigure sudo gitlab-ctl restart
-
-
在Rails 部署节点上运行部署后迁移:
- 确保部署节点仍然直接指向数据库领导者。如果节点当前通过 PgBouncer 到达数据库,则必须绕过它并直接连接到数据库领导者以运行迁移。
- 要找到数据库领导者,您可以在任何数据库节点上运行以下命令 -
sudo gitlab-ctl patroni members
。
- 要找到数据库领导者,您可以在任何数据库节点上运行以下命令 -
-
运行部署后迁移:
sudo gitlab-rake db:migrate
- 将配置恢复正常,通过在
/etc/gitlab/gitlab.rb
配置文件中设置gitlab_rails['auto_migrate'] = false
。- 如果使用 PgBouncer,请确保将数据库配置重新指向它
-
再次运行重新配置以重新应用正常配置并重新启动:
sudo gitlab-ctl reconfigure sudo gitlab-ctl restart
- 确保部署节点仍然直接指向数据库领导者。如果节点当前通过 PgBouncer 到达数据库,则必须绕过它并直接连接到数据库领导者以运行迁移。
Sidekiq
Sidekiq 采用与其他组件相同的底层过程进行无停机升级。
在每个组件节点上按顺序运行以下步骤以执行升级:
-
在
/etc/gitlab/skip-auto-reconfigure
创建一个空文件。这可以防止升级运行gitlab-ctl reconfigure
,默认情况下会自动停止极狐GitLab,运行所有数据库迁移并重新启动极狐GitLab:sudo touch /etc/gitlab/skip-auto-reconfigure
-
运行
reconfigure
命令以获取最新代码并重新启动:sudo gitlab-ctl reconfigure sudo gitlab-ctl restart
多节点 / 高可用部署与 Geo
{{< details >}}
- Tier: 专业版、旗舰版
- Offering: 极狐GitLab私有化部署
{{< /details >}}
本节描述了升级实时极狐GitLab环境与 Geo 部署所需的步骤。
总体而言,这种方法与正常过程大致相同,除了每个次要站点需要额外的步骤。所需的顺序是首先升级主站点,然后是次要站点。在所有次要站点更新后,您还必须在主站点上运行任何部署后迁移。
{{< alert type=”note” >}}
同样的要求和注意事项适用于升级实时极狐GitLab环境与 Geo。
{{< /alert >}}
主站点
主站点的升级过程与正常过程相同,唯一的例外是在所有次要站点更新后再运行部署后迁移。
按照描述的步骤完成主站点的步骤,但停止在 Rails 节点步骤的部署后迁移。
次要站点
任何次要站点的升级过程遵循正常过程的步骤,除了 Rails 节点需要几个额外步骤,如下所述。
要升级站点,请按照正常过程步骤进行,直到 Rails 节点,而是按照以下步骤进行:
Rails
-
在Rails 部署节点上:
-
优雅地排空节点流量。您可以通过多种方式实现,但一种方法是通过发送
QUIT
信号给 NGINX 然后停止服务来实现。 例如,您可以通过以下 shell 脚本来实现:# 发送 QUIT 信号给 NGINX 主进程以排空并退出 NGINX_PID=$(cat /var/opt/gitlab/nginx/nginx.pid) kill -QUIT $NGINX_PID # 等待排空完成 while kill -0 $NGINX_PID 2>/dev/null; do sleep 1; done # 停止 NGINX 服务以防止自动重启 gitlab-ctl stop nginx
-
停止 Geo 日志光标进程以确保其切换到其他节点:
gitlab-ctl stop geo-logcursor
-
在
/etc/gitlab/skip-auto-reconfigure
创建一个空文件。这可以防止升级运行gitlab-ctl reconfigure
,默认情况下会自动停止极狐GitLab,运行所有数据库迁移并重新启动极狐GitLab:sudo touch /etc/gitlab/skip-auto-reconfigure
-
如果主站点 Rails 节点与次要站点 Rails 节点不同,请将
/etc/gitlab/gitlab-secrets.json
文件从主站点 Rails 节点复制到次要站点 Rails 节点。该文件在一个站点的所有节点上必须相同。 -
确保没有配置自动运行迁移,通过在
/etc/gitlab/gitlab.rb
配置文件中设置gitlab_rails['auto_migrate'] = false
和geo_secondary['auto_migrate'] = false
。 -
运行
reconfigure
命令以获取最新代码并重新启动:sudo gitlab-ctl reconfigure sudo gitlab-ctl restart
-
运行常规 Geo 跟踪迁移并获取最新代码:
sudo SKIP_POST_DEPLOYMENT_MIGRATIONS=true gitlab-rake db:migrate:geo
-
-
在每个其他 Rails 节点上按顺序:
-
优雅地排空节点流量。您可以通过多种方式实现,但一种方法是通过发送
QUIT
信号给 NGINX 然后停止服务来实现。 例如,您可以通过以下 shell 脚本来实现:# 发送 QUIT 信号给 NGINX 主进程以排空并退出 NGINX_PID=$(cat /var/opt/gitlab/nginx/nginx.pid) kill -QUIT $NGINX_PID # 等待排空完成 while kill -0 $NGINX_PID 2>/dev/null; do sleep 1; done # 停止 NGINX 服务以防止自动重启 gitlab-ctl stop nginx
-
停止 Geo 日志光标进程以确保其切换到其他节点:
gitlab-ctl stop geo-logcursor
-
在
/etc/gitlab/skip-auto-reconfigure
创建一个空文件。这可以防止升级运行gitlab-ctl reconfigure
,默认情况下会自动停止极狐GitLab,运行所有数据库迁移并重新启动极狐GitLab:sudo touch /etc/gitlab/skip-auto-reconfigure
-
确保没有配置自动运行迁移,通过在
/etc/gitlab/gitlab.rb
配置文件中设置gitlab_rails['auto_migrate'] = false
和geo_secondary['auto_migrate'] = false
。 -
运行
reconfigure
命令以获取最新代码并重新启动:sudo gitlab-ctl reconfigure sudo gitlab-ctl restart
-
Sidekiq
按照主要流程,接下来需要完成的就是升级 Sidekiq。
以在主要部分中描述的相同方式升级 Sidekiq。
部署后迁移
最后,返回主站点并完成升级,运行部署后迁移:
-
在主站点的Rails 部署节点上运行部署后迁移:
- 确保部署节点仍然直接指向数据库领导者。如果节点当前通过 PgBouncer 到达数据库,则必须绕过它并直接连接到数据库领导者以运行迁移。
- 要找到数据库领导者,您可以在任何数据库节点上运行以下命令 -
sudo gitlab-ctl patroni members
。
- 要找到数据库领导者,您可以在任何数据库节点上运行以下命令 -
-
运行部署后迁移:
sudo gitlab-rake db:migrate
-
验证 Geo 配置和依赖关系:
sudo gitlab-rake gitlab:geo:check
- 将配置恢复正常,通过在
/etc/gitlab/gitlab.rb
配置文件中设置gitlab_rails['auto_migrate'] = false
。- 如果使用 PgBouncer,请确保将数据库配置重新指向它
-
再次运行重新配置以重新应用正常配置并重新启动:
sudo gitlab-ctl reconfigure sudo gitlab-ctl restart
- 确保部署节点仍然直接指向数据库领导者。如果节点当前通过 PgBouncer 到达数据库,则必须绕过它并直接连接到数据库领导者以运行迁移。
-
在次要站点的Rails 部署节点上运行部署后 Geo 跟踪迁移:
-
运行部署后 Geo 跟踪迁移:
sudo gitlab-rake db:migrate:geo
-
验证 Geo 状态:
sudo gitlab-rake geo:status
-