使用外部 Gitaly 配置 chart

本文档旨在提供有关如何使用外部 Gitaly 服务配置此 Helm chart 的文档。

如果您没有配置 Gitaly,对于内部私有化部署或部署到虚拟机,请考虑使用我们的 Linux 软件包

note 外部 Gitaly services 可以由 Gitaly 节点提供,或者 Praefect 集群。

配置 Chart

禁用 gitaly chart 及其提供的 Gitaly 服务,并将其它服务指向外部服务。

您需要设置以下属性:

  • global.gitaly.enabled:设置为 false 以禁用包含的 Gitaly chart。
  • global.gitaly.external:这是一个外部 Gitaly 服务 的数组。
  • global.gitaly.authToken.secret包含身份验证令牌的 secret 的名称。
  • global.gitaly.authToken.key:secret 中的 key,包含令牌内容。

外部的极狐GitLab 服务将使用它自己实例的极狐GitLab Shell。取决于您自己的实现,您可以用 chart 中的密钥进行配置,

外部 Gitaly 服务将使用自己的 GitLab Shell 实例。 根据您的实现方式,你可以使用这个 chart 中的密钥来配置它们,或者你可以使用预定义来源的内容来配置这个 chart 的密钥。

可能需要设置以下属性:

一个完整的示例配置,带有两个外部服务(external-gitaly.yml):

global:
  gitaly:
    enabled: false
    external:
      - name: default                   # required
        hostname: node1.git.example.com # required
        port: 8075                      # optional, default shown
      - name: praefect                  # required
        hostname: ha.git.example.com    # required
        port: 2305                      # Praefect uses port 2305
        tlsEnabled: false               # optional, overrides gitaly.tls.enabled
    authToken:
      secret: external-gitaly-token     # required
      key: token                        # optional, default shown
    tls:
      enabled: false                    # optional, default shown

使用上述配置文件,并结合 gitlab.yml 的其它配置的安装示例:

helm upgrade --install gitlab gitlab-jh/gitlab  \
  -f gitlab.yml \
  -f external-gitaly.yml

多个外部 Gitaly

如果您的实现使用这些 chart 外部的多个 Gitaly 节点,您也可以定义多个主机。语法略有不同,以允许所需的复杂性。

提供了一个 示例值文件,其中显示了适当的配置集。这个值文件的内容没有通过 --set 参数正确解释,所以应该使用 -f / --values 标志传递给 Helm。

通过 TLS 连接外部 Gitaly

如果您的外部 Gitaly 服务器通过 TLS 端口侦听,您可以让您的 GitLab 实例通过 TLS 与其通信。要做到这一点,你必须:

  1. 创建包含 Gitaly 服务器证书的 Kubernetes Secret

    kubectl create secret generic gitlab-gitaly-tls-certificate --from-file=gitaly-tls.crt=<path to certificate>
    
  2. 将外部 Gitaly 服务器的证书添加到 自定义证书颁发机构 列表中 在值文件中,指定以下内容:

    global:
      certificates:
        customCAs:
          - secret: gitlab-gitaly-tls-certificate
    

    或使用 --set 将其传递给 helm upgrade 命令

    --set global.certificates.customCAs[0].secret=gitlab-gitaly-tls-certificate
    
  3. 要为所有 Gitaly 实例启用 TLS,请设置 global.gitaly.tls.enabled: true

    global:
      gitaly:
        tls:
          enabled: true
    

    要单独启用实例,请为该条目设置 tlsEnabled: true

    global:
      gitaly:
        external:
          - name: default
            hostname: node1.git.example.com
            tlsEnabled: true
    
note 您可以为此选择任何有效的 secret 名称和键,但请确保键在 customCAs 中指定的所有 secret 中是唯一的,以避免冲突,因为 secret 中的所有键都将被挂载。 您不需要提供证书的密钥,因为这是_客户端_侧。

测试极狐GitLab 可以连接到 Gitaly

为了确保极狐GitLab 可以连接到 Gitaly 服务器,您可以使用以下命令:

kubectl exec -it <toolbox-pod> -- gitlab-rake gitlab:gitaly:check

如果您正在使用有 TLS 的 Gitaly,您还需要确认极狐GitLab chart 是否信任 Gitaly 证书:

