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

注意:GitLabのインストールで外部の(Omnibusで管理されていない)PostgreSQLインスタンスを使用している場合、Omnibusのロールは必要な設定手順をすべて実行することができません。 この場合は、代わりにGeo with external PostgreSQL instancesのドキュメントに従ってください。
注:セットアッププロセスのステージは、文書に記載された順序で完了する必要があります。 このステージのステップを試す前に、前のステージをすべて完了してください。

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

テスト/本番環境で実行する前に、まずすべてのステップに目を通すことをお勧めします。

PostgreSQL レプリケーション

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

プライマリノードが セカンダリノードの復旧に必要なすべてのデータを保持するために、PostgreSQLのレプリケーションスロットを使用することをお勧めします。 詳細は以下を参照してください。

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

  • Omnibusを使用しているため、PostgreSQL 11以降を使用しており、pg_basebackup ツール と改良された外部データラッパーのサポートが含まれています。
  • OmnibusのPostgreSQL(または同等のバージョン)が稼働しているプライマリノード(複製元のGitLabサーバー)がすでにセットアップされていて、すべてのノードでOS、PostgreSQL、GitLabのバージョンが同じで、新しいセカンダリサーバーがセットアップされているとします。
警告:Geoはストリーミング・レプリケーションで動作します。 論理レプリケーションは現時点ではサポートされていません。サポートが検討されているイシューがあります。

