Geoデータベースのレプリケーション
このドキュメントでは、プライマリGitLabデータベースをセカンダリノードのデータベースにレプリケートするために必要な最小限の手順を説明します。 データベースのセットアップやサイズなどによって、いくつかの値を変更する必要があるかもしれません。
テスト/本番環境で実行する前に、まずすべてのステップに目を通すことをお勧めします。
PostgreSQL レプリケーション
書き込みオペレーションを行うGitLabプライマリノードは プライマリデータベースサーバーに接続し、セカンダリノードはそれぞれのデータベースサーバー(読み込み専用)に接続します。
プライマリノードが セカンダリノードの復旧に必要なすべてのデータを保持するために、PostgreSQLのレプリケーションスロットを使用することをお勧めします。 詳細は以下を参照してください。
以下のガイドは、それを前提としています:
- Omnibusを使用しているため、PostgreSQL 11以降を使用しており、
pg_basebackup
ツール と改良された外部データラッパーのサポートが含まれています。 - OmnibusのPostgreSQL(または同等のバージョン)が稼働しているプライマリノード(複製元のGitLabサーバー)がすでにセットアップされていて、すべてのノードでOS、PostgreSQL、GitLabのバージョンが同じで、新しいセカンダリサーバーがセットアップされているとします。
ステップ1.プライマリサーバーの設定
-
GitLabのプライマリサーバにSSH接続し、rootでログインします:
sudo -i
-
/etc/gitlab/gitlab.rb
を編集し、ノードに固有の名前を追加します:# The unique identifier for the Geo node. gitlab_rails['geo_node_name'] = '<node_name_here>'
-
変更を有効にするには、プライマリノードを再設定します:
gitlab-ctl reconfigure
-
以下のコマンドを実行して、ノードをプライマリ・ノードとして定義します:
gitlab-ctl set-geo-primary-node
このコマンドは
/etc/gitlab/gitlab.rb
で定義したexternal_url
を使用します。 -
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>'
-
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>';
-
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
-
オプション:別のセカンダリー・ノードを追加したい場合、関連する設定は以下のようになります:
postgresql['md5_auth_cidr_addresses'] = ['<primary_node_ip>/32', '<secondary_node_ip>/32', '<another_secondary_node_ip>/32']
また、データベースのレプリケーション要件に合わせて、
wal_keep_segments
とmax_wal_senders
を編集することもできます。 詳細は PostgreSQL- Replication のドキュメントを参照してください。 -
ファイルを保存し、データベースのリッスンの変更とレプリケーションスロットの変更が適用されるようにGitLabを再設定します:
gitlab-ctl reconfigure
変更を有効にするためにPostgreSQLを再起動してください:
gitlab-ctl restart postgresql
-
PostgreSQLが再起動し、非公開アドレスでリッスンしているため、移行を再度有効にしてください。
/etc/gitlab/gitlab.rb
を編集し、コンフィギュレーションをtrue
に変更します:gitlab_rails['auto_migrate'] = true
ファイルを保存し、GitLabを再設定します:
gitlab-ctl reconfigure
-
PostgreSQLサーバがリモート接続を受け付けるように設定されたので、
netstat -plnt | grep 5432
。 PostgreSQLがプライマリサーバの非公開アドレスのポート5432
をリスンしていることを確認してください。 -
GitLabの再設定時に証明書が自動的に生成されました。 これはPostgreSQLのトラフィックを盗聴者から守るために自動的に使われますが、能動的な(”man-in-the-middle”)攻撃者から守るために、セカンダリノードには証明書のコピーが必要です。 このコマンドを実行して、プライマリノードのPostgreSQL
server.crt
ファイルのコピーを作成します:cat ~gitlab-psql/data/server.crt
出力をクリップボードまたはローカルファイルにコピーします。セカンダリノードをセットアップする際に必要になります!証明書は機密データではありません。
ステップ2.セカンダリーサーバーの設定
-
GitLabのセカンダリサーバにSSHで接続し、rootでログインします:
sudo -i
-
アプリケーションサーバーとSidekiqの停止
gitlab-ctl stop puma gitlab-ctl stop sidekiq
注:このステップは、ノードが完全に設定される前に何かを実行しようとしないようにするために重要です。 -
プライマリ・ノードのPostgreSQLサーバへのTCP接続を確認します:
gitlab-rake gitlab:tcp_check[<primary_node_ip>,5432]
注:この手順が失敗する場合は、間違ったIPアドレスを使用しているか、ファイアウォールがサーバーへのアクセスを妨げている可能性があります。 公開アドレスと非公開アドレスの違いに注意してIPアドレスを確認し、ファイアウォールが存在する場合は、セカンダリノードがポート5432でプライマリノードへの接続を許可されていることを確認します。 -
セカンダリ・サーバに、プライマリ・ノードのセットアップの最後のステップで取得した内容のファイル
server.crt
を作成します:editor server.crt
-
セカンダリノードでPostgreSQLのTLS検証を設定します:
server.crt
ファイルをインストールします:install \ -D \ -o gitlab-psql \ -g gitlab-psql \ -m 0400 \ -T server.crt ~gitlab-psql/.postgresql/root.crt
PostgreSQLはTLS接続を検証する際に、その証明書のみを認識するようになりました。 この証明書は、プライマリノードにしか存在しない秘密鍵にアクセスできる人だけが複製することができます。
-
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
の内容と一致していることを確認してください。 -
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
も削除する必要があります。 -
変更を有効にするために GitLab を再設定します:
gitlab-ctl reconfigure
-
IPの変更を有効にするためにPostgreSQLを再起動し、再設定してください:
gitlab-ctl restart postgresql gitlab-ctl reconfigure
この最後の再構成により、FDW構成がプロビジョニングされ、有効になります。
ステップ3.レプリケーションの開始
以下に、セカンダリノード上のデータベースをプライマリノード上のデータベースに接続し、データベースをレプリケートし、ストリーミングレプリケーションに必要なファイルを作成するスクリプトを示します。
使用するディレクトリは、Omnibus で設定されているデフォルトです。 デフォルトを変更した場合は、ディレクトリとパスを置き換えて適切な設定を行ってください。
pg_basebackup
を実行する前にPostgreSQLのデータをすべて削除しますので、必ずセカンダリサーバ上で実行してください。-
GitLabのセカンダリサーバにSSHで接続し、rootでログインします:
sudo -i
-
セカンダリノードのレプリケーションスロット名として使用するデータベースフレンドリーな名前を選択します。たとえば、ドメインが
secondary.geo.example.com
の場合、以下のコマンドに示すようにスロット名としてsecondary_example
を使用できます。 -
以下のコマンドを実行してバックアップ/リストアを開始し、レプリケーションを開始します。
警告: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
- PostgreSQLが標準以外のポートでリッスンしている場合は、
これでレプリケーション・プロセスは完了です。
PgBouncerのサポート(オプション)
PgBouncerはPostgreSQL接続をプールするためにGitLab Geoと一緒に使うことができます。 Geoプライマリノードをサポートするノードのクラスターと、Geoセカンダリノードをサポートするノードの別のクラスターでGitLabを高可用性構成で使う場合は、PgBouncerを使うことをお勧めします。 詳細については、Omnibus GitLabでの高可用性を参照してください。
Geoセカンダリノードがデータベースの前でPgBouncerと正しく動作するためには、PostgreSQLのFDWクエリを動作させるために別の読み取り専用ユーザーが必要です:
-
プライマリGeo データベースで、コンソールの PostgreSQL に admin ユーザーとして入ります。 Omnibus 管理データベースを使用している場合は、PostgreSQL データベースを実行しているプライマリノードにログオンします(デフォルトの Omnibus データベース名は
gitlabhq_production
):sudo \ -u gitlab-psql /opt/gitlab/embedded/bin/psql \ -h /var/opt/gitlab/postgresql gitlabhq_production
-
次に、読み取り専用ユーザーを作成します:
-- 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;
-
セカンダリノードで、
/etc/gitlab/gitlab.rb
を変更します:geo_postgresql['fdw_external_user'] = 'gitlab_geo_fdw'
-
ファイルを保存し、変更が適用されるように GitLab を再設定します:
gitlab-ctl reconfigure
トラブルシューティング
トラブルシューティングをお読みください。