kubectl exec -it <toolbox-pod> -- echo | /usr/bin/openssl s_client -connect <gitaly-host>:<gitaly-port>

从 Gitaly chart 迁移到外部 Gitaly

如果您正在使用 Gitaly Chart 提供 Gitaly 服务,您需要将您的所有仓库迁移到外部的 Gitaly 服务,以下方法可以实现这一目的:

使用仓库存储移动 API 进行迁移

此方法:

  • 使用仓库存储移动 API 将仓库从 Gitaly chart 迁移至外部 Gitaly 服务。
  • 可以进行零宕机操作。
  • 要求外部 Gitaly 服务和 Gitaly pod 在同一个 VPC/区域中。
  • 尚未与 Praefect chart 一起测试,因此暂不支持此 chart。

步骤 1:设置外部 Gitaly 服务或 Gitaly 集群

设置外部 Gitaly外部 Gitaly 集群。作为下面步骤的一部分,您必须从您的 Chart 安装提供 Gitaly 令牌和极狐GitLab Shell 密钥:

# Get the GitLab Shell secret
kubectl get secret <release>-gitlab-shell-secret -ojsonpath='{.data.secret}' | base64 -d

# Get the Gitaly token
kubectl get secret <release>-gitaly-secret -ojsonpath='{.data.token}' | base64 -d

::Tabs

:::TabTitle Gitaly

  • 此步骤获取的 Gitaly 令牌应用于 AUTH_TOKEN 值。
  • 此步骤获取的极狐GitLab Shell 密钥应用于 shellsecret 值。

:::TabTitle Gitaly 集群

  • 此步骤获取的 Gitaly 令牌应用于 PRAEFECT_EXTERNAL_TOKEN 值。
  • 此步骤获取的极狐GitLab Shell 密钥应用于 GITLAB_SHELL_SECRET_TOKEN 值。

::EndTabs

最后,确保外部 Gitaly 服务或 Gitaly 集群的防火墙允许来自 Kubernetes pod IP 范围的流量到配置的 Gitaly 端口。

步骤 2:配置实例以使用新的 Gitaly 服务

  1. 配置极狐GitLab 以使用外部 Gitaly。如果在您的主 gitlab.yml 配置文件中有任何 Gitaly 参考,请删除它们并用以下内容创建一个新的 mixed-gitaly.yml 文件:

    如果您有之前定义好的额外的 Gitaly 存储,您需要确保 Gitaly 存储的名称和新配置文件中的名称是一致的,否则恢复操作将失败。

    如果您要配置 TLS,请参考 通过 TLS 连接外部 Gitaly部分:

    ::Tabs

    :::TabTitle Gitaly

    global:
      gitaly:
        internal:
          names:
            - default
        external:
          - name: ext-gitaly                # required
            hostname: node1.git.example.com # required
            port: 8075                      # optional, default shown
            tlsEnabled: false               # optional, overrides gitaly.tls.enabled
    

    :::TabTitle Gitaly 集群

    global:
      gitaly:
        internal:
          names:
            - default
        external:
          - name: ext-gitaly-cluster        # required
            hostname: ha.git.example.com    # required
            port: 2305                      # Praefect uses port 2305
            tlsEnabled: false               # optional, overrides gitaly.tls.enabled
    

    ::EndTabs

  2. 使用 gitlab.ymlmixed-gitaly.yml 文件应用新的配置:

    helm upgrade --install gitlab gitlab/gitlab \
      -f gitlab.yml \
      -f mixed-gitaly.yml
    
  3. 在 Toolbox pod,确保极狐GitLab 能够成功连接到外部的 Gitaly:

    kubectl exec <toolbox pod name> -it -- gitlab-rake gitlab:gitaly:check
    
  4. 确保外部 Gitaly 能够连接到 Chart 安装的实例:

    ::Tabs

    :::TabTitle Gitaly 在 Gitaly pod 中,确保 Gitaly 服务可以成功回调到极狐GitLab API:

    sudo /opt/gitlab/embedded/bin/gitaly check /var/opt/gitlab/gitaly/config.toml
    

    :::TabTitle Gitaly Cluster

    在 Praefect pod 中,确保 Praefect 服务可以成功回调到极狐GitLab API:

    # Run on Praefect nodes
    sudo /opt/gitlab/embedded/bin/praefect -config /var/opt/gitlab/praefect/config.toml dial-nodes
    

    在所有的 Gitaly 节点上,确保 Gitaly 服务可以成功回调到极狐GitLab API:

    # Run on Gitaly nodes
    sudo /opt/gitlab/embedded/bin/gitaly check /var/opt/gitlab/gitaly/config.toml
    

    ::EndTabs

