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

このドキュメントでは、プライマリGitLabデータベースをセカンダリサイトのデータベースにレプリケートするために最低限必要な手順を説明します。データベースのセットアップやサイズなどの属性に応じて、いくつかの値を変更する必要があるかもしれません。

note
GitLabインストールが外部のPostgreSQLインスタンス(Linuxパッケージインストールによって管理されていない)を使用している場合、ロールは必要な設定ステップをすべて実行することはできません。この場合、代わりにGeo with external PostgreSQL instancesプロセスを使用してください。
note
セットアッププロセスのステージは、文書化された順序で完了する必要があります。そうでない場合は、先に進む前にすべてのステージを完了してください。

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

テスト環境や本番環境で実行する前に、これらの手順をすべて読んでレビューしてください。

シングルインスタンス・データベースのレプリケーション

シングル インスタンス データベースのレプリケーションはセットアップが簡単で、クラスター化されたものと同様の Geo 機能を提供します。単一マシンで実行しているセットアップや、将来のクラスター化に向けて Geo を評価しようとしている場合に便利です。

シングルインスタンスは、Patroni を使用してクラスタ化バージョンに拡張することができます。

PostgreSQLのレプリケーションをシングルインスタンスデータベースとして設定する方法については、以下の説明に従ってください。また、Patroniクラスタによるレプリケーションの設定方法については、マルチノードデータベースレプリケーションの説明を参照してください。

PostgreSQLレプリケーション

書き込みオペレーションを行うGitLabプライマリサイトは プライマリデータベースサーバーに接続します。セカンダリサイトはそれぞれのデータベースサーバー(読み込み専用)に接続します。

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

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

  • Linuxパッケージを使用している(つまり、PostgreSQL 12以降を使用している)こと、pg_basebackup ツールが含まれていること。
  • プライマリサイト(複製元となるGitLabサーバー)がすでにセットアップされていて、Linuxパッケージのインストールによって管理されているPostgreSQL(あるいは同等のバージョン)が稼働していること。そして、新しいセカンダリサイトがセットアップされていて、すべてのサイトで同じバージョンのPostgreSQL、OS、GitLabが稼働していること。
caution
Geoはストリーミングレプリケーションで動作します。論理レプリケーションは現時点ではサポートされていません。サポートが検討されているイシューがあります。

ステップ 1.プライマリ・サイトの設定

  1. SSHでGitLabのプライマリサイトに入り、rootでログインします:

    sudo -i
    
  2. /etc/gitlab/gitlab.rb を編集し、サイトのユニークな名前を追加します:

    ##
    ## 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>'
    
  3. プライマリ・サイトを再設定して、変更を有効にします:

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

    gitlab-ctl set-geo-primary-node
    

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

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

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

    gitlab-ctl pg-password-md5 gitlab
    # Enter password: <your_password_here>
    # Confirm password: <your_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_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_password_here>'
    
  6. データベース・レプリケーション・ユーザーのパスワードを定義します。

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

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

    gitlab-ctl pg-password-md5 gitlab_replicator
    # Enter password: <your_password_here>
    # Confirm password: <your_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_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>';
    
  7. /etc/gitlab/gitlab.rb を編集し、ロールをgeo_primary_role に設定します(詳細については、Geo ロールを参照してください):

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

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

    note
    外部の 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")"
    

    多くの場合、Geoサイトの設定には以下のアドレスが使われます:

    設定アドレス
    postgresql['listen_address'] プライマリサイトの公開アドレスまたはVPC非公開アドレス。
    postgresql['md5_auth_cidr_addresses'] プライマリサイトと セカンダリサイトの公開アドレスまたはVPC非公開アドレス。

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

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

    note
    0.0.0.0 または*listen_addressとして使用する必要がある場合は、postgresql['md5_auth_cidr_addresses'] の設定に127.0.0.1/32 を追加し、Rails が127.0.0.1を介して接続できるようにする必要があります。詳細はイシュー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
    
  9. PostgreSQLが再起動され、非公開アドレスでリッスンされるまで、データベースの自動マイグレーションを一時的に無効にしてください。/etc/gitlab/gitlab.rb を編集し、設定を false に変更します:

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

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

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

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

    gitlab-ctl reconfigure
    

    変更を有効にするためにPostgreSQLを再起動します:

    gitlab-ctl restart postgresql
    
  12. PostgreSQLが再起動し、非公開アドレスでリッスンするようになったので、マイグレーションを再度有効にしてください。

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

    gitlab_rails['auto_migrate'] = true
    

    ファイルを保存して GitLab を再設定してください:

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

  14. GitLabの再設定時に証明書が自動的に生成されました。これはPostgreSQLのトラフィックを盗聴者から保護するために自動的に使用されます。アクティブな(”man-in-the-middle”)攻撃者から守るために、セカンダリサイトには証明書のコピーが必要です。このコマンドを実行して、プライマリサイトのPostgreSQLserver.crt ファイルのコピーを作成してください:

    cat ~gitlab-psql/data/server.crt
    

    出力をクリップボードかローカルファイルにコピーしてください。セカンダリ・サイトを設定する際に必要です!証明書は機密データではありません。

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

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

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

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

    今後は、上記の証明書の代わりに、この証明書(postgresql['ssl_cert_file'] で設定した証明書)を使用できます。これにより、CNが一致する場合、レプリケーションエラーを起こさずにverify-full

