正式なドキュメントは英語版であり、この日本語訳はAI支援翻訳により作成された参考用のものです。日本語訳の一部の内容は人間によるレビューがまだ行われていないため、翻訳のタイミングにより英語版との間に差異が生じることがあります。最新かつ正確な情報については、英語版をご参照ください。

GitLab Geoデータベースレプリケーション

  • プラン: Premium、Ultimate
  • 提供形態: GitLab Self-Managed

このドキュメントでは、プライマリGitLabデータベースをセカンダリサイトのデータベースにレプリケートするために必要な最小限の手順について説明します。データベースの設定やサイズなどの属性に基づいて、いくつかの値を変更する必要がある場合があります。

GitLabのインスタンスが(Linuxパッケージのインストールによって管理されていない)外部PostgreSQLデータベースのインスタンスを使用している場合、ロールは必要なすべての設定手順を実行できません。この場合、代わりに外部PostgreSQLデータベースを使用するGeoプロセスを使用してください。

設定プロセスの各ステージは、ドキュメントに記載されている順序で完了する必要があります。そうでない場合は、続行する前に以前のすべてのステージを完了してください。

セカンダリサイトが、プライマリサイトと同じバージョンのGitLab Enterprise Editionを実行していることを確認してください。プライマリサイトに、PremiumまたはUltimateプランのサブスクリプションのライセンスを追加したことを確認してください。

テスト環境または本番環境でこれらの手順を実行する前に、必ずすべての手順を読み、確認してください。

データベースパスワードの整合性要件

データベース関連の各パスワード・タイプは、すべてのGeoサイト(プライマリとセカンダリ)で一致する値を持っている必要があります。これには次のユーザーが含まれます:

  • postgresql['sql_replication_password'](レプリケーションユーザーのパスワード、MD5)
  • postgresql['sql_user_password'](GitLabデータベース・ユーザーのパスワード、MD5)
  • gitlab_rails['db_password'](GitLabデータベース・ユーザーのパスワード、平文)
  • patroni['replication_password'](Patroni設定の場合、平文)
  • patroni['password'](Patroni API認証の場合、平文)
  • postgresql['pgbouncer_user_password'](PgBouncer使用時、MD5)

たとえば、プライマリサイトで設定されたpatroni['password']の値は、すべてのセカンダリサイトのpatroni['password']の値と同一である必要があります。

これらのパスワードは、プライマリサイトとセカンダリサイト間のデータベース認証とレプリケーションに使用されます。異なるパスワードを使用すると、レプリケーションの失敗が発生し、Geoが正常に機能しなくなります。

単一インスタンスのデータベースレプリケーション

単一インスタンスのデータベースレプリケーションは、設定が容易で、クラスター化された代替手段と同じGeo機能を提供します。これは、単一のマシンで実行される設定や、将来のクラスター化されたインストールのためにGeoを評価しようとする場合に役立ちます。

単一インスタンスは、HAアーキテクチャに推奨されるPatroniを使用して、クラスター化されたバージョンに展開できます。

PostgreSQLレプリケーションを単一インスタンスデータベースとして設定する方法については、以下の手順に従ってください。または、Patroniクラスターを使用したレプリケーションの設定に関するマルチノードデータベースレプリケーションの指示を参照してください。

PostgreSQLレプリケーション

書き込み操作が発生するGitLabのプライマリサイトは、プライマリデータベース・サーバーに接続します。セカンダリサイトは、独自のデータベース・サーバー(読み取り専用)に接続します。

プライマリサイトがセカンダリサイトの復元に必要なすべてのデータを保持するように、PostgreSQLレプリケーションスロットを使用する必要があります。詳細については、下記をご覧ください。

以下のガイドでは、以下を前提としています:

  • Linuxパッケージ(PostgreSQL 12以降を使用)を使用しており、pg_basebackupツールが含まれています。
  • Linuxパッケージのインストールによって管理されているPostgreSQL(または同等のバージョン)を実行しているプライマリサイト(レプリケート元のGitLabサーバー)がすでに設定されており、すべてのサイトで同じセカンダリサイトが設定され、同じバージョンのPostgreSQL、OS、GitLabを使用している。

Geoはストリーミングレプリケーションで動作します。論理レプリケーションはサポートされていませんが、エピック18022では、この動作を変更することを提案しています。