步骤 3:获取 Gitaly pod IP 和主机名

如果仓库存储移动 API 获得成功,外部 Gitaly 服务需要能够使用 pod 服务主机名连接回 Gitaly pod。为了 pod 服务主机名能够被解析,我们需要将主机名添加到每个运行 Gitaly 进程的外部 Gitaly 服务的 hosts 文件中。

  1. 获取 Gitaly pod 列表和它们对应的内部 IP 地址/主机名:

    kubectl get pods -l app=gitaly -o jsonpath='{range .items[*]}{.status.podIP}{"\t"}{.spec.hostname}{"."}{.spec.subdomain}{"."}{.metadata.namespace}{".svc\n"}{end}'
    
  2. 将上一步的输出添加到每一个运行 Gitaly 进程的外部 Gitaly 服务的 /etc/hosts 文件中。
  3. 确保每个运行 Gitaly 进程的外部 Gitaly 服务能够 ping 通 Gitaly pod 的主机名:

    ping <gitaly pod hostname>
    

连接确认后,我们可以继续安排仓库存储的迁移。

步骤 4:安排仓库存储的迁移

按照移动仓库中的指示步骤来安排迁移。

步骤 5:最终配置和验证

  1. 如果您有多个 Gitaly 存储,请配置新仓库的存储
  2. 考虑生成一个包含外部 Gitaly 配置的一致性 gitlab.yml 文件以备将来之用:

    helm get values <RELEASE_NAME> -o yaml > gitlab.yml
    
  3. gitlab.yml 文件中禁用内部的 Gitaly 子 chart,将新的 默认 仓库存储指向外部 Gitaly 服务。极狐GitLab 需要默认的仓库存储

    ::Tabs

    :::TabTitle Gitaly

    global:
      gitaly:
        enabled: false                      # Disable the internal Gitaly subchart
        external:
          - name: ext-gitaly                # required
            hostname: node1.git.example.com # required
            port: 8075                      # optional, default shown
            tlsEnabled: false               # optional, overrides gitaly.tls.enabled
          - name: default                   # Add the default repository storage, use the same settings as ext-gitaly
            hostname: node1.git.example.com
            port: 8075
            tlsEnabled: false
    

    :::TabTitle Gitaly 集群

    global:
      gitaly:
        enabled: false                      # Disable the internal Gitaly subchart
        external:
          - name: ext-gitaly-cluster        # required
            hostname: ha.git.example.com    # required
            port: 2305                      # Praefect uses port 2305
            tlsEnabled: false               # optional, overrides gitaly.tls.enabled
          - name: default                   # Add the default repository storage, use the same settings as ext-gitaly-cluster
            hostname: ha.git.example.com
            port: 2305
            tlsEnabled: false
    

    ::EndTabs

  4. 应用新的配置:

    helm upgrade --install gitlab gitlab/gitlab \
      -f gitlab.yml
    
  5. 可选。在遵循获取 Gitaly pod IP 和主机名的步骤后,您可以移除为每一个外部 Gitaly /etc/hosts 文件所做的变更。
  6. 在您确认一切如期望一样正常运行后,您可以删除 Gitaly PVC:

    caution 在你多次确认一切如期望一样正常运行之前不要删除 PVC。
     kubectl delete pvc repo-data-<release>-gitaly-0
    

使用备份/恢复方法迁移

此方法:

  • 从 Gitaly chart PVC 备份您的仓库然后将其恢复到外部 Gitaly 服务。
  • 会出现宕机。
  • 尚未与 Praefect chart 一起测试,因此暂不支持此 chart。

步骤 1:获取当前极狐GitLab chart 的版本信息

在迁移过程不太可能出现问题的情况下,获取当前极狐GitLab chart 的版本信息。复制输出并将其放在一边,以防我们需要执行回滚

