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

Consulのセットアップ方法

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

Consulクラスターは、サーバーおよびクライアントエージェントの両方で構成されます。サーバーは独自のノードで実行され、クライアントはサーバーと通信する他のノードで実行されます。

GitLab Premiumには、/etc/gitlab/gitlab.rbを使用して管理できるサービスネットワーキングソリューションであるConsulのバンドルされたバージョンが含まれています。

前提条件

Consulの設定を行う前に、次のことを確認してください:

  1. リファレンスアーキテクチャドキュメントを確認して、必要なConsulサーバーノードの数を決定してください。
  2. 必要に応じて、ファイアウォールで適切なポートが開いていることを確認してください。

Consulノードを設定する

各Consulサーバーノードで、次の手順を実行します:

  1. 希望するプラットフォームを選択してGitLabをインストールする手順に従いますが、求められてもEXTERNAL_URLの値は入力しないでください。

  2. /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
  3. 変更を有効にするには、GitLabを再設定します

  4. 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_filetls_certificate_file、およびtls_key_fileを指定する必要があります。
  • クライアントノードでは、クライアントTLS認証がサーバーで無効になっている場合(デフォルトで有効)、少なくともtls_ca_fileを指定する必要があります。そうでない場合は、tls_certificate_filetls_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_filetls_key_fileも渡す必要があります。サーバーノードがクライアントTLS認証を使用する場合、クライアントTLS証明書とキーはTLS認証と受信HTTPS接続の両方に使用されます。

Consulクライアントノードは、デフォルトではTLSクライアント認証を使用しません(サーバーとは対照的に)。consul['tls_verify_client'] = trueを設定して明示的に指示する必要があります。

以下はTLS暗号化の例です。

最小限のTLSサポート

以下の例では、サーバーは受信接続にTLSを使用します(クライアントTLS認証なし)。

  1. /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'] = false
  2. GitLabを再設定します:

    sudo gitlab-ctl reconfigure

例えば、Patroniノードで以下を設定できます。

  1. /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'
  2. GitLabを再設定します:

    sudo gitlab-ctl reconfigure

PatroniはローカルのConsulエージェントと通信しますが、これは受信接続にTLSを使用しません。したがって、patroni['consul']['url']のHTTP URLが使用されます。

デフォルトのTLSサポート

以下の例では、サーバーは相互TLS認証を使用します。

  1. /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'
  2. GitLabを再設定します:

    sudo gitlab-ctl reconfigure

例えば、Patroniノードで以下を設定できます。

  1. /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'
  2. GitLabを再設定します:

    sudo gitlab-ctl reconfigure

PatroniはローカルのConsulエージェントと通信しますが、ConsulサーバーノードへのTLS認証を使用しているにもかかわらず、受信接続にTLSを使用しません。したがって、patroni['consul']['url']のHTTP URLが使用されます。

フルTLSサポート

以下の例では、クライアントとサーバーの両方が相互TLS認証を使用します。

Consulサーバー、クライアント、およびPatroniクライアント証明書は、相互TLS認証を機能させるために同じ認証局によって発行される必要があります。

  1. /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'
  2. GitLabを再設定します:

    sudo gitlab-ctl reconfigure

例えば、Patroniノードで以下を設定できます。

  1. /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'] = true
  2. GitLabを再設定します:

    sudo gitlab-ctl reconfigure

ゴシップ暗号化

ゴシッププロトコルは、Consulエージェント間の通信を保護するために暗号化された場合があります。デフォルトでは暗号化は有効になっていません。暗号化を有効にするには、共有暗号化キーが必要です。便宜上、gitlab-ctl consul keygenコマンドを使用してキーを生成できます。キーは32バイト長で、Base 64でエンコードされ、すべてのエージェントで共有される必要があります。

以下のオプションは、クライアントとサーバーの両方のノードで機能します。

ゴシッププロトコルを有効にするには:

  1. /etc/gitlab/gitlab.rbを編集します。

    consul['encryption_key'] = <base-64-key>
    consul['encryption_verify_incoming'] = true
    consul['encryption_verify_outgoing'] = true
  2. GitLabを再設定します:

    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 consul

Consulノードは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

理想的には、すべてのノードのStatusaliveであるべきです。

Consulを再起動する

Consulを再起動する必要がある場合は、クォーラムを維持するために制御された方法で行うことが重要です。クォーラムが失われた場合、クラスターをリカバリーするには、Consulの停止リカバリープロセスに従います。

安全のため、クラスターが破損しないように、一度に1つのノードでConsulを再起動することをお勧めします。大規模なクラスターの場合、一度に複数のノードを再起動することが可能です。耐えられる失敗の数については、Consul合意ドキュメントを参照してください。これは、同時に維持できる再起動の数です。

Consulを再起動するには:

sudo gitlab-ctl restart consul

Consulノードが通信できない

デフォルトでは、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

これを修正するには、次の手順に従います:

  1. すべての他のノードがこのノードに到達できる、各ノード上のアドレスを選択します。

  2. /etc/gitlab/gitlab.rbを更新します。

    consul['configuration'] = {
      ...
      bind_addr: 'IP ADDRESS'
    }
  3. 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.

これを修正するには、次の手順に従います:

  1. すべての他のノードがこのノードに到達できる、ノード上のアドレスを選択します。

  2. /etc/gitlab/gitlab.rbを更新します。

    consul['configuration'] = {
      ...
      bind_addr: 'IP ADDRESS'
    }
  3. 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のガイドに従って失敗したクラスターをリカバリーしてください。