Consulのセットアップ方法
- プラン: Premium、Ultimate
- 提供形態: GitLab Self-Managed
Consulクラスターは、サーバーおよびクライアントエージェントの両方で構成されます。サーバーは独自のノードで実行され、クライアントはサーバーと通信する他のノードで実行されます。
GitLab Premiumには、/etc/gitlab/gitlab.rbを使用して管理できるサービスネットワーキングソリューションであるConsulのバンドルされたバージョンが含まれています。
前提条件
Consulの設定を行う前に、次のことを確認してください:
- リファレンスアーキテクチャドキュメントを確認して、必要なConsulサーバーノードの数を決定してください。
- 必要に応じて、ファイアウォールで適切なポートが開いていることを確認してください。
Consulノードを設定する
各Consulサーバーノードで、次の手順を実行します:
希望するプラットフォームを選択してGitLabをインストールする手順に従いますが、求められても
EXTERNAL_URLの値は入力しないでください。/etc/gitlab/gitlab.rbを編集し、retry_joinセクションに記載されている値を置き換えて以下を追加します。以下の例では、3つのノードがあり、2つはIPアドレスで、1つはFQDNで示されています。どちらの表記も使用できます:# Disable all components except Consul roles ['consul_role'] # Consul nodes: can be FQDN or IP, separated by a whitespace consul['configuration'] = { server: true, retry_join: %w(10.10.10.1 consul1.gitlab.example.com 10.10.10.2) } # Disable auto migrations gitlab_rails['auto_migrate'] = false変更を有効にするには、GitLabを再設定します。
Consulが正しく設定され、すべてのサーバーノードが通信していることを確認するために、次のコマンドを実行します:
sudo /opt/gitlab/embedded/bin/consul members出力は次のようになります:
Node Address Status Type Build Protocol DC CONSUL_NODE_ONE XXX.XXX.XXX.YYY:8301 alive server 0.9.2 2 gitlab_consul CONSUL_NODE_TWO XXX.XXX.XXX.YYY:8301 alive server 0.9.2 2 gitlab_consul CONSUL_NODE_THREE XXX.XXX.XXX.YYY:8301 alive server 0.9.2 2 gitlab_consul結果に
alive以外のステータスのノードが表示されている場合、または3つのノードのいずれかが不足している場合は、トラブルシューティングセクションを参照してください。
Consulノードの保護
Consulノード間の通信を保護する方法は、TLSまたはゴシップ暗号化の2通りあります。
TLS暗号化
デフォルトでは、Consulクラスターに対してTLSは有効になっていません。デフォルトの設定オプションとそのデフォルトは次のとおりです:
consul['use_tls'] = false
consul['tls_ca_file'] = nil
consul['tls_certificate_file'] = nil
consul['tls_key_file'] = nil
consul['tls_verify_client'] = nilこれらの設定オプションは、クライアントとサーバーの両方のノードに適用されます。
ConsulノードでTLSを有効にするには、consul['use_tls'] = trueから始めます。ノードの役割(サーバーまたはクライアント)とTLSの設定に応じて、さらに設定を行う必要があります:
- サーバーノードでは、少なくとも
tls_ca_file、tls_certificate_file、およびtls_key_fileを指定する必要があります。 - クライアントノードでは、クライアントTLS認証がサーバーで無効になっている場合(デフォルトで有効)、少なくとも
tls_ca_fileを指定する必要があります。そうでない場合は、tls_certificate_file、tls_key_fileを使用してクライアントTLS証明書とキーを渡す必要があります。
TLSが有効になっている場合、デフォルトではサーバーは相互TLSを使用し、HTTPSとHTTP(およびTLSと非TLS RPC)の両方でリッスンします。クライアントがTLS認証を使用することを想定しています。consul['tls_verify_client'] = falseを設定することで、クライアントTLS認証を無効にできます。
一方、クライアントはサーバーノードへの発信接続にのみTLSを使用し、受信リクエストにはHTTP(および非TLS RPC)のみをリッスンします。consul['https_port']を負ではない整数に設定することで、クライアントConsulエージェントに受信接続にTLSを使用させることができます(8501はConsulのデフォルトHTTPSポートです)。これが機能するには、tls_certificate_fileとtls_key_fileも渡す必要があります。サーバーノードがクライアントTLS認証を使用する場合、クライアントTLS証明書とキーはTLS認証と受信HTTPS接続の両方に使用されます。
Consulクライアントノードは、デフォルトではTLSクライアント認証を使用しません(サーバーとは対照的に)。consul['tls_verify_client'] = trueを設定して明示的に指示する必要があります。
以下はTLS暗号化の例です。
最小限のTLSサポート
以下の例では、サーバーは受信接続にTLSを使用します(クライアントTLS認証なし)。
/etc/gitlab/gitlab.rbを編集します。consul['enable'] = true consul['configuration'] = { 'server' => true } consul['use_tls'] = true consul['tls_ca_file'] = '/path/to/ca.crt.pem' consul['tls_certificate_file'] = '/path/to/server.crt.pem' consul['tls_key_file'] = '/path/to/server.key.pem' consul['tls_verify_client'] = falseGitLabを再設定します:
sudo gitlab-ctl reconfigure
例えば、Patroniノードで以下を設定できます。
/etc/gitlab/gitlab.rbを編集します。consul['enable'] = true consul['use_tls'] = true consul['tls_ca_file'] = '/path/to/ca.crt.pem' patroni['consul']['url'] = 'http://localhost:8500'GitLabを再設定します:
sudo gitlab-ctl reconfigure
PatroniはローカルのConsulエージェントと通信しますが、これは受信接続にTLSを使用しません。したがって、patroni['consul']['url']のHTTP URLが使用されます。
デフォルトのTLSサポート
以下の例では、サーバーは相互TLS認証を使用します。
/etc/gitlab/gitlab.rbを編集します。consul['enable'] = true consul['configuration'] = { 'server' => true } consul['use_tls'] = true consul['tls_ca_file'] = '/path/to/ca.crt.pem' consul['tls_certificate_file'] = '/path/to/server.crt.pem' consul['tls_key_file'] = '/path/to/server.key.pem'GitLabを再設定します:
sudo gitlab-ctl reconfigure
例えば、Patroniノードで以下を設定できます。
/etc/gitlab/gitlab.rbを編集します。consul['enable'] = true consul['use_tls'] = true consul['tls_ca_file'] = '/path/to/ca.crt.pem' consul['tls_certificate_file'] = '/path/to/client.crt.pem' consul['tls_key_file'] = '/path/to/client.key.pem' patroni['consul']['url'] = 'http://localhost:8500'GitLabを再設定します:
sudo gitlab-ctl reconfigure
PatroniはローカルのConsulエージェントと通信しますが、ConsulサーバーノードへのTLS認証を使用しているにもかかわらず、受信接続にTLSを使用しません。したがって、patroni['consul']['url']のHTTP URLが使用されます。
フルTLSサポート
以下の例では、クライアントとサーバーの両方が相互TLS認証を使用します。
Consulサーバー、クライアント、およびPatroniクライアント証明書は、相互TLS認証を機能させるために同じ認証局によって発行される必要があります。
/etc/gitlab/gitlab.rbを編集します。consul['enable'] = true consul['configuration'] = { 'server' => true } consul['use_tls'] = true consul['tls_ca_file'] = '/path/to/ca.crt.pem' consul['tls_certificate_file'] = '/path/to/server.crt.pem' consul['tls_key_file'] = '/path/to/server.key.pem'GitLabを再設定します:
sudo gitlab-ctl reconfigure
例えば、Patroniノードで以下を設定できます。
/etc/gitlab/gitlab.rbを編集します。consul['enable'] = true consul['use_tls'] = true consul['tls_verify_client'] = true consul['tls_ca_file'] = '/path/to/ca.crt.pem' consul['tls_certificate_file'] = '/path/to/client.crt.pem' consul['tls_key_file'] = '/path/to/client.key.pem' consul['https_port'] = 8501 patroni['consul']['url'] = 'https://localhost:8501' patroni['consul']['cacert'] = '/path/to/ca.crt.pem' patroni['consul']['cert'] = '/opt/tls/patroni.crt.pem' patroni['consul']['key'] = '/opt/tls/patroni.key.pem' patroni['consul']['verify'] = trueGitLabを再設定します:
sudo gitlab-ctl reconfigure
ゴシップ暗号化
ゴシッププロトコルは、Consulエージェント間の通信を保護するために暗号化された場合があります。デフォルトでは暗号化は有効になっていません。暗号化を有効にするには、共有暗号化キーが必要です。便宜上、gitlab-ctl consul keygenコマンドを使用してキーを生成できます。キーは32バイト長で、Base 64でエンコードされ、すべてのエージェントで共有される必要があります。
以下のオプションは、クライアントとサーバーの両方のノードで機能します。
ゴシッププロトコルを有効にするには:
/etc/gitlab/gitlab.rbを編集します。consul['encryption_key'] = <base-64-key> consul['encryption_verify_incoming'] = true consul['encryption_verify_outgoing'] = trueGitLabを再設定します:
sudo gitlab-ctl reconfigure
既存のデータセンターで暗号化を有効にするには、ローリングアップデートのためにこれらのオプションを手動で設定します。
Consulノードのアップグレード
Consulノードをアップグレードするには、GitLabパッケージをアップグレードします。
ノードは以下の条件を満たす必要があります:
- Linuxパッケージをアップグレードする前に、正常なクラスターのメンバーであること。
- 一度に1つのノードをアップグレードすること。
各ノードで次のコマンドを実行して、クラスター内の既存のヘルス上の問題を特定します。クラスターが正常であれば、コマンドは空の配列を返します:
curl "http://127.0.0.1:8500/v1/health/state/critical"Consulバージョンが変更された場合、gitlab-ctl reconfigureの最後に、新しいバージョンを使用するためにConsulを再起動する必要があることを示す通知が表示されます。
Consulを一度に1つのノードずつ再起動します:
sudo gitlab-ctl restart consulConsulノードはraftプロトコルを使用して通信します。現在のリーダーがオフラインになった場合、リーダー選挙が行われる必要があります。クラスター全体の同期を促進するには、リーダーノードが存在する必要があります。同時にあまりにも多くのノードがオフラインになると、クラスターはクォーラムを失い、合意が破られたためにリーダーを選出しません。
アップグレード後にクラスターがリカバリーできない場合は、トラブルシューティングセクションを参照してください。停止リカバリーが特に役立つ場合があります。
GitLabは、簡単に再生成できる一時的なデータのみをConsulに保存します。バンドルされたConsulがGitLab自体以外のプロセスで使用されていない場合、スクラッチからクラスターを再構築できます。
Consulのトラブルシューティング
以下は、問題をデバッグする場合のいくつかの操作です。次のコマンドを実行して、エラーログを確認できます:
sudo gitlab-ctl tail consulクラスターのメンバーシップを確認する
どのノードがクラスターの一部であるかを判断するには、クラスター内の任意のメンバーで次を実行します:
sudo /opt/gitlab/embedded/bin/consul members出力は次のようになります:
Node Address Status Type Build Protocol DC
consul-b XX.XX.X.Y:8301 alive server 0.9.0 2 gitlab_consul
consul-c XX.XX.X.Y:8301 alive server 0.9.0 2 gitlab_consul
consul-c XX.XX.X.Y:8301 alive server 0.9.0 2 gitlab_consul
db-a XX.XX.X.Y:8301 alive client 0.9.0 2 gitlab_consul
db-b XX.XX.X.Y:8301 alive client 0.9.0 2 gitlab_consul理想的には、すべてのノードのStatusがaliveであるべきです。
Consulを再起動する
Consulを再起動する必要がある場合は、クォーラムを維持するために制御された方法で行うことが重要です。クォーラムが失われた場合、クラスターをリカバリーするには、Consulの停止リカバリープロセスに従います。
安全のため、クラスターが破損しないように、一度に1つのノードでConsulを再起動することをお勧めします。大規模なクラスターの場合、一度に複数のノードを再起動することが可能です。耐えられる失敗の数については、Consul合意ドキュメントを参照してください。これは、同時に維持できる再起動の数です。
Consulを再起動するには:
sudo gitlab-ctl restart consulConsulノードが通信できない
デフォルトでは、Consulは0.0.0.0にバインドしようとしますが、他のConsulノードがそれと通信できるように、ノード上の最初のプライベートIPアドレスをアドバタイズします。他のノードがこのアドレスのノードと通信できない場合、クラスターは失敗したステータスになります。
この問題が発生した場合、gitlab-ctl tail consulに次のようなメッセージが出力されます:
2017-09-25_19:53:39.90821 2017/09/25 19:53:39 [WARN] raft: no known peers, aborting election
2017-09-25_19:53:41.74356 2017/09/25 19:53:41 [ERR] agent: failed to sync remote state: No cluster leaderこれを修正するには、次の手順に従います:
すべての他のノードがこのノードに到達できる、各ノード上のアドレスを選択します。
/etc/gitlab/gitlab.rbを更新します。consul['configuration'] = { ... bind_addr: 'IP ADDRESS' }GitLabを再設定します。
gitlab-ctl reconfigure
それでもエラーが表示される場合は、影響を受けたノードでConsulデータベースを消去して再初期化する必要がある場合があります。
Consulが起動しない - 複数のプライベートIP
ノードに複数のプライベートIPがある場合、Consulはどのアドレスをアドバタイズすべきか分からず、起動時にすぐに終了します。
gitlab-ctl tail consulに次のようなメッセージが出力されます:
2017-11-09_17:41:45.52876 ==> Starting Consul agent...
2017-11-09_17:41:45.53057 ==> Error creating agent: Failed to get advertise address: Multiple private IPs found. Please configure one.これを修正するには、次の手順に従います:
すべての他のノードがこのノードに到達できる、ノード上のアドレスを選択します。
/etc/gitlab/gitlab.rbを更新します。consul['configuration'] = { ... bind_addr: 'IP ADDRESS' }GitLabを再設定します。
gitlab-ctl reconfigure
停止リカバリー
クラスターのクォーラムを破るのに十分なConsulノードを失った場合、クラスターは失敗したと見なされ、手動での介入なしには機能できません。その場合、ノードをゼロから再作成するか、リカバリーを試みることができます。
スクラッチから再作成する
デフォルトでは、GitLabは再作成できないものをConsulノードに保存しません。Consulデータベースを消去して再初期化するには:
sudo gitlab-ctl stop consul
sudo rm -rf /var/opt/gitlab/consul/data
sudo gitlab-ctl start consulこの後、ノードは再起動し、残りのサーバーエージェントは再参加します。その後すぐに、クライアントエージェントも再参加するはずです。
参加しない場合は、クライアント上のConsulデータも消去する必要があるかもしれません:
sudo rm -rf /var/opt/gitlab/consul/data失敗したノードをリカバリーする
Consulを利用して他のデータを保存しており、失敗したノードを復元する場合は、Consulのガイドに従って失敗したクラスターをリカバリーしてください。