helm history <release> --max=1

步骤 2:设置外部 Gitaly 服务或 Gitaly 集群

设置外部 Gitaly外部 Gitaly 集群。作为下面步骤的一部分,您必须从您的 Chart 安装提供 Gitaly 令牌和极狐GitLab Shell 密钥:

# Get the GitLab Shell secret
kubectl get secret <release>-gitlab-shell-secret -ojsonpath='{.data.secret}' | base64 -d

# Get the Gitaly token
kubectl get secret <release>-gitaly-secret -ojsonpath='{.data.token}' | base64 -d

::Tabs

:::TabTitle Gitaly

  • 此步骤获取的 Gitaly 令牌应用于 AUTH_TOKEN 值。
  • 此步骤获取的极狐GitLab Shell 密钥应用于 shellsecret 值。

:::TabTitle Gitaly 集群

  • 此步骤获取的 Gitaly 令牌应用于 PRAEFECT_EXTERNAL_TOKEN 值。
  • 此步骤获取的极狐GitLab Shell 密钥应用于 GITLAB_SHELL_SECRET_TOKEN 值。

::EndTabs

步骤 3:验证在迁移期间没有 Git 变更

为了确保迁移数据的完整性,在下面的步骤中需要阻止向 Git 仓库做任何变更:

1. 开启维护模式

如果您在使用极狐GitLab 企业版(专业版或旗舰版),通过 UI、API 或者 Rails 控制台开启维护模式

kubectl exec <toolbox pod name> -it -- gitlab-rails runner 'Gitlab::CurrentSettings.update!(maintenance_mode: true)'

2. 缩放 Runner pod

如果您在使用极狐GitLab 企业版(专业版或旗舰版),您必须缩放集群中运行的极狐GitLab Runner pod 数量。这能够阻止 Runner 连接到极狐GitLab 来执行 CI/CD 作业。

如果您在使用极狐GitLab 企业版(专业版或旗舰版),此步骤是可选的因为维护模式本身就能够阻止集群中的 Runner 连接到极狐GitLab。

# Make note of the current number of replicas for Runners so we can scale up to this number later
kubectl get deploy -lapp=gitlab-gitlab-runner,release=<release> -o jsonpath='{.items[].spec.replicas}{"\n"}'

# Scale down the Runners pods to zero
kubectl scale deploy -lapp=gitlab-gitlab-runner,release=<release> --replicas=0

3. 确保没有 CI 作业在运行

在管理中心,前往CI/CD > 作业。此页面会显示您的所有作业,但是需要确认没有作业处于运行状态。在执行下一步之前您需要等待所有的作业都已完成。

4. 禁用 Sidekiq cron 作业

为了防止 Sidekiq 在迁移期间被调度和执行,执行以下命令禁用 Sidekiq cron 作业:

kubectl exec <toolbox pod name> -it -- gitlab-rails runner 'Sidekiq::Cron::Job.all.map(&:disable!)'

5. 确保没有后台作业在运行

在进行下一步之前,我们需要等待任何在队列或者在运行的作业得以完成。

  1. 在管理中心,前往监控然后选择后台作业
  2. 在 Sidekiq 仪表盘下,选择队列然后查看在线轮询
  3. 等待繁忙排队中的作业数量变为 0。

    Sidekiq background jobs

6. 缩放 Sidekiq 和 Webservice pod

缩放 Sidekiq 和 Webservice pod 以确保一致的备份。这两个服务在稍后阶段都会进行扩容:

  • 在恢复步骤中,Sidekiq pod 数量会被扩容
  • 在切换到外部 Gitaly 服务并测试链接后 Webservice pod 会被扩容
# Make note of the current number of replicas for Sidekiq and Webservice so we can scale up to this number later
kubectl get deploy -lapp=sidekiq,release=<release> -o jsonpath='{.items[].spec.replicas}{"\n"}'
kubectl get deploy -lapp=webservice,release=<release> -o jsonpath='{.items[].spec.replicas}{"\n"}'

# Scale down the Sidekiq and Webservice pods to zero
kubectl scale deploy -lapp=sidekiq,release=<release> --replicas=0
kubectl scale deploy -lapp=webservice,release=<release> --replicas=0

7. 限制到集群的外部链接