ステップ2.セカンダリサーバの設定

  1. GitLabのセカンダリサイトにSSHで入り、rootでログインします:

    sudo -i
    
  2. アプリケーションサーバーとSidekiqを停止します。

    gitlab-ctl stop puma
    gitlab-ctl stop sidekiq
    
    note
    このステップは、サイトが完全に設定される前に何かを実行しようとしないようにするために重要です。
  3. プライマリ・サイトのPostgreSQLサーバへのTCP接続を確認してください:

    gitlab-rake gitlab:tcp_check[<primary_site_ip>,5432]
    
    note
    この手順に失敗した場合は、間違ったIPアドレスを使用しているか、ファイアウォールがサイトへのアクセスを妨げている可能性があります。公開アドレスと非公開アドレスの違いに注意しながら、IPアドレスを確認してください。ファイアウォールが存在する場合、セカンダリ・サイトがポート 5432 でプライマリ・サイトへの接続を許可されていることを確認します。
  4. セカンダリ・サイトにプライマリ・サイトのセットアップの最後のステップで取得した内容で、ファイルserver.crt を作成します:

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

    server.crt ファイルをインストールしてください:

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

    PostgreSQLはTLS接続を検証する際にその証明書のみを認識するようになりました。この証明書は、プライマリサイトにしか存在しない秘密鍵にアクセスできる人だけが複製できます。

  6. 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>
    
    note
    手動で生成した証明書を使用しており、完全なホスト名検証を利用するためにsslmode=verify-full を使用したい場合は、コマンドを実行する際にverify-caverify-full に置き換えてください。

    プロンプトが表示されたら、最初の手順で設定した_平文の_パスワードをgitlab_replicator ユーザに入力します。すべてが正しく動作していれば、プライマリ・サイトのデータベースのリストが表示されるはずです。

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

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

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

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

    /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_password>'
    postgresql['sql_user_password'] = '<md5_hash_of_your_password>'
    gitlab_rails['db_password'] = '<your_password_here>'
    

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

  9. 変更を有効にするために GitLab を再設定します:

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

    gitlab-ctl restart postgresql
    

ステップ3.レプリケーション処理の開始

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

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

