- 要求
- 概览
- 设置 Omnibus 实例
- 设置 Kubernetes 集群
- 收集信息
- 配置主要数据库
- 将 chart 部署为 Geo Primary
- 设置 Geo Primary 实例
- 配置次要数据库
- 将 secret 从主集群复制到次要集群
- 将 chart 部署为 Geo Secondary
- 通过 Primary 实例添加 Secondary Geo 实例
- 确认操作状态
GitLab Geo
GitLab Geo 提供了拥有只读的地理分布式应用程序部署的能力。
在本指南中,两个集群具有相同的外部 URL。
要求
为了一起使用 GitLab Geo 与 GitLab Helm chart,必须满足以下要求:
- 使用外部 PostgreSQL 服务,因为 chart 中包含的 PostgresSQL 未暴露于外部网络,或者当前具有复制所需的 WAL 支持。
- 提供的数据库必须:
- 支持复制。
- 次要数据库只需要由次要应用程序实例部署访问。
- 支持主要实例和次要实例之间的 SSL。
- 所有次要实例都必须可以通过 HTTPS 访问主要应用程序实例。主实例必须可以通过 HTTPS 访问次要应用程序实例。
概览
本指南将使用 2 个 Omnibus GitLab 实例,仅配置所需的 PostgreSQL 服务,以及 2 个 GitLab Helm chart 的部署。 它旨在成为_最小_所需的配置。本文档目前不包括从应用程序到数据库的 SSL、对其它数据库提供程序的支持或将 secondary 实例提升为 primary 实例。
应按顺序遵循以下大纲:
- 设置 Omnibus 实例
- 设置 Kubernetes 集群
- 收集信息
- 配置主要数据库
- 将 chart 部署为 Geo Primary
- 设置 Geo Primary 实例
- 配置次要数据库
- 将 secret 从主集群复制到次要集群
- 将 chart 部署为 Geo Secondary
- 通过 Primary 实例添加 Secondary Geo 实例
- 确认操作状态
设置 Omnibus 实例
对于此过程,需要两个实例。一个是主要的,另一个是次要的。您可以使用任何本地或来自云提供商的机器基础设施提供商。
请记住,通信需要:
- 在两个数据库实例之间进行复制。
- 在每个数据库实例和它们各自的 Kubernetes 部署之间:
- 主要实例需要暴露 TCP 端口
5432
。 - 次要实例需要暴露 TCP 端口
5432
和5431
。
- 主要实例需要暴露 TCP 端口
安装 Omnibus GitLab 支持的操作系统,然后在其上安装 Omnibus GitLab。安装时不要提供 EXTERNAL_URL
环境变量,因为我们将在重新配置包之前提供一个最小的配置文件。
一旦安装了操作系统和 GitLab 包,就可以为将要使用的服务创建配置。 在我们这样做之前,必须收集信息。
设置 Kubernetes 集群
对于此过程,应使用两个 Kubernetes 集群,可以来自任何提供商,内部自由部署或云提供商。
请记住,通信需要:
- 对于相应的数据库实例:
- 主要实例出站流量到 TCP
5432
。 - 次要实例出站流量到 TCP
5432
和5431
.
- 主要实例出站流量到 TCP
- 通过 HTTPS 在两个 Kubernetes Ingress 之间。
配置的每个集群都应该具有:
- 足够的资源来支持这些 chart 的基础安装。
- 可以访问持久存储:
收集信息
要继续进行配置,需要从各种来源收集以下信息。收集这些,并做笔记以供在本文档的其余部分使用。
- 主要数据库:
- IP 地址
- 主机名(可选)
- 次要数据库:
- IP 地址
- 主机名(可选)
- 主要集群:
- 节点 IP 地址
- 外部 URL
- 内部 URL
- 次要集群:
- 节点 IP 地址
- 内部 URL
- 数据库密码(必须预先确定密码)
-
gitlab
(在postgresql['sql_user_password']
、global.psql.password
中使用) -
gitlab_geo
(在geo_postgresql['sql_user_password']
、global.geo.psql.password
中使用) -
gitlab_replicator
(复制时需要)
-
- 您的 GitLab 许可证文件
每个集群的内部 URL 必须是集群唯一的,以便所有集群都可以向所有其他集群发出请求。例如:
- 所有集群的外部 URL:
https://gitlab.example.com
- 主要集群的内部 URL:
https://london.gitlab.example.com
- 次要集群的内部 URL:
https://shanghai.gitlab.example.com
本指南不包括设置 DNS。
gitlab
和 gitlab_geo
数据库用户密码需要以两种形式存在:裸密码和 PostgreSQL 哈希密码。获取哈希形式,请在 Omnibus 实例之一上执行以下命令,这将要求您输入并确认密码,然后输出适当的哈希值,需要您记录。
gitlab-ctl pg-password-md5 gitlab
gitlab-ctl pg-password-md5 gitlab_geo
配置主要数据库
本节将在主 Omnibus GitLab 实例上执行。
要配置主数据库实例的 Omnibus GitLab,我们将从这个示例配置开始工作。
### Geo Primary
external_url 'http://gitlab-primary.example.com'
roles ['geo_primary_role']
# The unique identifier for the Geo node.
gitlab_rails['geo_node_name'] = 'gitlab-primary.example.com'
gitlab_rails['auto_migrate'] = false
## turn off everything but the DB
sidekiq['enable']=false
puma['enable']=false
gitlab_workhorse['enable']=false
nginx['enable']=false
geo_logcursor['enable']=false
grafana['enable']=false
gitaly['enable']=false
redis['enable']=false
prometheus_monitoring['enable'] = false
## Configure the DB for network
postgresql['enable'] = true
postgresql['listen_address'] = '0.0.0.0'
postgresql['sql_user_password'] = 'gitlab_user_password_hash'
# !! CAUTION !!
# This list of CIDR addresses should be customized
# - primary application deployment
# - secondary database instance(s)
postgresql['md5_auth_cidr_addresses'] = ['0.0.0.0/0']
我们需要更换以下几项:
-
external_url
必须更新以反映我们的主实例的主机名。 -
gitlab_rails['geo_node_name']
必须替换为节点的唯一名称。 -
gitlab_user_password_hash
必须替换为gitlab
密码的哈希形式。 -
postgresql['md5_auth_cidr_addresses']
可以更新为一个显式 IP 地址列表,或 CIDR 表示法中的地址块。
md5_auth_cidr_addresses
应采用以下形式 ['127.0.0.1/24','10.41.0.0/16']
。在此列表中包含 127.0.0.1
很重要,因为 Omnibus GitLab 中的自动化将使用它进行连接。此列表中的地址应包括次要数据库的 IP 地址(而非主机名)以及主 Kubernetes 集群的所有节点。 可以_保留为 ['0.0.0.0/0']
,但是_这不是最佳实践。
准备好上述配置后:
- 将内容放入
/etc/gitlab/gitlab.rb
- 运行
gitlab-ctl reconfigure
。如果您在服务未侦听 TCP 方面遇到任何问题,请尝试直接使用gitlab-ctl restart postgresql
重新启动它。 - 运行
gitlab-ctl set-replication-password
以设置gitlab_replicator
用户的密码。 -
检索主数据库服务器的公共证书,这是次要数据库能够复制所必需的(保存此输出)。
cat ~gitlab-psql/data/server.crt
将 chart 部署为 Geo Primary
本节将在主 Kubernetes 集群上执行。
为了将此 chart 部署为 Geo Primary,我们将开始 从此示例配置。
-
我们需要创建一个包含数据库密码的 secret,供 chart 使用。 将下面的
PASSWORD
替换为gitlab
数据库用户的密码。kubectl --namespace gitlab create secret generic geo --from-literal=postgresql-password=PASSWORD
-
根据示例配置创建一个
primary.yaml
文件并更新配置以反映正确的值:### Geo Primary global: # See docs.gitlab.com/charts/charts/globals # Configure host & domain hosts: domain: example.com # configure DB connection psql: host: geo-1.db.example.com port: 5432 password: secret: geo key: postgresql-password # configure geo (primary) geo: nodeName: London Office enabled: true role: primary # External DB, disable postgresql: install: false
- global.hosts.domain
- global.psql.host
- global.geo.nodeName 必需与管理中心的 Geo 站点的名称字段匹配。
- 还可以进行任何其它配置,例如:
-
使用此配置部署 chart。
helm upgrade --install gitlab-geo gitlab-jh/gitlab --namespace gitlab -f primary.yaml
这里假设您使用的是gitlab
命名空间,如果您想使用不同的命名空间,您还应该在本文档的其余部分将其替换为--namespace gitlab
。 -
等待部署完成,应用程序上线。一旦应用程序可访问,请登录。
-
登录极狐GitLab,然后激活您的极狐GitLab 订阅。
此步骤是 Geo 运行所必需的。
设置 Geo Primary 实例
现在已经部署了 chart,并上传了许可证,我们可以将其配置为主实例。我们将通过 Task Runner Pod 执行此操作。
-
找到 Toolbox Pod
kubectl --namespace gitlab get pods -lapp=toolbox
-
使用
kubectl exec
运行gitlab-rake geo:set_primary_node
kubectl --namespace gitlab exec -ti gitlab-geo-toolbox-XXX -- gitlab-rake geo:set_primary_node
-
使用 Rails runner 命令设置主站点的内部 URL。将
https://primary.gitlab.example.com
替换为实际的内部 URL:kubectl --namespace gitlab exec -ti gitlab-geo-toolbox-XXX -- gitlab-rails runner "GeoNode.primary_node.update!(internal_url: 'https://primary.gitlab.example.com'"
-
检查 Geo 配置的状态
kubectl --namespace gitlab exec -ti gitlab-geo-toolbox-XXX -- gitlab-rake gitlab:geo:check
您应该会看到类似于以下内容的输出:
WARNING: This version of GitLab depends on gitlab-shell 10.2.0, but you're running Unknown. Please update gitlab-shell. Checking Geo ... GitLab Geo is available ... yes GitLab Geo is enabled ... yes GitLab Geo secondary database is correctly configured ... not a secondary node Database replication enabled? ... not a secondary node Database replication working? ... not a secondary node GitLab Geo HTTP(S) connectivity ... not a secondary node HTTP/HTTPS repository cloning is enabled ... yes Machine clock is synchronized ... Exception: getaddrinfo: Servname not supported for ai_socktype Git user has default SSH configuration? ... yes OpenSSH configured to use AuthorizedKeysCommand ... no Reason: Cannot find OpenSSH configuration file at: /assets/sshd_config Try fixing it: If you are not using our official docker containers, make sure you have OpenSSH server installed and configured correctly on this system For more information see: doc/administration/operations/fast_ssh_key_lookup.md GitLab configured to disable writing to authorized_keys file ... yes GitLab configured to store new projects in hashed storage? ... yes All projects are in hashed storage? ... yes Checking Geo ... Finished
- 不要担心
Exception: getaddrinfo: Servname not supported for ai_socktype
,因为 Kubernetes 容器将无法访问主机时钟。这属于正常情况。 -
OpenSSH configured to use AuthorizedKeysCommand ... no
是期待的输出。此 Rake 任务检查本地 SSH 服务器,它实际上存在于gitlab-shell
chart 中,部署在其它地方,并且已经正确配置。
- 不要担心
配置次要数据库
本节将在次要 Omnibus GitLab 实例上执行。
要配置辅助数据库实例的 Omnibus GitLab,我们将从这个示例配置开始工作。
### Geo Secondary
# external_url must match the Primary cluster's external_url
external_url 'http://gitlab-secondary.example.com'
roles ['geo_secondary_role']
gitlab_rails['enable'] = true
# The unique identifier for the Geo node.
gitlab_rails['geo_node_name'] = 'gitlab-secondary.example.com'
gitlab_rails['auto_migrate'] = false
geo_secondary['auto_migrate'] = false
## turn off everything but the DB
sidekiq['enable']=false
puma['enable']=false
gitlab_workhorse['enable']=false
nginx['enable']=false
geo_logcursor['enable']=false
grafana['enable']=false
gitaly['enable']=false
redis['enable']=false
prometheus_monitoring['enable'] = false
## Configure the DBs for network
postgresql['enable'] = true
postgresql['listen_address'] = '0.0.0.0'
postgresql['sql_user_password'] = 'gitlab_user_password_hash'
# !! CAUTION !!
# This list of CIDR addresses should be customized
# - secondary application deployment
# - secondary database instance(s)
postgresql['md5_auth_cidr_addresses'] = ['0.0.0.0/0']
geo_postgresql['listen_address'] = '0.0.0.0'
geo_postgresql['sql_user_password'] = 'gitlab_geo_user_password_hash'
# !! CAUTION !!
# This list of CIDR addresses should be customized
# - secondary application deployment
# - secondary database instance(s)
geo_postgresql['md5_auth_cidr_addresses'] = ['0.0.0.0/0']
gitlab_rails['db_password']='gitlab_user_password'
我们需要更换以下几项:
-
gitlab_rails['geo_node_name']
必须替换为您节点的唯一名称。 -
gitlab_user_password_hash
必须替换为gitlab
密码的哈希形式。 -
postgresql['md5_auth_cidr_addresses']
应该更新为显式 IP 地址列表,或 CIDR 表示法中的地址块。 -
gitlab_geo_user_password_hash
必须替换为gitlab_geo
密码的哈希形式。 -
geo_postgresql['md5_auth_cidr_addresses']
应该更新为显式 IP 地址列表,或 CIDR 表示法中的地址块。 -
gitlab_user_password
必须更新,在这里使用是为了让 Omnibus GitLab 自动化 PostgreSQL 配置。
md5_auth_cidr_addresses
应采用 ['127.0.0.1/24','10.41.0.0/16']
形式。在此列表中包含 127.0.0.1
很重要,因为 Omnibus GitLab 中的自动化将使用它进行连接。此列表中的地址应包括 Secondary Kubernetes 集群的所有节点的 IP 地址。可以_保留为['0.0.0.0/0']
,但是_这不是最佳实践。
准备好上述配置后:
-
检查与 primary 节点的 PostgreSQL 服务器的 TCP 连接:
openssl s_client -connect <primary_node_ip>:5432 </dev/null
输出应显示以下内容:
CONNECTED(00000003) write:errno=0
如果此步骤失败,您可能使用了错误的 IP 地址,或者防火墙可能阻止访问服务器。检查 IP 地址,密切注意公共地址和私有地址之间的区别,并确保在存在防火墙的情况下,允许 secondary 节点在端口 5432 上连接到 primary 节点。 - 将内容放入
/etc/gitlab/gitlab.rb
- 运行
gitlab-ctl reconfigure
。 如果您在服务未侦听 TCP 方面遇到任何问题,请尝试直接使用gitlab-ctl restart postgresql
重新启动它。 - 将上面的主数据库的证书内容放入
primary.crt
。 -
在 secondary 节点上设置 PostgreSQL TLS 验证:
安装
primary.crt
文件:install \ -D \ -o gitlab-psql \ -g gitlab-psql \ -m 0400 \ -T primary.crt ~gitlab-psql/.postgresql/root.crt
PostgreSQL 现在只会在验证 TLS 连接时识别确切的证书。该证书只能由有权访问私钥的人复制,该私钥仅存在于 primary 节点上。
-
测试
gitlab-psql
用户可以连接到 primary 节点的数据库(默认的 Omnibus 数据库名称是gitlabhq_production
):sudo \ -u gitlab-psql /opt/gitlab/embedded/bin/psql \ --list \ -U gitlab_replicator \ -d "dbname=gitlabhq_production sslmode=verify-ca" \ -W \ -h <primary_node_ip>
出现提示时,输入之前为
gitlab_replicator
用户收集的密码。 如果一切正常,您应该会看到 primary 节点的数据库列表。此处连接失败表示 TLS 配置不正确。确保 primary 节点上
~gitlab-psql/data/server.crt
的内容与 secondary 节点上~gitlab-psql/.postgresql/root.crt
的内容匹配 . -
复制数据库。用主数据库实例的 IP 或主机名替换
PRIMARY_DATABASE_HOST
。gitlab-ctl replicate-geo-database --slot-name=geo_2 --host=PRIMARY_DATABASE_HOST --sslmode=verify-ca
-
复制完成后,我们必须最后一次重新配置 Omnibus GitLab 以确保
pg_hba.conf
对次要数据库来说是正确的。gitlab-ctl reconfigure
将 secret 从主集群复制到次要集群
我们现在需要将一些 secret 从主 Kubernetes 部署复制到次要 Kubernetes 部署。
gitlab-geo-gitlab-shell-host-keys
gitlab-geo-rails-secret
-
gitlab-geo-registry-secret
(如果启用了 Registry 复制)
- 将您的
kubectl
上下文更改为您的主节点的上下文。 - 从主要部署中收集这些 secret。
kubectl get --namespace gitlab -o yaml secret gitlab-geo-gitlab-shell-host-keys > ssh-host-keys.yaml
kubectl get --namespace gitlab -o yaml secret gitlab-geo-rails-secret > rails-secrets.yaml
kubectl get --namespace gitlab -o yaml secret gitlab-geo-registry-secret > registry-secrets.yaml
- 将您的
kubectl
上下文更改为您的次要节点的上下文。 -
应用这些 secret
kubectl --namespace gitlab apply -f ssh-host-keys.yaml kubectl --namespace gitlab apply -f rails-secrets.yaml kubectl --namespace gitlab apply -f registry-secrets.yaml
我们现在需要创建一个包含数据库密码的 secret。将下面的密码替换为适当的值。
kubectl --namespace gitlab create secret generic geo \
--from-literal=postgresql-password=gitlab_user_password \
--from-literal=geo-postgresql-password=gitlab_geo_user_password
将 chart 部署为 Geo Secondary
本节将在 Secondary Kubernetes 集群上执行。
为了将此图表部署为 Geo Secondary,我们将开始从此示例配置 .
-
根据示例配置创建一个
secondary.yaml
文件,并更新配置以反映正确的值:## Geo Secondary global: # See docs.gitlab.com/charts/charts/globals # Configure host & domain hosts: hostSuffix: secondary domain: example.com # configure DB connection psql: host: geo-2.db.example.com port: 5432 password: secret: geo key: postgresql-password # configure geo (secondary) geo: enabled: true role: secondary nodeName: secondary.example.com psql: host: geo-2.db.example.com port: 5431 password: secret: geo key: geo-postgresql-password # External DB, disable postgresql: install: false
global.hosts.domain
global.psql.host
global.geo.psql.host
- 还可以进行任何其它配置,例如:
- 对于外部数据库,
global.psql.host
是次要的只读数据库,而global.geo.psql.host
是跟踪数据库。
-
使用此配置部署 chart
helm upgrade --install gitlab-geo gitlab-jh/gitlab --namespace gitlab -f secondary.yaml
-
等待部署完成,应用程序上线。
通过 Primary 实例添加 Secondary Geo 实例
现在两个数据库都已配置并部署了应用程序,我们必须告诉主节点存在次要节点:
- 访问 primary 实例。
- 在左侧边栏上,展开最顶部的向下箭头()。
- 选择 管理中心。
- 选择 Geo > 添加站点。
- 添加 secondary 实例。使用完整的极狐GitLab URL 作为实例 URL。
- 使用
global.geo.nodeName
输入名称。这些值必须始终完全匹配,逐个字符。 - 输入内部 URL,例如
https://shanghai.gitlab.example.com
。 - 或者,选择 secondary 实例应复制哪些组或存储分片。留空以复制所有内容。
- 选择 添加节点。
添加到管理面板后,次要 实例将在称为 回填 的过程中自动开始从 主要 实例复制丢失的数据。 同时,primary 实例将开始通知每个 secondary 实例任何更改,以便 secondary 实例可以立即对这些通知采取行动。
确认操作状态
最后一步是在完全配置后,通过 Task Runner Pod 验证 Secondary 实例上的 Geo 复制状态。
-
找到 Toolbox Pod
kubectl --namespace gitlab get pods -lapp=toolbox
-
使用
kubectl exec
进入 Podkubectl --namespace gitlab exec -ti gitlab-geo-toolbox-XXX -- bash -l
-
检查 Geo 配置的状态
gitlab-rake gitlab:geo:check
您应该会看到类似于以下内容的输出:
WARNING: This version of GitLab depends on gitlab-shell 10.2.0, but you're running Unknown. Please update gitlab-shell. Checking Geo ... GitLab Geo is available ... yes GitLab Geo is enabled ... yes GitLab Geo secondary database is correctly configured ... yes Database replication enabled? ... yes Database replication working? ... yes GitLab Geo HTTP(S) connectivity ... * Can connect to the primary node ... yes HTTP/HTTPS repository cloning is enabled ... yes Machine clock is synchronized ... Exception: getaddrinfo: Servname not supported for ai_socktype Git user has default SSH configuration? ... yes OpenSSH configured to use AuthorizedKeysCommand ... no Reason: Cannot find OpenSSH configuration file at: /assets/sshd_config Try fixing it: If you are not using our official docker containers, make sure you have OpenSSH server installed and configured correctly on this system For more information see: doc/administration/operations/fast_ssh_key_lookup.md GitLab configured to disable writing to authorized_keys file ... yes GitLab configured to store new projects in hashed storage? ... yes All projects are in hashed storage? ... yes Checking Geo ... Finished
- 不要担心
Exception: getaddrinfo: Servname not supported for ai_socktype
,因为 Kubernetes 容器将无法访问主机时钟。这属于正常情况。 -
OpenSSH configured to use AuthorizedKeysCommand ... no
是期待的输出。此 Rake 任务检查本地 SSH 服务器,它实际上存在于gitlab-shell
chart 中,部署在其它地方,并且已经正确配置。
- 不要担心