GitLab Geo

caution以下指南描述了如何使用统一的 URL 设置 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 实例。

应按顺序遵循以下大纲:

  1. 设置 Omnibus 实例
  2. 设置 Kubernetes 集群
  3. 收集信息
  4. 配置主要数据库
  5. 将 chart 部署为 Geo Primary
  6. 设置 Geo Primary 实例
  7. 配置次要数据库
  8. 将 secret 从主集群复制到次要集群
  9. 将 chart 部署为 Geo Secondary
  10. 通过 Primary 实例添加 Secondary Geo 实例
  11. 确认操作状态

设置 Omnibus 实例

对于此过程,需要两个实例。一个是主要的,另一个是次要的。您可以使用任何本地或来自云提供商的机器基础设施提供商。

请记住,通信需要:

  • 在两个数据库实例之间进行复制。
  • 在每个数据库实例和它们各自的 Kubernetes 部署之间:
    • 主要实例需要暴露 TCP 端口 5432
    • 次要实例需要暴露 TCP 端口 54325431

安装 Omnibus GitLab 支持的操作系统,然后在其上安装 Omnibus GitLab。安装时不要提供 EXTERNAL_URL 环境变量,因为我们将在重新配置包之前提供一个最小的配置文件。

一旦安装了操作系统和 GitLab 包,就可以为将要使用的服务创建配置。 在我们这样做之前,必须收集信息。

设置 Kubernetes 集群

对于此过程,应使用两个 Kubernetes 集群,可以来自任何提供商,内部自由部署或云提供商。

请记住,通信需要:

  • 对于相应的数据库实例:
    • 主要实例出站流量到 TCP 5432
    • 次要实例出站流量到 TCP 54325431.
  • 通过 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。

gitlabgitlab_geo 数据库用户密码需要以两种形式存在:裸密码和 PostgreSQL 哈希密码。获取哈希形式,请在 Omnibus 实例之一上执行以下命令,这将要求您输入并确认密码,然后输出适当的哈希值,需要您记录。

  1. gitlab-ctl pg-password-md5 gitlab
  2. 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'],但是_这不是最佳实践

准备好上述配置后:

  1. 将内容放入/etc/gitlab/gitlab.rb
  2. 运行 gitlab-ctl reconfigure。如果您在服务未侦听 TCP 方面遇到任何问题,请尝试直接使用 gitlab-ctl restart postgresql 重新启动它。
  3. 运行 gitlab-ctl set-replication-password 以设置 gitlab_replicator 用户的密码。
  4. 检索主数据库服务器的公共证书,这是次要数据库能够复制所必需的(保存此输出)。

    cat ~gitlab-psql/data/server.crt
    

将 chart 部署为 Geo Primary

本节将在主 Kubernetes 集群上执行。

为了将此 chart 部署为 Geo Primary,我们将开始 从此示例配置

  1. 我们需要创建一个包含数据库密码的 secret,供 chart 使用。 将下面的 PASSWORD 替换为 gitlab 数据库用户的密码。

    kubectl --namespace gitlab create secret generic geo --from-literal=postgresql-password=PASSWORD
    
  2. 根据示例配置创建一个 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
    
  3. 使用此配置部署 chart。

    helm upgrade --install gitlab-geo gitlab-jh/gitlab --namespace gitlab -f primary.yaml
    
    note这里假设您使用的是 gitlab 命名空间,如果您想使用不同的命名空间,您还应该在本文档的其余部分将其替换为 --namespace gitlab
  4. 等待部署完成,应用程序上线。一旦应用程序可访问,请登录。

  5. 登录极狐GitLab,然后激活您的极狐GitLab 订阅

    note此步骤是 Geo 运行所必需的。

设置 Geo Primary 实例

现在已经部署了 chart,并上传了许可证,我们可以将其配置为主实例。我们将通过 Task Runner Pod 执行此操作。

  1. 找到 Toolbox Pod

    kubectl --namespace gitlab get pods -lapp=toolbox
    
  2. 使用 kubectl exec 运行 gitlab-rake geo:set_primary_node

    kubectl --namespace gitlab exec -ti gitlab-geo-toolbox-XXX -- gitlab-rake geo:set_primary_node
    
  3. 使用 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'"
    
  4. 检查 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'],但是_这不是最佳实践

准备好上述配置后:

  1. 检查与 primary 节点的 PostgreSQL 服务器的 TCP 连接:

    openssl s_client -connect <primary_node_ip>:5432 </dev/null
    

    输出应显示以下内容:

    CONNECTED(00000003)
    write:errno=0
    
    note如果此步骤失败,您可能使用了错误的 IP 地址,或者防火墙可能阻止访问服务器。检查 IP 地址,密切注意公共地址和私有地址之间的区别,并确保在存在防火墙的情况下,允许 secondary 节点在端口 5432 上连接到 primary 节点。
  2. 将内容放入/etc/gitlab/gitlab.rb
  3. 运行gitlab-ctl reconfigure。 如果您在服务未侦听 TCP 方面遇到任何问题,请尝试直接使用 gitlab-ctl restart postgresql 重新启动它。
  4. 将上面的主数据库的证书内容放入primary.crt
  5. 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 节点上。

  6. 测试 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 的内容匹配 .

  7. 复制数据库。用主数据库实例的 IP 或主机名替换 PRIMARY_DATABASE_HOST

    gitlab-ctl replicate-geo-database --slot-name=geo_2 --host=PRIMARY_DATABASE_HOST --sslmode=verify-ca
    
  8. 复制完成后,我们必须最后一次重新配置 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 复制)
  1. 将您的 kubectl 上下文更改为您的主节点的上下文。
  2. 从主要部署中收集这些 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
  1. 将您的 kubectl 上下文更改为您的次要节点的上下文。
  2. 应用这些 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,我们将开始从此示例配置 .

  1. 根据示例配置创建一个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
    
  2. 使用此配置部署 chart

    helm upgrade --install gitlab-geo gitlab-jh/gitlab --namespace gitlab -f secondary.yaml
    
  3. 等待部署完成,应用程序上线。

通过 Primary 实例添加 Secondary Geo 实例

现在两个数据库都已配置并部署了应用程序,我们必须告诉主节点存在次要节点:

  1. 访问 primary 实例。
  2. 在左侧边栏上,展开最顶部的向下箭头()。
  3. 选择 管理中心
  4. 选择 Geo > 添加站点
  5. 添加 secondary 实例。使用完整的极狐GitLab URL 作为实例 URL。
  6. 使用 global.geo.nodeName 输入名称。这些值必须始终完全匹配,逐个字符。
  7. 输入内部 URL,例如 https://shanghai.gitlab.example.com
  8. 或者,选择 secondary 实例应复制哪些组或存储分片。留空以复制所有内容。
  9. 选择 添加节点

添加到管理面板后,次要 实例将在称为 回填 的过程中自动开始从 主要 实例复制丢失的数据。 同时,primary 实例将开始通知每个 secondary 实例任何更改,以便 secondary 实例可以立即对这些通知采取行动。

确认操作状态

最后一步是在完全配置后,通过 Task Runner Pod 验证 Secondary 实例上的 Geo 复制状态。

  1. 找到 Toolbox Pod

    kubectl --namespace gitlab get pods -lapp=toolbox
    
  2. 使用 kubectl exec 进入 Pod

    kubectl --namespace gitlab exec -ti gitlab-geo-toolbox-XXX -- bash -l
    
  3. 检查 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 中,部署在其它地方,并且已经正确配置。