caution
pg_basebackup を実行する前にPostgreSQLのデータをすべて削除しますので、必ずセカンダリサイトで実行してください。
  1. GitLabのセカンダリサイトにSSHで入り、rootでログインします:

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

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

    caution
    各Geoセカンダリサイトは、それぞれ固有のレプリケーションスロット名を持っている必要があります。2つのセカンダリ間で同じスロット名を使用すると、PostgreSQL レプリケーションが壊れます。
    note
    レプリケーションスロット名には小文字、数字、アンダースコア文字のみを含める必要があります。

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

    gitlab-ctl replicate-geo-database \
       --slot-name=<secondary_site_name> \
       --host=<primary_site_ip> \
       --sslmode=verify-ca
    
    note
    カスタムPostgreSQL証明書を生成した場合、--sslmode=verify-full (またはsslmode 行を完全に省略)して、証明書のCN/SANにおける完全なホスト名の検証を行い、セキュリティを強化する必要があります。そうでない場合、自動的に作成された証明書をverify-full で使用すると、このコマンドの--host の値と一致しない一般的なPostgreSQL CN を持つため失敗します。

    このコマンドは、いくつかの追加オプションも取ります。--help 、それらをすべて列挙することができますが、ここではいくつかのヒントを示します:

    • PostgreSQLが非標準のポートをリスンしている場合は、--port= を追加してください。
    • データベースが大きすぎて30分で転送できない場合は、タイムアウトを増やす必要があります。例えば、最初のレプリケーションに1時間未満かかると予想される場合は、--backup-timeout=3600 を使用してください。
    • パス--sslmode=disable PostgreSQLのTLS認証を完全に省略することができます(例えば、ネットワーク経路が安全であることがわかっている場合や、サイト間VPNを使用している場合など)。公開インターネット上では安全ではありません
    • それぞれのsslmode についての詳細はPostgreSQLのドキュメントを参照してください。上記の手順は、受動的な盗聴者と能動的な “man-in-the-middle “攻撃者の両方から確実に保護されるように注意深く書かれています。
    • --slot-nameプライマリデータベースで使用するレプリケーションスロットの名前に変更してください。こ の ス ク リ プ ト は、 レ プ リ ケーシ ョ ン ス ロ ッ ト が存在 し ない場合は自動的に作成 し よ う と し ます。
    • 古いサイトを Geoセカンダリサイトに再利用する場合は、コマンドラインに--force を追加する必要があります。
    • 本番マシンでない場合は、--skip-backup を追加することで、バックアップステップを無効にすることができます。
    • PgBouncerを使用している場合、データベースホストを直接ターゲットにする必要があります。
    • プライマリサイトでPatroniを使用している場合、現在のリーダーホストをターゲットにする必要があります。
    • ロードバランサのプロキシ(例えば HAProxy)を使っていて、 それがプライマリの Patroni リーダをターゲットにしている場合は、 代わりにロードバランサのプロキシをターゲットにしてください。

これでレプリケーション処理は完了です。

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

PgBouncerはGitLab GeoでPostgreSQL接続をプールするために使用することができます。

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

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

Linuxパッケージ・インストールで管理されるPostgreSQLインスタンスを使用する場合に、レプリケーション・ユーザのパスワードを変更するには、以下の手順に従います:

Geoプライマリサイトで

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

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

    sudo gitlab-ctl pg-password-md5 gitlab_replicator
    # Enter password: <your_password_here>
    # Confirm password: <your_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_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"

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

  1. 'sql_replication_password' GitLab Geoセカンダリサイトでは 'sql_replication_password'ハッシュは'sql_replication_password' 使用さ 'sql_replication_password'れないため、設定の観点からは最初のステップは必要ありません。'sql_replication_password' しかし 'sql_replication_password''sql_replication_password' セカンダリサイトをGitLab Geoプライマリサイトに昇格させる必要があるイベントがある場合は、 'sql_replication_password' セカンダリサイトの設定に'sql_replication_password' マッチする '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_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
    

複数ノードデータベースレプリケーション

GitLab 14.0では、PatroniがrepmgrPostgreSQLの高可用性ソリューションとしてサポートされました。

note
もしまだrepmgrからPatroniにマイグレーションしていないのであれば、マイグレーションすることを強くお勧めします。

repmgrからPatroniへのマイグレーション

  1. マイグレーションを行う前に、プライマリサイトと セカンダリサイトの間にレプリケーションの遅延がないこと、レプリケーションが一時停止されていることを確認してください。GitLab 13.2以降では、gitlab-ctl geo-replication-pause 、Geoセカンダリデータベースノードのgitlab-ctl geo-replication-resume 、レプリケーションを一時停止したり再開したりすることができます。
  2. 指示に従ってrepmgrをPatroniにマイグレーションしてください。各プライマリサイトデータベースノードでPatroni を設定する際、patroni['replication_slots'] = { '<slot_name>' => 'physical' }gitlab.rb に追加します。<slot_name>セカンダリサイトのレプリケーションスロットの名前です。これにより、Patroniはレプリケーションスロットを永続的なものとして認識し、再起動時にドロップしないようにします。
  3. マイグレーション前にセカンダリサイトへのデータベースレプリケーションを一時停止していた場合は、プライマリサイトでPatroniが動作していることを確認した後にレプリケーションを再開します。

単一のPostgreSQLノードのPatroniへのマイグレーション

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

Patroniの導入により、このサポートが可能になりました。既存のPostgreSQLをPatroniにマイグレーションする場合:

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

シングルノードで_スタンバイクラスタを_構成します。上記と同じ手順でPatroniノードを追加することができます。

Patroniのサポート

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

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

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

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

repmgr Geo プライマリサイトで repmgr使用している場合は、Patroni へのrepmgr マイグレーション手順を参照してください repmgr