ステップ1: プライマリサイトを設定する

  1. GitLabのプライマリサイトにSSHで接続し、rootとしてサインインします:

    sudo -i
  2. GitLabのバージョンアップグレード時に意図しないダウンタイムが発生するのを防ぐため、PostgreSQLの自動バージョンアップグレードをオプトアウトします。既知のGeoでPostgreSQLをバージョンアップグレードする際の注意点に注意してください。特に大規模な環境では、PostgreSQLのバージョンアップグレードは慎重に計画および実行する必要があります。その結果、今後は、PostgreSQLのバージョンアップグレードが定期的なメンテナンス活動の一部であることを確認してください。

  3. /etc/gitlab/gitlab.rbを編集して、サイトのunique(一意)の名前を追加します:

    ##
    ## The unique identifier for the Geo site. See
    ## https://docs.gitlab.com/ee/administration/geo_sites.html#common-settings
    ##
    gitlab_rails['geo_node_name'] = '<site_name_here>'
  4. 変更を有効にするには、プライマリサイトを再設定します:

    gitlab-ctl reconfigure
  5. サイトをプライマリサイトとして定義するには、以下のコマンドを実行します:

    gitlab-ctl set-geo-primary-node

    このコマンドは、/etc/gitlab/gitlab.rbで定義されたexternal_urlを使用します。

  6. gitlabデータベース・ユーザーのパスワードを定義します:

    必要なパスワードのMD5ハッシュを生成します:

    gitlab-ctl pg-password-md5 gitlab
    # Enter password: <your_db_password_here>
    # Confirm password: <your_db_password_here>
    # fca0b89a972d69f00eb3ec98a5838484

    /etc/gitlab/gitlab.rbを編集します:

    # Fill with the hash generated by `gitlab-ctl pg-password-md5 gitlab`
    postgresql['sql_user_password'] = '<md5_hash_of_your_db_password>'
    
    # Every node that runs Puma or Sidekiq needs to have the database
    # password specified as below. If you have a high-availability setup, this
    # must be present in all application nodes.
    gitlab_rails['db_password'] = '<your_db_password_here>'
  7. データベースのレプリケーションユーザーのパスワードを定義します。

    postgresql['sql_replication_user']/etc/gitlab/gitlab.rbで定義されているユーザー名を使用します。デフォルト値はgitlab_replicatorです。ユーザー名を別のものに変更した場合は、以下の手順を調整してください。

    必要なパスワードのMD5ハッシュを生成します:

    gitlab-ctl pg-password-md5 gitlab_replicator
    # Enter password: <your_replication_password_here>
    # Confirm password: <your_replication_password_here>
    # 950233c0dfc2f39c64cf30457c3b7f1e

    /etc/gitlab/gitlab.rbを編集します:

    # Fill with the hash generated by `gitlab-ctl pg-password-md5 gitlab_replicator`
    postgresql['sql_replication_password'] = '<md5_hash_of_your_replication_password>'

    Linuxパッケージのインストールによって管理されていない外部データベースを使用している場合は、gitlab_replicatorユーザーを作成し、そのユーザーのパスワードを手動で定義する必要があります:

    --- Create a new user 'replicator'
    CREATE USER gitlab_replicator;
    
    --- Set/change a password and grants replication privilege
    ALTER USER gitlab_replicator WITH REPLICATION ENCRYPTED PASSWORD '<replication_password>';
  8. /etc/gitlab/gitlab.rbを編集し、ロールをgeo_primary_roleに設定します(詳細については、Geoロールを参照してください):

    ## Geo Primary role
    roles(['geo_primary_role'])
  9. ネットワーク・インターフェースでリッスンするようにPostgreSQLを設定します:

    セキュリティ上の理由から、PostgreSQLはデフォルトではどのネットワーク・インターフェースでもリッスンしません。ただし、Geoでは、セカンダリサイトがプライマリサイトのデータベースに接続できる必要があります。このため、各サイトのIPアドレスが必要です。

    外部PostgreSQLインスタンスについては、追加手順を参照してください。

    クラウドプロバイダーを使用している場合は、各Geoサイトのアドレスをクラウドプロバイダーの管理コンソールで確認できます。

    Geoサイトのアドレスを調べるには、GeoサイトにSSHで接続して実行します:

    ##
    ## Private address
    ##
    ip route get 255.255.255.255 | awk '{print "Private address:", $NF; exit}'
    
    ##
    ## Public address
    ##
    echo "External address: $(curl --silent "ipinfo.io/ip")"

    ほとんどの場合、以下のアドレスがGitLab Geoの設定に使用されます:

    設定アドレス
    postgresql['listen_address']プライマリサイトのパブリックまたはVPCプライベート・アドレス。
    postgresql['md5_auth_cidr_addresses']プライマリサイトおよびセカンダリサイトのパブリックまたはVPCプライベート・アドレス。

    Googleクラウドプロバイダー、SoftLayer、またはVirtual Private Cloud(VPC)を提供するその他のベンダーを使用している場合は、プライマリサイトとセカンダリサイトの「プライベート」または「内部」アドレスをpostgresql['md5_auth_cidr_addresses']およびpostgresql['listen_address']に使用することをお勧めします。

    listen_addressオプションは、指定されたアドレスに対応するインターフェースとのネットワーク接続に対してPostgreSQLを展開します。詳細については、PostgreSQLのドキュメントを参照してください。

    0.0.0.0または*listen_addressとして使用する必要がある場合は、Railsが127.0.0.1経由で接続できるように、127.0.0.1/32postgresql['md5_auth_cidr_addresses']設定に追加する必要があります。詳細については、issue 5258を参照してください。

    ネットワーク設定によっては、推奨されるアドレスが正しくない場合があります。プライマリサイトとセカンダリサイトがローカルエリアネットワーク、またはAmazon VPCGoogle VPCのようなアベイラビリティーゾーンを接続する仮想ネットワーク経由で接続する場合は、postgresql['md5_auth_cidr_addresses']セカンダリサイトのプライベートアドレスを使用する必要があります。

    /etc/gitlab/gitlab.rbを編集し、IPアドレスをネットワーク設定に適したアドレスに置き換えて、以下を追加します:

    ##
    ## Primary address
    ## - replace '<primary_node_ip>' with the public or VPC address of your Geo primary node
    ##
    postgresql['listen_address'] = '<primary_site_ip>'
    
    ##
    # Allow PostgreSQL client authentication from the primary and secondary IPs. These IPs may be
    # public or VPC addresses in CIDR format, for example ['198.51.100.1/32', '198.51.100.2/32']
    ##
    postgresql['md5_auth_cidr_addresses'] = ['<primary_site_ip>/32', '<secondary_site_ip>/32']
    
    ##
    ## Replication settings
    ##
    # postgresql['max_replication_slots'] = 1 # Set this to be the number of Geo secondary nodes if you have more than one
    # postgresql['max_wal_senders'] = 10
    # postgresql['wal_keep_segments'] = 10
  10. PostgreSQLが再起動され、プライベートアドレスでリッスンするまで、自動データベース移行を一時的に無効にします。/etc/gitlab/gitlab.rbを編集し、設定をfalseに変更します:

    ## Disable automatic database migrations
    gitlab_rails['auto_migrate'] = false
  11. オプション。別のセカンダリサイトを追加する場合は、関連する設定は次のようになります:

    postgresql['md5_auth_cidr_addresses'] = ['<primary_site_ip>/32', '<secondary_site_ip>/32', '<another_secondary_site_ip>/32']

    データベースレプリケーション要件に合わせて、wal_keep_segmentsmax_wal_sendersを編集することもできます。詳細については、PostgreSQL - レプリケーションに関するドキュメントを参照してください。

  12. ファイルを保存し、データベースのリスン変更とレプリケーションスロットの変更が適用されるようにGitLabを再設定します:

    gitlab-ctl reconfigure

    PostgreSQLを再起動して、変更を有効にします:

    gitlab-ctl restart postgresql
  13. PostgreSQLが再起動され、プライベートアドレスでリッスンするようになったので、移行を再度有効にします。

    /etc/gitlab/gitlab.rbを編集し、設定を変更してtrueにします:

    gitlab_rails['auto_migrate'] = true

    ファイルを保存して、GitLabを再設定します:

    gitlab-ctl reconfigure
  14. PostgreSQLサーバーがリモート接続を受け入れるように設定されたので、netstat -plnt | grep 5432を実行して、PostgreSQLがポート5432プライマリサイトのプライベートアドレスをリッスンしていることを確認します。

  15. GitLabを再設定すると、CA証明書が自動的に生成されました。これは、PostgreSQLトラフィックを盗聴者から保護するために自動的に使用されます。アクティブな(「中間者」)攻撃者から保護するには、セカンダリサイトは、証明書に署名した認証局のコピーを必要とします。この自己署名証明書の場合、プライマリサイトでこのコマンドを実行して、PostgreSQLのserver.crtファイルのコピーを作成します:

    cat ~gitlab-psql/data/server.crt

    出力をクリップボードまたはローカル・ファイルにコピーします。セカンダリサイトの設定時に必要になります。証明書は機密データではありません。

    ただし、この証明書は汎用的なPostgreSQL共通名で作成されています。このため、データベースをレプリケートする際にverify-caモードを使用する必要があります。そうしないと、ホスト名の不一致によってエラーが発生します。

  16. オプション。生成された証明書を使用する代わりに、独自のSSL証明書を生成し、手動でPostgreSQLのSSLを設定します

    少なくともSSL証明書とキーが必要です。データベースSSLのドキュメントに従って、postgresql['ssl_cert_file']postgresql['ssl_key_file']の値をフルパスに設定します。

    これにより、データベースをレプリケートする際にverify-full SSLモードを使用し、CNの完全なホスト名を検証するという追加のメリットを得ることができます。

    今後は、以前に自動生成された自己署名証明書の代わりに、この証明書(postgresql['ssl_cert_file']にも設定されている)を使用できます。これにより、CNが一致する場合、レプリケーションエラーなしでverify-fullを使用できます。

    プライマリデータベースで、/etc/gitlab/gitlab.rbを開き、postgresql['ssl_ca_file'](CA証明書)を検索します。後でserver.crtに貼り付けるクリップボードに値をコピーします。

