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

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

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

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

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

セカンダリGeoサイトがプライマリGeoサイトと同じGitLab Enterprise Editionのバージョンを実行していることを確認してください。プライマリGeoサイトに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)

例えば、プライマリGeoサイトで設定されたpatroni['password']の値は、すべてのセカンダリGeoサイトのpatroni['password']の値と同一でなければなりません。

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

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

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

単一インスタンスは、Patroniを使用してクラスター化されたバージョンに拡張できます。これは高可用性アーキテクチャに推奨されます。

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

PostgreSQLレプリケーション

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

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

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

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

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

ステップ1.プライマリGeoサイトを構成する

  1. あなたのGitLabプライマリGeoサイトに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/administration/geo_sites/#common-settings
    ##
    gitlab_rails['geo_node_name'] = '<site_name_here>'
  4. 変更を有効にするため、プライマリGeoサイトを再構成します:

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

    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では、セカンダリGeoサイトがプライマリGeoサイトのデータベースに接続できる必要があります。このため、各GeoサイトのIPアドレスが必要です。

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

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

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

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

    ほとんどの場合、GitLab Geoを構成するには、以下のアドレスが使用されます:

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

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

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

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

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

    /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. オプション。別のセカンダリGeoサイトを追加したい場合は、関連する設定は次のようになります:

    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がプライマリGeoサイトのプライベートアドレスへのポート5432でリッスンしていることを確認します。

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

    cat ~gitlab-psql/data/server.crt

    この出力をクリップボードにコピーするか、ローカルファイルに保存します。セカンダリGeoサイトを設定するときに必要になります!この証明書は機密データではありません。

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

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

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

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

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

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