本番稼動可能でセキュアなセットアップには少なくとも以下のものが必要です:

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

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

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

ステップ1.プライマリサイトのPatroni永久レプリケーションスロットの設定

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

プライマリサイトのPatroniインスタンスを実行している各ノードで、Patroniリーダーインスタンスを起動します:

  1. PatroniインスタンスにSSHし、rootでログインします:

    sudo -i
    
  2. /etc/gitlab/gitlab.rb を編集し、以下を追加してください:

    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
    
  3. 変更を有効にするために GitLab を再設定します:

    gitlab-ctl reconfigure
    
ステップ 2.プライマリサイトの内部ロードバランサーの設定

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

Linuxパッケージにはロードバランサは含まれていません。HAProxyを使った方法を紹介します。

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

  • 10.6.0.21:パトロニ1 (patroni1.internal)
  • 10.6.0.22:パトロニ2 (patroni2.internal)
  • 10.6.0.23:パトロニ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 *:5000
    mode tcp
    option tcplog

    default_backend postgresql

backend postgresql
    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. SSHでPgBouncerノードにログインします:

    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. ConsulがPgBouncerをリロードできるように.pgpass 。尋ねられたら、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.セカンダリサイトにスタンバイクラスタを設定します。
note
単一のPostgreSQLインスタンスを持つセカンダリサイトをPatroniクラスタに変換する場合、PostgreSQLインスタンスで開始する必要があります。このインスタンスがPatroniスタンバイリーダインスタンスとなり、必要であれば他のレプリカに切り替えることができます。

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

  1. SSHでPatroniノードにログインしてください:

    sudo -i
    
  2. /etc/gitlab/gitlab.rb を編集し、以下を追加してください:

    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['db_password'] = 'POSTGRESQL_PASSWORD'
    gitlab_rails['enable'] = true
    gitlab_rails['auto_migrate'] = false
    
  3. 変更を有効にするために GitLab を再設定します。このステップはPostgreSQLのユーザーと設定をブートストラップするために必要です。

    • Patroniを新規にインストールする場合は、GitLabを再設定してください:

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

       gitlab-ctl stop 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
       gitlab-ctl start patroni
      

単一のトラッキングデータベースノードをPatroniにマイグレーションする場合

Patroni導入以前、GeoはセカンダリサイトのHAセットアップのためのLinuxパッケージインストールをサポートしていませんでした。

Patroniにより、HAセットアップをサポートすることが可能になりました。しかし、Patroniのいくつかの制限により、同じマシン上で2つの異なるクラスターを管理することができません。上記と同じ手順で、トラッキングデータベース用に新しいPatroniクラスターをセットアップしてください。

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

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

セカンダリサイトでは、レプリケーションステータスを追跡し、潜在的なレプリケーションの問題から自動的にリカバリするために、トラッキングデータベースとして別のPostgreSQLインストールを使用します。Linuxパッケージでは、roles(['geo_secondary_role']) を設定すると自動的に追跡データベースを設定します。

このデータベースを高可用性設定で実行したい場合は、上記のgeo_secondary_role 。代わりに、以下の指示に従ってください。

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

トラッキングPostgreSQL DBの本番環境でのセキュアなセットアップには、少なくとも3つのConsulノードが必要です:2つのPatroniノードと、セカンダリサイト上の1つのPgBouncerノード。

イシュー6587により、Consulは複数のサービスを追跡することができないため、これらはスタンバイクラスターデータベースに使用するノードとは異なる必要があります。

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

ステップ1.セカンダリサイトのPgBouncerノードの設定

PostgreSQL追跡データベースのPgBouncerサービスを実行している各ノードで、PgBouncerを設定します:

  1. SSHでPgBouncerノードにログインします:

    sudo -i
    
  2. /etc/gitlab/gitlab.rb を編集し、以下を追加してください:

    # Disable all components except Pgbouncer and Consul agent
    roles(['pgbouncer_role'])
       
    # PgBouncer configuration
    pgbouncer['users'] = {
      'pgbouncer': {
        password: 'PGBOUNCER_PASSWORD_HASH'
      }
    }
       
    pgbouncer['databases'] = {
      gitlabhq_geo_production: {
        user: 'pgbouncer',
        password: 'PGBOUNCER_PASSWORD_HASH'
      }
    }
       
    # Consul configuration
    consul['watchers'] = %w(postgresql)
       
    consul['configuration'] = {
      retry_join: %w[CONSUL_TRACKINGDB1_IP CONSUL_TRACKINGDB2_IP CONSUL_TRACKINGDB3_IP]
    }
       
    consul['monitoring_service_discovery'] =  true
       
    # GitLab database settings
    gitlab_rails['db_database'] = 'gitlabhq_geo_production'
    gitlab_rails['db_username'] = 'gitlab_geo'
    
  3. 変更を有効にするために GitLab を再設定します:

    gitlab-ctl reconfigure
    
  4. ConsulがPgBouncerをリロードできるように.pgpass 。尋ねられたら、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 restart pgbouncer
    