ステップ2: セカンダリサーバーを設定する

  1. GitLabのセカンダリサイトにSSHで接続し、rootとしてサインインします:

    sudo -i
  2. GitLabのバージョンアップグレード時に意図しないダウンタイムが発生するのを防ぐため、PostgreSQLの自動バージョンアップグレードをオプトアウトします。既知のGeoでPostgreSQLをバージョンアップグレードする際の注意点に注意してください。特に大規模な環境では、PostgreSQLのバージョンアップグレードは慎重に計画および実行する必要があります。その結果、今後は、PostgreSQLのバージョンアップグレードが定期的なメンテナンス活動の一部であることを確認してください。

  3. アプリケーションサーバーとSidekiqを停止します:

    gitlab-ctl stop puma
    gitlab-ctl stop sidekiq

    この手順は、サイトが完全に設定される前に何かを実行しようとしないようにするために重要です。

  4. プライマリサイトのPostgreSQLサーバーへのプライマリをチェックします:

    gitlab-rake gitlab:tcp_check[<primary_site_ip>,5432]

    この手順が失敗した場合は、間違ったIPアドレスを使用しているか、ファイアウォールがサイトへのアクセスを妨げている可能性があります。IPアドレスを確認し、パブリックアドレスとプライベートアドレスの違いに細心の注意を払ってください。ファイアウォールが存在する場合、セカンダリサイトがポート5432でプライマリサイトに接続することを許可されていることを確認してください。

  5. セカンダリサイトにファイルserver.crtを作成します。コンテンツは、プライマリサイトの設定の最後の手順で取得したものです:

    editor server.crt
  6. セカンダリサイトでPostgreSQL TLS検証を設定します:

    server.crtファイルをインストールします:

    install \
       -D \
       -o gitlab-psql \
       -g gitlab-psql \
       -m 0400 \
       -T server.crt ~gitlab-psql/.postgresql/root.crt

    PostgreSQLは、TLS接続を検証する際に、その正確な証明書のみを認識するようになりました。証明書は、プライマリサイトにonly(のみ)存在する秘密キーへのアクセス権を持つ人のみがレプリケートできます。

  7. gitlab-psqlユーザーがプライマリサイトのデータベースに接続できることをテストします(デフォルトのデータベース名はLinuxパッケージのインストールでは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_site_ip>

    手動で生成した証明書を使用しており、完全なホスト名の検証を利用するためにsslmode=verify-fullを使用する場合は、コマンドの実行時にverify-caverify-fullに置き換えます。

    メッセージが表示されたら、最初のステップでgitlab_replicatorユーザー用に設定した平文パスワードを入力します。すべてが正しく機能している場合は、プライマリサイトのデータベースのリストが表示されます。

    ここで接続に失敗した場合は、TLSの設定が正しくないことを示します。プライマリサイトの~gitlab-psql/data/server.crtの内容が、セカンダリサイトの~gitlab-psql/.postgresql/root.crtの内容と一致していることを確認してください。

  8. /etc/gitlab/gitlab.rbを編集し、ロールをgeo_secondary_roleに設定します(詳細については、Geoロールを参照してください):

    ##
    ## Geo Secondary role
    ## - configure dependent flags automatically to enable Geo
    ##
    roles(['geo_secondary_role'])
  9. PostgreSQLを設定する:

    この手順は、プライマリインスタンスを設定した方法と似ています。これは、単一のノードを使用している場合でも、有効にする必要があります。

    各パスワード・タイプは、すべてのGeoサイトで一致する値を持っている必要があります。

    /etc/gitlab/gitlab.rbを編集し、IPアドレスをネットワーク設定に適したアドレスに置き換えて、以下を追加します:

    ##
    ## Secondary address
    ## - replace '<secondary_site_ip>' with the public or VPC address of your Geo secondary site
    ##
    postgresql['listen_address'] = '<secondary_site_ip>'
    postgresql['md5_auth_cidr_addresses'] = ['<secondary_site_ip>/32']
    
    ##
    ## Database credentials password (defined previously in primary site)
    ## - replicate same values here as defined in primary site
    ##
    postgresql['sql_replication_password'] = '<md5_hash_of_your_replication_password>'
    postgresql['sql_user_password'] = '<md5_hash_of_your_db_password>'
    gitlab_rails['db_password'] = '<your_db_password_here>'

    外部PostgreSQLインスタンスについては、追加手順を参照してください。以前のプライマリサイトをオンラインに戻してセカンダリサイトとして機能させる場合は、roles(['geo_primary_role'])またはgeo_primary_role['enable'] = trueも削除する必要があります。

  10. 変更を有効にするには、GitLabを再構成してください:

    gitlab-ctl reconfigure
  11. IPの変更を有効にするには、PostgreSQLを再起動します:

    gitlab-ctl restart postgresql

ステップ3: レプリケーションプロセスを開始する

以下は、セカンダリサイトのデータベースをプライマリサイトのデータベースに接続するスクリプトです。このスクリプトはデータベースをレプリケートし、ストリーミングレプリケーションに必要なファイルを作成します。

使用されるディレクトリは、Linuxパッケージのインストールで設定されているデフォルトです。デフォルトを変更した場合は、それに応じてスクリプトを設定してください(ディレクトリとパスを置き換えます)。

pg_basebackupの実行前にPostgreSQLのすべてのデータを削除するため、必ずセカンダリサイトでこれを実行してください。

  1. GitLabのセカンダリサイトにSSHで接続し、rootとしてサインインします:

    sudo -i
  2. レプリケーションスロット名として使用するセカンダリサイトに使用する、データベースに適した名前を選択してください。たとえば、ドメインがsecondary.geo.example.comの場合、以下のコマンドに示すように、スロット名としてsecondary_exampleを使用します。

  3. 以下のコマンドを実行して、バックアップ/復元するを開始し、レプリケーションを開始します。

    各GitLab Geoのセカンダリサイトには、独自のユニークなレプリケーションスロット名が必要です。2つのセカンダリ間で同じスロット名を使用すると、PostgreSQLのレプリケーションが中断されます。

    レプリケーションスロット名には、小文字の文字、数字、アンダースコア文字のみを含める必要があります。

    プロンプ​​トが表示されたら、最初の手順でgitlab_replicatorユーザーに設定した平文のパスワードを入力します。

    gitlab-ctl replicate-geo-database \
       --slot-name=<secondary_site_name> \
       --host=<primary_site_ip> \
       --sslmode=verify-ca

    カスタムPostgreSQL証明書を生成した場合は、追加のセキュリティのために証明書CN / SANの完全なホスト名の追加検証を利用するには、--sslmode=verify-full(またはsslmode行を完全に省略)を使用する必要があります。そうでない場合、自動的に作成された証明書をverify-fullで使用すると、一般的なPostgreSQL CNがあり、このコマンドの--host値と一致しないため、失敗します。

    このコマンドは、多数の追加オプションも使用します。すべてをリストするには--helpを使用できますが、以下にいくつかのヒントを示します:

    • プライマリサイトに単一ノードがある場合は、--hostパラメータとしてプライマリノードホストを使用します。
    • プライマリサイトが外部PostgreSQLデータベースを使用している場合は、--hostパラメータを調整する必要があります:
      • PgBouncerの設定では、PgBouncerのアドレスではなく、実際のPostgreSQLデータベースホストを直接ターゲットにします。
      • Patroni構成の場合は、現在のPatroniリーダーホストをターゲットにします。
      • ロードバランサー(たとえば、HAProxy)を使用する場合、ロードバランサーが常にPatroniリーダーにルーティングするように構成されている場合は、ロードバランサーのターゲットにできます。そうでない場合は、実際のデータベースホストをターゲットにする必要があります。
      • 専用のPostgreSQLノードを使用するセットアップの場合は、専用のデータベースホストを直接ターゲットにします。
    • --slot-nameを、プライマリデータベースで使用されるレプリケーションスロットの名前に変更します。スクリプトは、レプリケーションスロットが存在しない場合、自動的に作成しようとします。
    • PostgreSQLが標準以外のポートでリッスンしている場合は、--port=を追加します。
    • データベースが大きすぎて30分で転送できない場合は、タイムアウトを増やす必要があります。たとえば、最初のレプリケーションに1時間未満かかると思われる場合は、--backup-timeout=3600を使用します。
    • --sslmode=disableを渡して、PostgreSQL TLS認証を完全にスキップします(たとえば、ネットワークパスが安全であることがわかっているか、サイト間VPNを使用している場合)。公衆インターネット上では安全not(ではありません)。
    • sslmodeの詳細については、PostgreSQLドキュメントを参照してください。上記の手順は、受動的な盗聴者とアクティブな「man-in-the-middle」攻撃者の両方に対する保護を確保するために、注意深く記述されています。
    • 古いサイトをGitLab Geoのセカンダリサイトに再利用する場合は、コマンドラインに--forceを追加する必要があります。
    • 本番環境マシンにない場合は、--skip-backupを追加して、(必要な場合に)バックアップ手順を無効にすることができます。

レプリケーションプロセスは完了しました。

レプリケーションプロセスは、プライマリサイトのデータベースからセカンダリサイトのデータベースにのみデータをコピーします。セカンダリサイトの設定を完了するには、プライマリサイトにセカンダリサイトを追加します。

PgBouncerのサポート(オプション)

PgBouncerは、GitLab Geoで使用してPostgreSQL接続をプールすることができ、単一インスタンスインストールで使用する場合でもパフォーマンスを向上させることができます。

GitLabを高可用性構成で使用し、Geoのプライマリサイトをサポートするクラスターと、Geoのセカンダリサイトをサポートする他の2つのクラスターを使用する場合は、PgBouncerを使用する必要があります。2つのPgBouncerノードが必要です。メインデータベース用と、追跡データベース用です。詳細については、関連ドキュメントを参照してください。

レプリケーションパスワードの変更

レプリケーションパスワードを変更する場合は、すべてのGeoサイト(プライマリとすべてのセカンダリ)で同じパスワード値に更新する必要があります。パスワードの同期を維持できないと、レプリケーションが中断します。

Linuxパッケージのインストールによって管理されるPostgreSQLインスタンスを使用する場合に、レプリケーションユーザーのパスワードを変更するには、次の手順を実行します:

GitLab Geoのプライマリサイト:

  1. レプリケーションユーザーのデフォルト値はgitlab_replicatorですが、/etc/gitlab/gitlab.rbpostgresql['sql_replication_user']設定でカスタムレプリケーションユーザーを設定した場合は、独自のユーザーに合わせて以下の手順を調整してください。

    目的のパスワードのMD5ハッシュを生成します:

    sudo gitlab-ctl pg-password-md5 gitlab_replicator
    # Enter password: <your_replication_password_here>
    # Confirm password: <your_replication_password_here>
    # 950233c0dfc2f39c64cf30457c3b7f1e

    /etc/gitlab/gitlab.rbを編集します:

    # Fill with the hash generated by `gitlab-ctl pg-password-md5 gitlab_replicator`
    postgresql['sql_replication_password'] = '<md5_hash_of_your_replication_password>'
  2. ファイルを保存し、GitLabを再設定して、PostgreSQLでレプリケーションユーザーのパスワードを変更します:

    sudo gitlab-ctl reconfigure
  3. PostgreSQLを再起動して、レプリケーションパスワードの変更を有効にします:

    sudo gitlab-ctl restart postgresql

パスワードがいずれかのセカンダリサイトで更新されるまで、セカンダリのPostgreSQLログに次のエラーメッセージが表示されます:

FATAL:  could not connect to the primary server: FATAL:  password authentication failed for user "gitlab_replicator"

すべてのGitLab Geoのセカンダリサイト:

  1. ハッシュされた'sql_replication_password'がGitLab Geoのセカンダリサイトで使用されていないため、最初のステップは設定の観点からは必要ありません。ただし、セカンダリサイトをGitLab Geoのプライマリにプロモートする必要がある場合は、セカンダリサイトの設定で'sql_replication_password'が一致していることを確認してください。

    /etc/gitlab/gitlab.rbを編集します:

    # Fill with the hash generated by `gitlab-ctl pg-password-md5 gitlab_replicator` on the Geo primary
    postgresql['sql_replication_password'] = '<md5_hash_of_your_replication_password>'
  2. 最初のレプリケーションセットアップ中に、gitlab-ctl replicate-geo-databaseコマンドは、レプリケーションユーザーアカウントの平文パスワードを次の2つの場所に書き込みます:

    • gitlab-geo.conf: PostgreSQLのレプリケーションプロセスで使用され、PostgreSQLデータディレクトリに書き込まれます。デフォルトでは、 /var/opt/gitlab/postgresql/data/gitlab-geo.confにあります。
    • .pgpass: gitlab-psqlユーザーによって使用され、デフォルトでは/var/opt/gitlab/postgresql/.pgpassにあります。

    これらの両方のファイルで平文のパスワードを更新し、PostgreSQLを再起動します:

    sudo gitlab-ctl restart postgresql

マルチノードデータベースレプリケーション

PostgreSQLノードをPatroniに移行する

Patroniが導入される前は、Geoはセカンダリサイトでの高可用性構成用のLinuxパッケージのインストールをサポートしていませんでした。

Patroniを使用すると、このサポートが可能になりました。既存のPostgreSQLをPatroniに移行するには:

  1. プライマリサイトでセットアップした方法と同様に、セカンダリでConsulクラスターセットアップがあることを確認します。
  2. 永続的なレプリケーションスロットを設定します
  3. 内部ロードバランサーを設定する
  4. PgBouncerノードを設定します
  5. その単一ノードマシンでスタンバイクラスターを設定する

単一ノードを備えたStandby Cluster(スタンバイクラスター)で終了します。これにより、以前にリストされた同じ手順に従って、追加のPatroniノードを追加できます。

Patroniのサポート

Patroniは、Geoの公式レプリケーション管理ソリューションです。Patroniを使用すると、プライマリセカンダリ Geoサイトで、可用性の高いクラスターをビルドできます。セカンダリサイトでのPatroniの使用はオプションであり、各Geoサイトで同じ数のノードを使用する必要はありません。

プライマリサイトでPatroniをセットアップする方法については、関連ドキュメントを参照してください。

GeoのセカンダリサイトのPatroniクラスターの設定

Geoのセカンダリサイトでは、メインPostgreSQLデータベースは、プライマリサイトのPostgreSQLデータベースの読み取り専用のレプリカです。

本番環境に対応した安全なセットアップには、少なくとも次のものが必要です:

  • 3つのConsulノード_(プライマリおよびセカンダリサイト)_
  • 2つのPatroniノード_(プライマリおよびセカンダリサイト)_
  • 1つのPgBouncerノード_(プライマリおよびセカンダリサイト)_
  • 1つの内部ロードバランサー_(プライマリサイトのみ)_

内部ロードバランサーは、新しいリーダーが選択されるたびに、Patroniクラスターのリーダーに接続するためのシングルエンドポイントを提供します。ロードバランサーは、セカンダリサイトからのカスケードレプリケーションを有効にするために必要です。

必ずパスワード認証情報と、他のデータベースのベストプラクティスを使用してください。

ステップ1: プライマリサイトでPatroniの永続的なレプリケーションスロットを設定する

プライマリデータベースからセカンダリノードのPatroniクラスターへの継続的なデータレプリケーションを保証するために、プライマリデータベースに永続的なレプリケーションスロットをセットアップします。

セカンダリサイトでPatroniを使用したデータベースレプリケーションをセットアップするには、プライマリサイトのPatroniクラスターに永続的なレプリケーションスロットを設定し、パスワード認証が使用されていることを確認する必要があります。

プライマリサイトのPatroniインスタンスを実行している各ノードで、starting on the Patroni Leader instance(Patroniリーダーインスタンスから開始)します:

  1. PatroniインスタンスにSSHで接続し、rootとしてサインインします:

    sudo -i
  2. GitLabのバージョンアップグレード時に意図しないダウンタイムが発生するのを防ぐため、PostgreSQLの自動バージョンアップグレードをオプトアウトします。既知のGeoでPostgreSQLをバージョンアップグレードする際の注意点に注意してください。特に大規模な環境では、PostgreSQLのバージョンアップグレードは慎重に計画および実行する必要があります。その結果、今後は、PostgreSQLのバージョンアップグレードが定期的なメンテナンス活動の一部であることを確認してください。

  3. /etc/gitlab/gitlab.rbを編集し、以下を追加します。各パスワードタイプに、すべてのGeoサイトで一致する値があることを確認してください。

    roles(['patroni_role'])
    
    consul['services'] = %w(postgresql)
    consul['configuration'] = {
      retry_join: %w[CONSUL_PRIMARY1_IP CONSUL_PRIMARY2_IP CONSUL_PRIMARY3_IP]
    }
    
    # You need one entry for each secondary, with a unique name following PostgreSQL slot_name constraints:
    #
    # Configuration syntax is: 'unique_slotname' => { 'type' => 'physical' },
    # We don't support setting a permanent replication slot for logical replication type
    patroni['replication_slots'] = {
      'geo_secondary' => { 'type' => 'physical' }
    }
    
    patroni['use_pg_rewind'] = true
    patroni['postgresql']['max_wal_senders'] = 8 # Use double of the amount of patroni/reserved slots (3 patronis + 1 reserved slot for a Geo secondary).
    patroni['postgresql']['max_replication_slots'] = 8 # Use double of the amount of patroni/reserved slots (3 patronis + 1 reserved slot for a Geo secondary).
    patroni['username'] = 'PATRONI_API_USERNAME'
    patroni['password'] = 'PATRONI_API_PASSWORD'
    patroni['replication_password'] = 'PLAIN_TEXT_POSTGRESQL_REPLICATION_PASSWORD'
    
    # Add all patroni nodes to the allowlist
    patroni['allowlist'] = %w[
      127.0.0.1/32
      PATRONI_PRIMARY1_IP/32 PATRONI_PRIMARY2_IP/32 PATRONI_PRIMARY3_IP/32
      PATRONI_SECONDARY1_IP/32 PATRONI_SECONDARY2_IP/32 PATRONI_SECONDARY3_IP/32
    ]
    
    # We list all secondary instances as they can all become a Standby Leader
    postgresql['md5_auth_cidr_addresses'] = %w[
      PATRONI_PRIMARY1_IP/32 PATRONI_PRIMARY2_IP/32 PATRONI_PRIMARY3_IP/32 PATRONI_PRIMARY_PGBOUNCER/32
      PATRONI_SECONDARY1_IP/32 PATRONI_SECONDARY2_IP/32 PATRONI_SECONDARY3_IP/32 PATRONI_SECONDARY_PGBOUNCER/32
    ]
    
    postgresql['pgbouncer_user_password'] = 'PGBOUNCER_PASSWORD_HASH'
    postgresql['sql_replication_password'] = 'POSTGRESQL_REPLICATION_PASSWORD_HASH'
    postgresql['sql_user_password'] = 'POSTGRESQL_PASSWORD_HASH'
    postgresql['listen_address'] = '0.0.0.0' # You can use a public or VPC address here instead
  4. 変更を有効にするには、GitLabを再構成してください:

    gitlab-ctl reconfigure
  1. 単一ノードインスタンスにSSHで接続し、rootとしてサインインします:

    sudo -i
  2. GitLabのバージョンアップグレード時に意図しないダウンタイムが発生するのを防ぐため、PostgreSQLの自動バージョンアップグレードをオプトアウトします。既知のGeoでPostgreSQLをバージョンアップグレードする際の注意点に注意してください。特に大規模な環境では、PostgreSQLのバージョンアップグレードは慎重に計画および実行する必要があります。その結果、今後は、PostgreSQLのバージョンアップグレードが定期的なメンテナンス活動の一部であることを確認してください。

  3. /etc/gitlab/gitlab.rbを編集し、以下を追加します:

    postgresql['max_wal_senders'] = 2 # Use 2 per secondary site (1 temporary slot for initial Patroni replication + 1 reserved slot for a Geo secondary)
    postgresql['max_replication_slots'] = 2 # Use 2 per secondary site (1 temporary slot for initial Patroni replication + 1 reserved slot for a Geo secondary)
  4. GitLabを再設定します:

    gitlab-ctl reconfigure
  5. PostgreSQLサービスを再起動して、新しい変更を有効にします:

    gitlab-ctl restart postgresql
  6. データベースコンソールを起動します

    gitlab-psql
  7. プライマリサイトで永続的なレプリケーションスロットを設定します

    select pg_create_physical_replication_slot('geo_secondary')
  8. オプション。プライマリにPgBouncerがないが、セカンダリにある場合:

    プライマリサイトでpgbouncerユーザーを設定し、Linuxパッケージに含まれているPgBouncerに必要なpg_shadow_lookup関数を追加します。セカンダリサーバー上のPgBouncerは、セカンダリサイト上のPostgreSQLノードに引き続き接続できる必要があります。

    --- Create a new user 'pgbouncer'
    CREATE USER pgbouncer;
    
    --- Set/change a password and grants replication privilege
    ALTER USER pgbouncer WITH REPLICATION ENCRYPTED PASSWORD '<pgbouncer_password_from_secondary>';
    
    CREATE OR REPLACE FUNCTION public.pg_shadow_lookup(in i_username text, out username text, out password text) RETURNS record AS $$
    BEGIN
        SELECT usename, passwd FROM pg_catalog.pg_shadow
        WHERE usename = i_username INTO username, password;
        RETURN;
    END;
    $$ LANGUAGE plpgsql SECURITY DEFINER;
    
    REVOKE ALL ON FUNCTION public.pg_shadow_lookup(text) FROM public, pgbouncer;
    GRANT EXECUTE ON FUNCTION public.pg_shadow_lookup(text) TO pgbouncer;
ステップ2: プライマリサイトで内部ロードバランサーを設定する

プライマリサイトで新しいリーダーが選択されるたびに、セカンダリサイトでスタンバイリーダーを再設定することを回避するには、TCP内部ロードバランサーをセットアップする必要があります。このロードバランサーは、Patroniクラスターのリーダーに接続するためのシングルエンドポイントを提供します。

Linuxパッケージにロードバランサーは含まれていません。HAProxyを使用してこれを行う方法を次に示します。

以下のIPと名前を例として使用します:

  • 10.6.0.21: HAProxy 1 (patroni1.internal)
  • 10.6.0.22: HAProxy 2 (patroni2.internal)
  • 10.6.0.23: HAProxy 3 (patroni3.internal)
global
    log /dev/log local0
    log localhost local1 notice
    log stdout format raw local0

defaults
    log global
    default-server inter 3s fall 3 rise 2 on-marked-down shutdown-sessions

frontend internal-postgresql-tcp-in
    bind *:5432
    mode tcp
    option tcplog

    default_backend postgresql

backend postgresql
    mode tcp
    option httpchk
    http-check expect status 200

    server patroni1.internal 10.6.0.21:5432 maxconn 100 check port 8008
    server patroni2.internal 10.6.0.22:5432 maxconn 100 check port 8008
    server patroni3.internal 10.6.0.23:5432 maxconn 100 check port 8008

詳細なガイダンスについては、推奨されるロードバランサーのドキュメントを参照してください。

ステップ3: セカンダリサイトでPgBouncerノードを設定する

本番環境に対応した、可用性の高い設定では、少なくとも3つのConsulノードと最小限1つのPgBouncerノードが必要です。ただし、データベースノードごとに1つのPgBouncerノードを用意することをお勧めします。複数のPgBouncerサービスノードがある場合は、内部ロードバランサー(TCP)が必要です。内部ロードバランサーは、PgBouncerクラスターに接続するためのシングルエンドポイントを提供します。詳細については、関連ドキュメントを参照してください。

セカンダリサイトでPgBouncerインスタンスを実行している各ノードで:

  1. PgBouncerノードにSSHで接続し、rootとしてサインインします:

    sudo -i
  2. /etc/gitlab/gitlab.rbを編集し、以下を追加します:

    # Disable all components except Pgbouncer and Consul agent
    roles(['pgbouncer_role'])
    
    # PgBouncer configuration
    pgbouncer['admin_users'] = %w(pgbouncer gitlab-consul)
    pgbouncer['users'] = {
    'gitlab-consul': {
       # Generate it with: `gitlab-ctl pg-password-md5 gitlab-consul`
       password: 'GITLAB_CONSUL_PASSWORD_HASH'
     },
      'pgbouncer': {
        # Generate it with: `gitlab-ctl pg-password-md5 pgbouncer`
        password: 'PGBOUNCER_PASSWORD_HASH'
      }
    }
    
    # Consul configuration
    consul['watchers'] = %w(postgresql)
    consul['configuration'] = {
      retry_join: %w[CONSUL_SECONDARY1_IP CONSUL_SECONDARY2_IP CONSUL_SECONDARY3_IP]
    }
    consul['monitoring_service_discovery'] =  true
  3. 変更を有効にするには、GitLabを再構成してください:

    gitlab-ctl reconfigure
  4. .pgpassファイルを作成して、ConsulがPgBouncerを再読み込みできるようにします。プロンプトが表示されたら、PLAIN_TEXT_PGBOUNCER_PASSWORDを2回入力します:

    gitlab-ctl write-pgpass --host 127.0.0.1 --database pgbouncer --user pgbouncer --hostuser gitlab-consul
  5. PgBouncerサービスをリロードします:

    gitlab-ctl hup pgbouncer
ステップ4: セカンダリサイトでスタンバイクラスターを設定する

シングルPostgreSQLインスタンスを備えたセカンダリサイトをPatroniクラスターに変換する場合は、PostgreSQLインスタンスから開始する必要があります。Patroniのスタンバイリーダーインスタンスになり、必要に応じて別のレプリカに切り替えることができます。

セカンダリサイトでPatroniインスタンスを実行している各ノードの場合:

  1. PatroniノードにSSHで接続し、rootとしてサインインします:

    sudo -i
  2. GitLabのバージョンアップグレード時に意図しないダウンタイムが発生するのを防ぐため、PostgreSQLの自動バージョンアップグレードをオプトアウトします。既知のGeoでPostgreSQLをバージョンアップグレードする際の注意点に注意してください。特に大規模な環境では、PostgreSQLのバージョンアップグレードは慎重に計画および実行する必要があります。その結果、今後は、PostgreSQLのバージョンアップグレードが定期的なメンテナンス活動の一部であることを確認してください。

  3. /etc/gitlab/gitlab.rbを編集し、以下を追加します:

    各パスワード・タイプは、すべてのGeoサイトで一致する値を持っている必要があります。

    roles(['consul_role', 'patroni_role'])
    
    consul['enable'] = true
    consul['configuration'] = {
      retry_join: %w[CONSUL_SECONDARY1_IP CONSUL_SECONDARY2_IP CONSUL_SECONDARY3_IP]
    }
    consul['services'] = %w(postgresql)
    
    postgresql['md5_auth_cidr_addresses'] = [
      'PATRONI_SECONDARY1_IP/32', 'PATRONI_SECONDARY2_IP/32', 'PATRONI_SECONDARY3_IP/32', 'PATRONI_SECONDARY_PGBOUNCER/32',
      # Any other instance that needs access to the database as per documentation
    ]
    
    
    # Add patroni nodes to the allowlist
    patroni['allowlist'] = %w[
      127.0.0.1/32
      PATRONI_SECONDARY1_IP/32 PATRONI_SECONDARY2_IP/32 PATRONI_SECONDARY3_IP/32
    ]
    
    patroni['standby_cluster']['enable'] = true
    patroni['standby_cluster']['host'] = 'INTERNAL_LOAD_BALANCER_PRIMARY_IP'
    patroni['standby_cluster']['port'] = INTERNAL_LOAD_BALANCER_PRIMARY_PORT
    patroni['standby_cluster']['primary_slot_name'] = 'geo_secondary' # Or the unique replication slot name you setup before
    patroni['username'] = 'PATRONI_API_USERNAME'
    patroni['password'] = 'PATRONI_API_PASSWORD'
    patroni['replication_password'] = 'PLAIN_TEXT_POSTGRESQL_REPLICATION_PASSWORD'
    patroni['use_pg_rewind'] = true
    patroni['postgresql']['max_wal_senders'] = 5 # A minimum of three for one replica, plus two for each additional replica
    patroni['postgresql']['max_replication_slots'] = 5 # A minimum of three for one replica, plus two for each additional replica
    
    postgresql['pgbouncer_user_password'] = 'PGBOUNCER_PASSWORD_HASH'
    postgresql['sql_replication_password'] = 'POSTGRESQL_REPLICATION_PASSWORD_HASH'
    postgresql['sql_user_password'] = 'POSTGRESQL_PASSWORD_HASH'
    postgresql['listen_address'] = '0.0.0.0' # You can use a public or VPC address here instead
    
    # GitLab Rails configuration is required for `gitlab-ctl geo-replication-pause`
    gitlab_rails['db_password'] = 'POSTGRESQL_PASSWORD'
    gitlab_rails['enable'] = true
    gitlab_rails['auto_migrate'] = false

    patroni['standby_cluster']['host']patroni['standby_cluster']['port']を設定する場合:

    • INTERNAL_LOAD_BALANCER_PRIMARY_IPは、プライマリ内部ロードバランサーのIPを指している必要があります。
    • INTERNAL_LOAD_BALANCER_PRIMARY_PORTは、プライマリPatroniクラスターリーダー用に設定されたフロントエンドポートを指している必要があります。PgBouncerフロントエンドポートはDo not(使用しないでください)。
  4. 変更を有効にするには、GitLabを再構成してください。この手順は、PostgreSQLユーザーと設定をブートストラップするために必要です。

    • これがPatroniの新しいインストールの場合は:

      gitlab-ctl reconfigure
    • 以前に動作していたPatroniクラスターがあるGeoサイトでPatroniスタンバイクラスターを設定している場合:

      1. カスケードレプリカを含め、Patroniによって管理されているすべてのノードでPatroniを停止します:

        gitlab-ctl stop patroni
      2. リーダーPatroniノードで以下を実行して、スタンバイクラスターを再作成します:

        rm -rf /var/opt/gitlab/postgresql/data
        /opt/gitlab/embedded/bin/patronictl -c /var/opt/gitlab/patroni/patroni.yaml remove postgresql-ha
        gitlab-ctl reconfigure
      3. プライマリPostgreSQLデータベースからのレプリケーションプロセスを開始するには、リーダーPatroniノードでPatroniを開始します:

        gitlab-ctl start patroni
      4. Patroniクラスターのステータスを確認します:

        gitlab-ctl patroni members

        以下を確認します:

        • 現在のPatroniノードが出力に表示されます。
        • ロールはStandby Leaderです。ロールは最初にReplicaと表示される場合があります。
        • 状態はRunningです。状態は最初にCreating replicaと表示される場合があります。

        ノードのロールがStandby Leaderとして安定し、状態がRunningになるまで待ちます。これには数分かかる場合があります。

      5. リーダーPatroniノードがStandby LeaderRunningの場合、スタンバイクラスター内の他のPatroniノードでPatroniを開始します:

        gitlab-ctl start patroni

        他のPatroniノードは、レプリカとして新しいスタンバイクラスターに参加し、リーダーPatroniノードからのレプリケーションを自動的に開始します。

  5. クラスターの状態を確認します:

    gitlab-ctl patroni members

    すべてのPatroniノードがRunning状態でリストされていることを確認します。1つのStandby Leaderノードと複数のReplicaノードが必要です。

単一のトラッキングデータベースノードをPatroniに移行する

Patroniの導入前は、Geoはセカンダリサイト上の高可用性設定のLinuxパッケージインストールをサポートしていませんでした。

Patroniを使用すると、高可用性設定をサポートできるようになりました。ただし、Patroniの一部の制限により、同じマシン上で2つの異なるクラスターを管理できません。GeoのセカンダリサイトのPatroniクラスターを設定する方法を説明する同じ手順に従って、トラッキングデータベースの新しいPatroniクラスターをセットアップする必要があります。

セカンダリノードは新しいトラッキングデータベースをバックフィルし、データの同期は必要ありません。

トラッキングPostgreSQLデータベースのPatroniクラスターの設定

セカンダリGeoサイトは、別のPostgreSQLインストールをトラッキングデータベースとして使用して、レプリケーションのステータスを追跡し、潜在的なレプリケーションの問題から自動的に回復します。

単一のノードでGeoトラッキングデータベースを実行する場合は、GeoセカンダリサイトでGeoトラッキングデータベースを設定するを参照してください。

Linuxパッケージは、高可用性設定でのGeoトラッキングデータベースの実行をサポートしていません。特に、フェイルオーバーは正しく機能しません。機能リクエストイシューを参照してください。

高可用性設定でGeoトラッキングデータベースを実行する場合は、セカンダリサイトをクラウド管理データベースなどの外部PostgreSQLデータベース、または手動で設定されたPatroniクラスター(GitLab Linuxパッケージで管理されていない)に接続できます。外部PostgreSQLインスタンスを使用したGeoに従ってください。

トラブルシューティング

トラブルシューティングドキュメントをお読みください。