为了防止用户和外部极狐GitLab Runner 向极狐GitLab 做任何变更,我们需要限制所有不必要的连接到极狐GitLab。

一旦完成了这些步骤,在恢复完成以前,极狐GitLab 在浏览器上是不可访问的。

在迁移期间,为了保证集群能够访问外部 Gitaly 服务,我们必须将外部 Gitaly 服务的 IP 地址添加到 nginx-ingress 配置中,作为唯一的外部例外。

  1. 使用以下内容创建一个 ingress-only-allow-ext-gitaly.yml 文件:

    nginx-ingress:
      controller:
        service:
          loadBalancerSourceRanges:
           - "x.x.x.x/32"
    

    x.x.x.x 应该是外部 Gitaly 服务的 IP 地址。

  2. 使用 gitlab.ymlingress-only-allow-ext-gitaly.yml 文件应用新的配置:

    helm upgrade <release> gitlab/gitlab \
      -f gitlab.yml \
      -f ingress-only-allow-ext-gitaly.yml
    

8. 创建仓库检验和列表

在运行备份前,检查所有极狐GitLab 仓库并创建仓库校验和列表。将输出管道至文件中以便在迁移之后我们可以用 diff 进行校验:

kubectl exec <toolbox pod name> -it -- gitlab-rake gitlab:git:checksum_projects > ~/checksums-before.txt

步骤 4: 备份所有的仓库

仅为您的仓库创建备份

kubectl exec <toolbox pod name> -it -- backup-utility --skip artifacts,ci_secure_files,db,external_diffs,lfs,packages,pages,registry,terraform_state,uploads

步骤 5:配置实例使用新的 Gitaly 服务

  1. 禁用 Gitaly 子 chart 并配置极狐GitLab 使用外部 Gitaly。如果在您的主 gitlab.yml 配置文件有任何 Gitaly 引用,移除它们然后用下面的内容创建一个新的 external-gitaly.yml 文件。

    如果您之前已经定义好了额外的 Gitaly 存储,您需要确保 Gitaly 存储的名称和新配置文件中的名称是一致的,否则恢复操作将失败。

    如果您在配置 TLS 请求,请参考通过 TLS 连接外部 Gitaly 部分:

    ::Tabs

    :::TabTitle Gitaly

    global:
      gitaly:
        enabled: false
        external:
          - name: default                   # required
            hostname: node1.git.example.com # required
            port: 8075                      # optional, default shown
            tlsEnabled: false               # optional, overrides gitaly.tls.enabled
    

    :::TabTitle Gitaly 集群

    global:
      gitaly:
        enabled: false
        external:
          - name: default                   # required
            hostname: ha.git.example.com    # required
            port: 2305                      # Praefect uses port 2305
            tlsEnabled: false               # optional, overrides gitaly.tls.enabled
    

    ::EndTabs

  2. 使用 gitlab.ymlingress-only-allow-ext-gitaly.ymlexternal-gitaly.yml 文件应用新的配置:

    helm upgrade --install gitlab gitlab/gitlab \
      -f gitlab.yml \
      -f ingress-only-allow-ext-gitaly.yml \
      -f external-gitaly.yml
    
  3. 如果 Webservice pod 没有运行的话,将其 pod 扩容至原来的副本数。这是有必要的,因为我们可以在后面的步骤中测试极狐GitLab 和外部 Gitaly 的连接:

    kubectl scale deploy -lapp=webservice,release=<release> --replicas=<value>
    
  4. 在 Toolbox pod 中,确保极狐GitLab 能够成功连接到外部的 Gitaly:

    kubectl exec <toolbox pod name> -it -- gitlab-rake gitlab:gitaly:check
    
  5. 确保外部 Gitaly 可以连接回 Chart 安装的实例:

    ::Tabs

    :::TabTitle Gitaly

    确保 Gitaly 服务可以成功回调到极狐GitLab API:

    sudo /opt/gitlab/embedded/bin/gitaly check /var/opt/gitlab/gitaly/config.toml
    

    :::TabTitle Gitaly 集群

    在所有的 Praefect 节点上,确保 Praefect 服务可以成功回调到极狐GitLab API:

    # Run on Praefect nodes
    sudo /opt/gitlab/embedded/bin/praefect -config /var/opt/gitlab/praefect/config.toml dial-nodes
    

    在所有的 Gitaly 节点上,确保 Gitaly 服务可以成功回调到极狐GitLab API:

    # Run on Gitaly nodes
    sudo /opt/gitlab/embedded/bin/gitaly check /var/opt/gitlab/gitaly/config.toml
    

    ::EndTabs