ステップ2.セカンダリサーバーを構成する

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

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

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

    gitlab-ctl stop puma
    gitlab-ctl stop sidekiq

    このステップは、Geoサイトが完全に構成される前に何も実行しないようにするために重要です。

  4. プライマリGeoサイトのPostgreSQLサーバーへのTCP接続を確認します:

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

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

  5. セカンダリGeoサイトにserver.crtファイルを作成します。内容はプライマリGeoサイトの設定の最後のステップで取得したものです:

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

    gitlab-psqlユーザー用にserver.crtファイルをインストールします:

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

    PostgreSQLは、TLS接続を検証する際に、その正確な証明書のみを認識します。証明書は、プライベートキーにアクセスできる人によってのみレプリケートすることができます。これはプライマリGeoサイトにonly存在します。

    gitlab-ctl replicate-geo-databaseはrootとして実行されるため、rootユーザーにも証明書をインストールします。そうでない場合、レプリケーションコマンドはcould not open certificate fileエラーで失敗します(sslmode=verify-caまたはsslmode=verify-fullを使用する場合):

    install \
       -D \
       -o root \
       -g root \
       -m 0400 \
       -T server.crt /root/.postgresql/root.crt
  7. gitlab-psqlユーザーがプライマリGeoサイトのデータベースに接続できることをテストします(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ユーザーに設定したプレーンテキストパスワードを入力します。すべてが正しく機能した場合、プライマリGeoサイトのデータベースのリストが表示されるはずです。

    ここでの接続失敗は、TLS設定が正しくないことを示します。プライマリGeoサイトの~gitlab-psql/data/server.crtの内容が、セカンダリGeoサイトの~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インスタンスについては、追加の手順を参照してください。以前のプライマリGeoサイトをセカンダリGeoサイトとして再稼働させる場合は、roles(['geo_primary_role'])またはgeo_primary_role['enable'] = trueも削除する必要があります。

  10. 変更を反映するためにGitLabを再設定します:

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

    gitlab-ctl restart postgresql

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

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

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

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

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

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

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

    各Geoサイトのセカンダリ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で使用すると、このコマンドの--host値と一致しない汎用的なPostgreSQL CNがあるため、失敗します。

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

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

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

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

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

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

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

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

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

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

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

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

    希望するパスワードの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

パスワードがセカンダリGeoサイトで更新されるまで、セカンダリのPostgreSQLログは以下のエラーメッセージを報告します:

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

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

  1. 最初のステップは、ハッシュ化された'sql_replication_password'がGitLab GeoセカンダリGeoサイトで使用されないため、設定の観点からは必要ありません。ただし、セカンダリGeoサイトがGitLab Geoプライマリにプロモートされる必要がある場合は、セカンダリ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レプリケーションプロセスによって使用され、デフォルトで/var/opt/gitlab/postgresql/data/gitlab-geo.confにPostgreSQLデータディレクトリに書き込まれます。
    • .pgpass: gitlab-psqlユーザーによって使用され、デフォルトで/var/opt/gitlab/postgresql/.pgpassにあります。

    これら両方のファイルでプレーンテキストパスワードを更新し、PostgreSQLを再起動します:

    sudo gitlab-ctl restart postgresql

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

単一PostgreSQLノードをPatroniに移行する

Patroniの導入前は、GeoはセカンダリGeoサイトでのHA設定に対するLinuxパッケージインストールをサポートしていませんでした。

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

  1. セカンダリGeoサイトにConsulクラスターが設定されていることを確認してください(プライマリGeoサイトでの設定方法と同様)。
  2. 永続的なレプリケーションスロットを構成します。
  3. 内部ロードバランサーを構成します。
  4. PgBouncerノードを構成
  5. その単一ノードマシン上にスタンバイクラスターを構成します。

最終的に、単一ノードを持つStandby Clusterになります。これにより、以前にリストされたのと同じ手順に従って、追加のPatroniノードを追加できます。

Patroniサポート

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

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

GeoセカンダリGeoサイト用のPatroniクラスターを構成する

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

本番環境対応で安全な設定には、少なくとも以下が必要です:

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

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

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

ステップ1.プライマリGeoサイトでPatroni永続レプリケーションスロットを構成する

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

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

プライマリGeoサイトでPatroniインスタンスを実行している各ノードで、starting on the Patroni Leader instance:

  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. プライマリGeoサイトで永続レプリケーションスロットを構成します

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

    プライマリGeoサイトでpgbouncerユーザーを構成し、Linuxパッケージに含まれるPgBouncerに必要なpg_shadow_lookup関数を追加します。セカンダリサーバー上のPgBouncerは、引き続きセカンダリGeoサイト上の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.プライマリGeoサイトで内部ロードバランサーを構成する

プライマリGeoサイトで新しいリーダーが選出されるたびにセカンダリGeoサイトでスタンバイリーダーを再構成するのを避けるため、TCP内部ロードバランサーを設定する必要があります。このロードバランサーは、Patroniクラスターのリーダーに接続するための単一のエンドポイントを提供します。

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

以下のIPと名前は例として使用されます:

  • 10.6.0.21: Patroni 1(patroni1.internal
  • 10.6.0.22: Patroni 2(patroni2.internal
  • 10.6.0.23: Patroni 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.セカンダリGeoサイトでPgBouncerノードを構成する

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

セカンダリGeoサイトで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.セカンダリGeoサイトでスタンバイクラスターを構成する

単一のPostgreSQLインスタンスを持つセカンダリGeoサイトをPatroniクラスターに変換する場合、PostgreSQLインスタンスから開始する必要があります。それがPatroniスタンバイリーダーインスタンスとなり、必要に応じて別のレプリカに切り替えることができます。

セカンダリGeoサイトで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. リーダー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はセカンダリGeoサイトでのHA設定に対するLinuxパッケージインストールをサポートしていませんでした。

Patroniを使用すると、HA設定をサポートできるようになりました。ただし、Patroniには、同じマシン上で2つの異なるクラスターを管理することを妨げるいくつかの制限があります。GeoセカンダリGeoサイト用のPatroniクラスターを構成する方法を説明するのと同じ手順に従って、追跡するデータベース用の新しいPatroniクラスターを設定する必要があります。

セカンダリノードが新しい追跡データベースをバックフィルするため、データ同期は必要ありません。

追跡するPostgreSQLデータベース用のPatroniクラスターを構成する

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

Geo追跡するデータベースを単一ノードで実行したい場合は、GeoセカンダリGeoサイトでGeo追跡するデータベースを構成を参照してください。

Linuxパッケージは、Geo追跡するデータベースを高可用性構成で実行することをサポートしていません。特に、フェイルオーバーは正しく機能しません。機能リクエストイシューを参照してください。

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

トラブルシューティング

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