CircleCI Server v3.x クラスタのハードニング

ネットワーク トポロジ

CircleCI Server システムでは主に、Kubernetes ノード、Nomad クライアント、外部 VM という 3 種類のコンピューティング インスタンスを実行します。

これらのインスタンスは、CIDR ブロックの異なるサブネットに分けてデプロイすることを強くお勧めします。 そうすることで、システムのコンポーネント間を流れるトラフィックの制御やそれぞれの分離がしやすくなります。

通例どおり、リソースはできる限り非公開にすることが原則です。 CircleCI Server システムへのユーザー アクセスが VPN 経由に限られ、かつ NAT ゲートウェイが適切に設定されていれば、パブリック IP アドレスの割り当ては必要ありません。 そうでない場合は、少なくとも CircleCI Server Traefik ロード バランサー用にパブリック サブネットを 1 つ用意する必要があります。

ただし、この場合には、パブリック サブネットに Nomad クライアントと VM を配置して、ジョブにユーザーが SSH 接続できるようにするとともに、ネットワーク ルールでアクセス スコープを設定することもお勧めします。

現時点では、GCP はカスタムのサブネット化には対応していません。 カスタムのサブネット化は、今後の更新/リリースで使用可能になる予定です。

ネットワーク トラフィック

このセクションでは、CircleCI Server システムの稼働に必要な最小要件について説明します。 ワークロードによっては、Nomad クライアントと VM の送信にルールを追加する必要があります。 クラウド プロバイダーごとに名称は異なります。 そのため、ファイアウォール ルールやセキュリティ グループなどを使用した実装が必要になる可能性があります。

表中の "外部" は、特に断りがない限り、すべての外部 IPv4 アドレスを意味します。 ただし、外部トラフィックすべてにプロキシを使用している場合など、お使いの環境によっては、より具体的に指定することができます。

なお、ここでは、Nomad、VM サービス、出力プロセッサそれぞれのロード バランサーは、すべて内部ロード バランサー (デフォルト) にすることを前提としています。

また、下記のルールは、特別な記載のない限り、TCP 接続に対してステートフルで設定するものとします。 ステートレス ルールを使用する場合には、下表の各項目に該当する送受信ルールをそれぞれ作成してください。

Kubernetes ロード バランサー

お使いの環境によっては、ロード バランサーが透過的である (ネットワーク トポロジの個別のレイヤーとしては扱われない) ことがあります。 この場合には、ロード バランサーの背後にあるネットワーク トラフィックの送信先またはソースに対して、本セクションのルールを直接適用してください。 CircleCI Server システムで使用している負荷分散の種類に応じたネットワーク セキュリティ ルールの適切な適用方法については、ご利用のクラウド プロバイダーのドキュメントをご覧ください。

受信

ロード バランサーのトラフィック ルールが自動的に作成されていない場合は、次の各ポートを設定してください。

名前 ポート ソース 用途

*-server-traefik

80

外部

ユーザー インターフェイスとフロントエンド API

*-server-traefik

443

外部

ユーザー インターフェイスとフロントエンド API

vm-service

3000

Nomad クライアント

Nomad クライアントとの通信

nomad

4647

Nomad クライアント

Nomad クライアントとの通信

output-processor

8585

Nomad クライアント

Nomad クライアントとの通信

送信

必要な送信は、Kubernetes (K8s) ロード バランサーのポート (30000 ~ 32767) 上にある K8s ノードへの TCP トラフィックのみです。 ただし、ロード バランサーが透過的であればこの送信は必要ありません。

コンピューティング インスタンスの共通ルール

以下のルールは、ロード バランサーを除くすべてのコンピューティング インスタンスに適用されます。

受信

インスタンスに SSH でアクセスする必要がある場合は、該当するインスタンスへの TCP 接続用にポート 22 を開放してください。 ルールの範囲を許可したソース IP のみに絞り込むことをお勧めします。または、必要に応じて限定的なルールを随時追加することも有効です。

送信

ほとんどの環境では、インスタンスすべてに対してインターネット リソースへのアクセスを許可することになります。 これを行うには、VPC 内にある DNS サーバーへのポート 53 からの UDP と TCP の送信を許可する必要があります。また、HTTP と HTTPS それぞれのトラフィックについて、ポート 80 と 443 からの TCP の送信を許可する必要もあります。 ジョブのビルドを行うインスタンス (Nomad クライアントや外部 VM) では、多くの場合、SSH 経由でご利用中の VCS からコードをプルする必要があります (TCP ポート 22)。 SSH は、外部 VM との通信にも使用されます。 そのため、少なくとも送信先が VM サブネットおよび VCS であるインスタンスすべてについて、SSH を許可する必要があります。

Kubernetes ノード

ノード間のトラフィック

デフォルトでは、K8s クラスタ内のトラフィックはネットワーク ポリシーにより制限されています。 ほとんどの用途では、Pod 間のトラフィックを制限するだけで十分です。つまり、K8s ノード間のトラフィックを特別に制限する必要はなく、これらノード間のトラフィックはすべて許可してかまいません。

クラスタ内でネットワーク ポリシーを使用するには、クラウド プロバイダーや環境設定にもよりますが、追加の手順を実行する必要があります。 以下の資料を参考にしてください。

受信

マネージド サービスを使用している場合は、ロード バランサーおよび許可済みのポート範囲からの送信トラフィックに対して作成されているルールを確認できます。 受信側の設定では、K8s ロード バランサーの標準のポート範囲 (30000 ~ 32767) を許可するだけで十分です。 ただし、透過的なロード バランサーを使用している場合は、上記のロード バランサー用受信ルールを適用する必要があります。

送信

ポート 送信先 用途

2376

VM

VM との通信

4647

Nomad クライアント

Nomad クライアントとの通信

すべてのトラフィック

その他のノード

クラスタ内トラフィックの許可

Nomad クライアント

Nomad クライアント同士が通信する必要はないため、Nomad クライアント インスタンス間のトラフィックはすべてブロックしてください。

受信

ポート ソース 用途

4647

K8s ノード

Nomad サーバーとの通信

64535 ~ 65535

外部

SSH でのジョブ再実行機能

送信

ポート 送信先 用途

2376

VM

VM との通信

3000

VM サービスのロード バランサー

内部通信

4647

Nomad のロード バランサー

内部通信

8585

出力プロセッサのロード バランサー

内部通信

外部 VM

Nomad クライアントと同じく、外部 VM 同士も通信する必要はありません。

受信

ポート ソース 用途

22

Kubernetes ノード

内部通信

22

Nomad クライアント

内部通信

2376

Kubernetes ノード

内部通信

2376

Nomad クライアント

内部通信

54782

外部

SSH でのジョブ再実行機能

送信

設定が必要な送信ルールは、VCS へのインターネット アクセスと SSH 接続のみです。



ドキュメントの改善にご協力ください

このガイドは、CircleCI の他のドキュメントと同様にオープンソースで、GitHub で使用できます。 ご協力いただき、ありがとうございます。


クリエイティブ・コモンズ・ライセンス
CircleCICircleCI ドキュメントは、クリエイティブ・コモンズの表示--非営利-継承 4.0 国際ライセンス に基づいてライセンス供与されています。