步骤 6:恢复并验证仓库的备份

  1. 恢复之前创建的备份文件。结果是仓库被拷贝到配置好的外部 Gitaly 或 Gitaly 集群。
  2. 检查所有极狐GitLab 仓库并创建仓库校验和列表。将输出管道至文件中以便在迁移之后我们可以用 diff 进行校验:

    kubectl exec <toolbox pod name> -it -- gitlab-rake gitlab:git:checksum_projects  > ~/checksums-after.txt
    
  3. 对比仓库迁移前后的校验和列表。如果校验和一致,此命令将不会有任何输出:

    diff ~/checksums-before.txt ~/checksums-after.txt
    

如果您看到 diff 输出中某个特定行的空白校验和变为 0000000000000000000000000000000000000000,这就是期望之中的,可以直接忽略。

步骤 7:最终配置和验证

  1. 为了允许外部用户和极狐GitLab Runner 再次连接到极狐GitLab,同时应用 gitlab.ymlexternal-gitaly.yml 文件。由于我们没有指定 ingress-only-allow-ext-gitaly.yml 文件,因此这会移除 IP 限制:

     helm upgrade <release> gitlab/gitlab \
       -f gitlab.yml \
       -f external-gitaly.yml
    

    考虑生成一个包含外部 Gitaly 配置的一致性 gitlab.yml 文件以备将来之用:

     helm get values <release> gitlab/gitlab -o yaml > gitlab.yml
    
  2. 如果您正在使用极狐GitLab 企业版(专业版或旗舰版),您可以通过 UI、API 或 Rails 控制台禁用维护模式

    kubectl exec <toolbox pod name> -it -- gitlab-rails runner 'Gitlab::CurrentSettings.update!(maintenance_mode: false)'
    
  3. 如果您有多个 Gitaly 存储,请配置新仓库的存储
  4. 开启 Sidekiq cron 作业:

    kubectl exec <toolbox pod name> -it -- gitlab-rails runner 'Sidekiq::Cron::Job.all.map(&:enable!)'
    
  5. 如果它们没有正常运行,将您的 Runner pod 扩容至原来的副本数:

    kubectl scale deploy -lapp=gitlab-gitlab-runner,release=<release> --replicas=<value>
    
  6. 在您确认一切如期望一样正常运行后,您可以删除 Gitaly PVC:

    WARNING:直到您已经确认校验和和步骤 6 中的相匹配之前且您已经多次确认一切如期望一样正常运行之前不要删除 PVC。

     kubectl delete pvc repo-data-<release>-gitaly-0
    

回滚

如果您遇到了任何问题,您可以回滚变更以便再次使用 Gitaly 子 chart。

要想回滚成功,原来的 Gitaly PVC 就必须存在。

  1. 使用在步骤 1:获取当前的极狐GitLab Chart 版本中获取的版本号,回滚到原来的极狐GitLab Chart 版本:

    helm rollback <release> <revision>
    
  2. 如果它们没有正常运行,将您的 Webservice pod 扩容至原来的副本数:

    kubectl scale deploy -lapp=webservice,release=<release> --replicas=<value>
    
  3. 如果它们没有正常运行,将您的 Sidekiq pod 扩容至原来的副本数:

    kubectl scale deploy -lapp=sidekiq,release=<release> --replicas=<value>
    
  4. 如果之前禁用了 Sidekiq cron 作业,请开启它们:

    kubectl exec <toolbox pod name> -it -- gitlab-rails runner 'Sidekiq::Cron::Job.all.map(&:enable!)'
    
  5. 如果它们没有正常运行,将您的 Runner pod 扩容至原来的副本数:

    kubectl scale deploy -lapp=gitlab-gitlab-runner,release=<release> --replicas=<value>
    
  6. 如果您在使用极狐GitLab 企业版(专业版或旗舰版),如果维护模式已开启,则禁用它。

相关文档