Gitaly ClusterでGitLabのGitalyを冗長化させる


はじめに

GitLabは複数のコンポーネントから構成されていますが、その中でもGitalyはGitリポジトリへのアクセス処理を担っています。GitLab 13からはGitaly Clusterが提供されるようになり、Gitリポジトリの冗長化が可能となりました。

それ以前もNFSをストレージとして使用して可用性を上げることはできていましたが、公式ページによるとGitLab 13からNFSは非推奨となり、GitLab 14からはサポート外となるようです。

今回はGitaly ClusterをKubernetes上に構築する手順を説明します。

Gitaly Clusterについて

Gitaly ClusterはGitalyのクラスタ化を実現させたもので、PraefectというGitalyへのルーティングとトランザクション処理を行うコンポーネントを利用します。また、PraefectにはロードバランサとDBをデプロイする必要があります。Kubernetesの場合、ロードバランサはServiceになります。

Gitaly Clusterは以下の機能があります。

  • レプリカごとの高い整合性
  • 自動フェイルオーバー
  • データロス検知後のリポジトリへのready only設定

構築

環境はEKS 1.16を使用し、Helm 3.4.0でデプロイします。GitLab Helm Chart 4.5.3、ALB Ingress Controller Helm Chart 0.1.11を利用しています。

GitLabのデプロイ

GitLab Helm Chartのvaluesは以下のようにします。RDSのPostgreSQL DBを事前にPraefectのために作成しておきglobal.praefect.psql.hostに設定します。バージョンは11以上でないといけないことに注意しましょう。

my-values.yaml
global:
  edition: ce
  hosts:
    https: false
    gitlab:
      name: XXXXXXXXXX.ap-northeast-1.elb.amazonaws.com
      https: false
  ingress:
    configureCertmanager: false
    enabled: false
    tls:
      enabled: false
  praefect:
    enabled: true
    gitalyReplicas: 3
    psql:
      host: YYYYYYYYYY.ap-northeast-1.rds.amazonaws.com
      port: 5432
      user: praefect
      dbName: praefect
      sslMode: "disable"
upgradeCheck:
  enabled: false
certmanager:
  install: false
nginx-ingress:
  enabled: false
prometheus:
  install: false
registry:
  enabled: false
gitlab-runner:
  install: false
gitlab:
  gitlab-exporter:
    enabled: false
  gitlab-shell:
    enabled: false
  praefect:
    replicas: 3
  sidekiq:
    registry:
      enabled: false
  task-runner:
    enabled: false
    registry:
      enabled: false
  webservice:
    registry:
      enabled: false
    service:
      type: NodePort
    ingress:
      enabled: false
$ helm install --name test-gitlab \
  -f my-values.yaml \
  gitlab/gitlab --version 4.5.3

global.hosts.gitlab.nameにはALBのエンドポイントを設定しています。ALB Ingress Controllerをデプロイしておき、以下のIngressでALBを自動作成します。gitlab.webservice.service.typeNodePortになっているのもそのためです。

ingress.yaml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  annotations:
    alb.ingress.kubernetes.io/scheme: internet-facing
    kubernetes.io/ingress.class: alb
  name: alb-ingress
spec:
  rules:
  - http:
      paths:
       - backend:
           serviceName: test-gitlab-webservice
           servicePort: 8181
       - backend:
           serviceName: test-gitlab-webservice 
           servicePort: 8080
         path: /admin/sidekiq
$ kubectl apply -f ingress.yaml

以上を行うだけではPraefect PodはRunningになりません。Praefect DBの設定を手動で行う必要があります。

Praefect DBの設定

HelmでGitLabをデプロイした際、Praefect DBのパスワードがSecretとして作成されるので以下のコマンドで確認します。

$ kubectl get secret test-gitlab-praefect-dbsecret \
  -o jsonpath='{.data.secret}' \
  | base64 --decode

確認したパスワードを用いて、事前に作成したRDSのPostgreSQL DBに以下の設定を入れます。

$ psql -h YYYYYYYYYY.ap-northeast-1.rds.amazonaws.com \
  -p 5432 \
  -U postgres \
  -d template1
> CREATE ROLE praefect WITH LOGIN;
> \password praefect
Enter new password:
Enter it again:
> GRANT praefect TO postgres;
> CREATE DATABASE praefect WITH OWNER praefect;

Podの確認

実際にPodを確認します。PraefectとGitalyが複数存在していることが分かります。

$ kubectl get pod
NAME                                               READY   STATUS      RESTARTS   AGE
test-gitlab-gitaly-0                               1/1     Running     0          3h24m
test-gitlab-gitaly-1                               1/1     Running     0          3h24m
test-gitlab-gitaly-2                               1/1     Running     0          3h24m
test-gitlab-migrations-2-kn8sj                     0/1     Completed   0          3h18m
test-gitlab-minio-666d6596c-kpfzx                  1/1     Running     0          3h24m
test-gitlab-minio-create-buckets-2-psqds           0/1     Completed   0          3h18m
test-gitlab-postgresql-0                           2/2     Running     0          3h24m
test-gitlab-praefect-0                             1/1     Running     0          3h20m
test-gitlab-praefect-1                             1/1     Running     0          3h20m
test-gitlab-praefect-2                             1/1     Running     0          3h20m
test-gitlab-redis-master-0                         2/2     Running     0          3h24m
test-gitlab-sidekiq-all-in-1-v1-76489f4f45-4ql2m   1/1     Running     0          3h18m
test-gitlab-webservice-6db7f4bcd8-jgh57            2/2     Running     0          3h18m
test-gitlab-webservice-6db7f4bcd8-qrcrr            2/2     Running     0          3h18m

動作確認

実際にアクセスして動作を確認していきます。

rootでログインしてプロジェクトを作成してみます。

testという名前でプロジェクトを作成することにします。

実際に作成されました。これでGitaly Clusterの動作確認は完了です。

まとめ

GitLabのGitリポジトリへのアクセス処理を行うGitalyを冗長化させるためのGitaly ClusterをEKS上に構築する方法を説明しました。

今回はGitalyにフォーカスしていたため別コンポーネントには特に触れていませんが、可用性をさらに上げる場合にはminioをS3、アプリ用のpostgresql DBをRDS、redisをElastiCache等で代替すると良いです。