ステップ1.プライマリサーバーの設定

  1. GitLabのプライマリサーバにSSH接続し、rootでログインします:

    sudo -i
    
  2. /etc/gitlab/gitlab.rb を編集し、ノードに固有の名前を追加します:

    # The unique identifier for the Geo node.
    gitlab_rails['geo_node_name'] = '<node_name_here>'
    
  3. 変更を有効にするには、プライマリノードを再設定します:

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

    gitlab-ctl set-geo-primary-node
    

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

  5. GitLab 10.4 以降のみ: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. Omnibus GitLabにはすでにgitlab_replicatorというレプリケーション・ユーザーがいます。 このユーザーのパスワードは手動で設定する必要があります。 パスワードを入力するプロンプトが表示されます:

    gitlab-ctl set-replication-password
    

    このコマンドは、gitlab_replicator ユーザー名を他のものに変更した場合にpostgresql['sql_replication_user'] Omnibus の設定も読み込みます。

    GitLabが管理していない外部データベースを使用する場合は、レプリケーターユーザーを作成し、パスワードを手動で定義する必要があります:

    --- 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. PostgreSQLがネットワークインタフェースをリッスンするように設定してください:

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

    注意:外部の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 Cloud Platform、SoftLayer、または仮想プライベートクラウドを提供するその他のベンダーを使用している場合、(VPC) 、プライマリと セカンダリのノードの非公開アドレス(Google Cloud Platformの「内部アドレス」に相当)を** 、postgresql['listen_address']

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

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

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

    ##
    ## Geo Primary role
    ## - configure dependent flags automatically to enable Geo
    ##
    roles ['geo_primary_role']
    
    ##
    ## Primary address
    ## - replace '<primary_node_ip>' with the public or VPC address of your Geo primary node
    ##
    postgresql['listen_address'] = '<primary_node_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_node_ip>/32', '<secondary_node_ip>/32']
    
    ##
    ## Replication settings
    ## - set this to be the number of Geo secondary nodes you have
    ##
    postgresql['max_replication_slots'] = 1
    # postgresql['max_wal_senders'] = 10
    # postgresql['wal_keep_segments'] = 10
    
    ##
    ## Disable automatic database migrations temporarily
    ## (until PostgreSQL is restarted and listening on the private address).
    ##
    gitlab_rails['auto_migrate'] = false
    
  8. オプション:別のセカンダリー・ノードを追加したい場合、関連する設定は以下のようになります:

    postgresql['md5_auth_cidr_addresses'] = ['<primary_node_ip>/32', '<secondary_node_ip>/32', '<another_secondary_node_ip>/32']
    

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

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

    gitlab-ctl reconfigure
    

    変更を有効にするためにPostgreSQLを再起動してください:

    gitlab-ctl restart postgresql
    
  10. PostgreSQLが再起動し、非公開アドレスでリッスンしているため、移行を再度有効にしてください。

    /etc/gitlab/gitlab.rb を編集し、コンフィギュレーションをtrue変更します:

    gitlab_rails['auto_migrate'] = true
    

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

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

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

    cat ~gitlab-psql/data/server.crt
    

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

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

  1. GitLabのセカンダリサーバにSSHで接続し、rootでログインします:

    sudo -i
    
  2. アプリケーションサーバーとSidekiqの停止

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

    gitlab-rake gitlab:tcp_check[<primary_node_ip>,5432]
    
    注:この手順が失敗する場合は、間違った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 ユーザがプライマリ・ノードのデータベース(デフォルトの Omnibus データベース名は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_node_ip>
    

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

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

  7. FDWサポートを有効にするためにPostgreSQLを設定してください:

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

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

    ##
    ## Geo Secondary role
    ## - configure dependent flags automatically to enable Geo
    ##
    roles ['geo_secondary_role']
    
    ##
    ## Secondary address
    ## - replace '<secondary_node_ip>' with the public or VPC address of your Geo secondary node
    ##
    postgresql['listen_address'] = '<secondary_node_ip>'
    postgresql['md5_auth_cidr_addresses'] = ['<secondary_node_ip>/32']
    
    ##
    ## Database credentials password (defined previously in primary node)
    ## - replicate same values here as defined in primary node
    ##
    postgresql['sql_user_password'] = '<md5_hash_of_your_password>'
    gitlab_rails['db_password'] = '<your_password_here>'
    
    ##
    ## Enable FDW support for the Geo Tracking Database (improves performance)
    ##
    geo_secondary['db_fdw'] = true
    

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

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

    gitlab-ctl reconfigure
    
  9. IPの変更を有効にするためにPostgreSQLを再起動し、再設定してください:

    gitlab-ctl restart postgresql
    gitlab-ctl reconfigure
    

    この最後の再構成により、FDW構成がプロビジョニングされ、有効になります。

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

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

使用するディレクトリは、Omnibus で設定されているデフォルトです。 デフォルトを変更した場合は、ディレクトリとパスを置き換えて適切な設定を行ってください。

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

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

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

    警告:Geoセカンダリノードにはそれぞれ固有のレプリケーションスロット名が必要です。 2つのセカンダリ間で同じスロット名を使用すると、PostgreSQLのレプリケーションが壊れてしまいます。
    gitlab-ctl replicate-geo-database \
       --slot-name=<secondary_node_name> \
       --host=<primary_node_ip>
    
    注意:レプリケーション・スロット名には、小文字、数字、アンダースコア文字のみを含める必要があります。

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

    このコマンドには、さらにいくつかのオプションがあります。--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のサポート(オプション)

PgBouncerはPostgreSQL接続をプールするためにGitLab Geoと一緒に使うことができます。 Geoプライマリノードをサポートするノードのクラスターと、Geoセカンダリノードをサポートするノードの別のクラスターでGitLabを高可用性構成で使う場合は、PgBouncerを使うことをお勧めします。 詳細については、Omnibus GitLabでの高可用性を参照してください。

Geoセカンダリノードがデータベースの前でPgBouncerと正しく動作するためには、PostgreSQLのFDWクエリを動作させるために別の読み取り専用ユーザーが必要です:

  1. プライマリGeo データベースで、コンソールの PostgreSQL に admin ユーザーとして入ります。 Omnibus 管理データベースを使用している場合は、PostgreSQL データベースを実行しているプライマリノードにログオンします(デフォルトの Omnibus データベース名はgitlabhq_production):

     sudo \
        -u gitlab-psql /opt/gitlab/embedded/bin/psql \
        -h /var/opt/gitlab/postgresql gitlabhq_production
    
  2. 次に、読み取り専用ユーザーを作成します:

    -- NOTE: Use the password defined earlier
    CREATE USER gitlab_geo_fdw WITH password 'mypassword';
    GRANT CONNECT ON DATABASE gitlabhq_production to gitlab_geo_fdw;
    GRANT USAGE ON SCHEMA public TO gitlab_geo_fdw;
    GRANT SELECT ON ALL TABLES IN SCHEMA public TO gitlab_geo_fdw;
    GRANT SELECT ON ALL SEQUENCES IN SCHEMA public TO gitlab_geo_fdw;
    
    -- Tables created by "gitlab" should be made read-only for "gitlab_geo_fdw"
    -- automatically.
    ALTER DEFAULT PRIVILEGES FOR USER gitlab IN SCHEMA public GRANT SELECT ON TABLES TO gitlab_geo_fdw;
    ALTER DEFAULT PRIVILEGES FOR USER gitlab IN SCHEMA public GRANT SELECT ON SEQUENCES TO gitlab_geo_fdw;
    
  3. セカンダリノードで/etc/gitlab/gitlab.rbを変更します:

    geo_postgresql['fdw_external_user'] = 'gitlab_geo_fdw'
    
  4. ファイルを保存し、変更が適用されるように GitLab を再設定します:

    gitlab-ctl reconfigure
    

トラブルシューティング

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