ステップ 2.Patroniクラスターの設定

セカンダリサイトでPostgreSQLトラッキングデータベース用のPatroniインスタンスを実行している各ノードで、Patroniクラスタを構成します:

  1. SSHでPatroniノードにログインしてください:

    sudo -i
    
  2. /etc/gitlab/gitlab.rb を編集し、以下を追加してください:

    # Disable all components except PostgreSQL, Patroni, and Consul
    roles(['patroni_role'])
       
    # Consul configuration
    consul['services'] = %w(postgresql)
       
    consul['configuration'] = {
      server: true,
      retry_join: %w[CONSUL_TRACKINGDB1_IP CONSUL_TRACKINGDB2_IP CONSUL_TRACKINGDB3_IP]
    }
       
    # PostgreSQL configuration
    postgresql['listen_address'] = '0.0.0.0'
    postgresql['hot_standby'] = 'on'
    postgresql['wal_level'] = 'replica'
       
    postgresql['pgbouncer_user_password'] = 'PGBOUNCER_PASSWORD_HASH'
    postgresql['sql_replication_password'] = 'POSTGRESQL_REPLICATION_PASSWORD_HASH'
    postgresql['sql_user_password'] = 'POSTGRESQL_PASSWORD_HASH'
       
    postgresql['md5_auth_cidr_addresses'] = [
       'PATRONI_TRACKINGDB1_IP/32', 'PATRONI_TRACKINGDB2_IP/32', 'PATRONI_TRACKINGDB3_IP/32', 'PATRONI_TRACKINGDB_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_TRACKINGDB1_IP/32 PATRONI_TRACKINGDB2_IP/32 PATRONI_TRACKINGDB3_IP/32
    ]
       
    # Patroni configuration
    patroni['username'] = 'PATRONI_API_USERNAME'
    patroni['password'] = 'PATRONI_API_PASSWORD'
    patroni['replication_password'] = 'PLAIN_TEXT_POSTGRESQL_REPLICATION_PASSWORD'
    patroni['postgresql']['max_wal_senders'] = 5 # A minimum of three for one replica, plus two for each additional replica
       
    # GitLab database settings
    gitlab_rails['db_database'] = 'gitlabhq_geo_production'
    gitlab_rails['db_username'] = 'gitlab_geo'
    gitlab_rails['enable'] = true
       
    # Disable automatic database migrations
    gitlab_rails['auto_migrate'] = false
    
  3. 変更を有効にするために GitLab を再設定します。このステップはPostgreSQLのユーザーと設定をブートストラップするために必要です:

    gitlab-ctl reconfigure
    

ステップ 3.セカンダリサイトのトラッキングデータベースの設定

gitlab-railssidekiqgeo-logcursor サービスを実行している各ノードについて:

  1. お使いのノードにSSH接続し、rootでログインします:

    sudo -i
    
  2. /etc/gitlab/gitlab.rb を編集し、以下の属性を追加します。他の属性を設定してもかまいませんが、以下の属性は必ず設定してください。

    # Tracking database settings
    geo_secondary['db_username'] = 'gitlab_geo'
    geo_secondary['db_password'] = 'PLAIN_TEXT_PGBOUNCER_PASSWORD'
    geo_secondary['db_database'] = 'gitlabhq_geo_production'
    geo_secondary['db_host'] = 'PATRONI_TRACKINGDB_PGBOUNCER_IP'
    geo_secondary['db_port'] = 6432
    geo_secondary['auto_migrate'] = false
       
    # Disable the tracking database service
    geo_postgresql['enable'] = false
    
  3. 変更を有効にするために GitLab を再設定します。

    gitlab-ctl reconfigure
    
  4. トラッキングデータベースのマイグレーションを実行します:

    gitlab-rake db:migrate:geo
    

トラブルシューティング

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