デモシステムインフラ — Kubernetes

さまざまなクラスターサイズに対応した GitLab の Kubernetes クラスター設計を解説します

Kubernetes クラスター設計

私たちは GKE のデフォルトクラスター設定を、さまざまなユースケースに適したサイズに縮小しました。

スモールクラスター(予約/ユーザーサンドボックス)

スモールクラスターを /23 CIDR 範囲に収めることを前提とします。経験上、/24 以下の範囲を使用するとポッド IP がすぐに枯渇します。

ノードあたりのポッド数を 16 に削減します。これによりノードごとのポッドに /27 CIDR 範囲が使用されます。経験上、新規の Kubernetes クラスターは Kubernetes 管理関連のコンテナに約 15 ポッドを使用するため、新規クラスターがノード 1 つだけを使用するよう設計しています。

ドキュメントの目的上、IP アドレスと CIDR 範囲の第 2 オクテットを x(未知の変数)、r(クラスターに割り当てられた /23 の範囲)に置き換えます。/23 は 2 つの /24 範囲(偶数と奇数)を消費するため、r の値は常に偶数(0・2・4・6、252 まで)になります。

CIDR 範囲IP 範囲サブネット名収容数
10.x.r.0/2710.x.r.0 - 10.x.r.31demosys-k8s-clusterName-nodes9 ノード
varies10.x.r.32 - 10.x.r.128(将来の予約)(将来の利用)
10.x.r.128/2510.x.r.128 - 10.x.r.255demosys-k8s-clusterName-services127 サービス
10.x.{r+1}.0/2410.x.{r+1}.0 - 10.x.{r+1}.255demosys-k8s-clusterName-pods144 ポッド(16/ノード)

この設計により、/16 CIDR 範囲ごとに 127 クラスターを収容できます。

詳細は Terraform 設定モジュールをご参照ください。

ミディアムクラスター(特定サービス向け)

特定サービス用の各 Kubernetes クラスターを /20 CIDR 範囲に収めることを前提とします。

ノードあたりのポッド数を 55 に削減します。目安として、1 vCPU または 1GB メモリ(いずれか小さい方)あたり最大 4 つとします。これは選択した gcp_machine_type に応じて調整が必要です。ミディアムクラスターの /20 CIDR 範囲では、ポッドに /21(1,022 アドレス)が利用可能です。このクラスターの最大 30 ノードで、適切なマシンタイプを使用した場合、ノードあたり最大 34 ポッドが利用できます。8 vCPU・7.2GB メモリの n1-highcpu-8 では、32 を推奨します。

CIDR 範囲 /20使用可能ホスト範囲
10.x.0.0 /2010.x.0.1 - 10.x.15.254
10.x.16.0 /2010.x.16.1 - 10.x.31.254
10.x.32.0 /2010.x.32.1 - 10.x.47.254
10.x.48.0 /2010.x.48.1 - 10.x.63.254
10.x.64.0 /2010.x.64.1 - 10.x.79.254
10.x.80.0 /2010.x.80.1 - 10.x.95.254
10.x.96.0 /2010.x.96.1 - 10.x.111.254
10.x.112.0 /2010.x.112.1 - 10.x.127.254
10.x.128.0 /2010.x.128.1 - 10.x.143.254
10.x.144.0 /2010.x.144.1 - 10.x.159.254
10.x.160.0 /2010.x.160.1 - 10.x.175.254
10.x.176.0 /2010.x.176.1 - 10.x.191.254
10.x.192.0 /2010.x.192.1 - 10.x.207.254
10.x.208.0 /2010.x.208.1 - 10.x.223.254
10.x.224.0 /2010.x.224.1 - 10.x.239.254
10.x.240.0 /2010.x.240.1 - 10.x.255.254

この設計により、/16 CIDR 範囲ごとに 16 クラスターを収容できます。

ドキュメントの目的上、第 3 オクテットの 16 通りの値を表すために、/20 CIDR 範囲に応じて変動する文字として a から p を使用します。

CIDR 範囲IP 範囲サブネット名収容数
10.x.a.0/2410.x.a.0 - 10.x.a.255demosys-k8s-clusterName-nodes32 ノード
varies10.x.b.0 - 10.x.d.255(将来の予約)(将来の利用)
10.x.e.0/2210.x.e.1 - 10.x.h.254demosys-k8s-clusterName-services1,024 サービス
10.x.i.0/2110.x.i.1 - 10.x.p.254demosys-k8s-clusterName-pods1,024 ポッド

詳細は Terraform 設定モジュールをご参照ください。

ラージクラスター(マルチテナント/本番)

各マルチテナント Kubernetes クラスターを /16 CIDR 範囲に収めることを前提とします。

ノードあたりのポッド数を 55 に削減します。目安として、1 vCPU または 1GB メモリ(いずれか小さい方)あたり最大 4 つとします。これは選択した gcp_machine_type に応じて調整が必要です。ラージクラスターの /16 CIDR 範囲では、ポッドに /17(14,080 アドレス)が利用可能です。このクラスターの最大 255 ノードで、適切なマシンタイプを使用した場合、ノードあたり最大 55 ポッドが利用できます。16 vCPU・14.4GB メモリの n1-highcpu-16 では、55(57.6 を切り捨て)を推奨します。

ドキュメントの目的上、/16 クラスターを表すために IP アドレスと CIDR 範囲の第 2 オクテットを c に置き換えます。

CIDR 範囲IP 範囲サブネット名収容数
10.c.0.0/2310.c.0.0 - 10.c.1.255demosys-k8s-clusterName-nodes255 ノード
varies10.c.2.0 - 10.c.63.255(将来の予約)(将来の利用)
10.c.64.0/1810.c.64.1 - 10.c.127.254demosys-k8s-clusterName-services16,384 サービス
10.c.128.0/1710.c.128.1 - 10.c.255.254demosys-k8s-clusterName-pods14,080 ポッド

詳細は Terraform 設定モジュールをご参照ください。

Kubernetes スケーラビリティの考慮事項

Google Kubernetes Engine の IP 割り当て

以下は Google Kubernetes Engine ドキュメントからの抜粋です。

  • 各ノードにはクラスターの Virtual Private Cloud(VPC)ネットワークから IP アドレスが割り当てられます。このノード IP は、kube-proxy や kubelet などのコントロールコンポーネントから Kubernetes API サーバーへの接続を提供します。この IP がノードとクラスターの他の部分との接続点となります。
  • 各 Service にはクラスターの VPC ネットワークから ClusterIP と呼ばれる IP アドレスが割り当てられます。クラスター作成時に VPC ネットワークをオプションでカスタマイズできます。
  • 各ノードには GKE がそのノード上で動作するポッドに割り当てる IP アドレスのプールがあります(デフォルトでは /24 CIDR ブロック)。クラスター作成時にオプションで IP の範囲を指定できます。Flexible Pod CIDR 範囲機能により、指定したノードプール内のノードのポッド IP 範囲のサイズを縮小できます。
  • /24 範囲のノードで実行できるポッドは最大 110 で、256 ではありません。これにより、ノードのポッド IP 範囲の一時的な IP 不足によってポッドがスケジュール不能にならないようにバッファが設けられています。/24 より小さい範囲では、範囲内の IP アドレス数のほぼ半分のポッドしかスケジュールできません。各ポッドにはそのノードのポッド CIDR 範囲から単一の IP アドレスが割り当てられます。この IP アドレスはポッド内で動作するすべてのコンテナで共有され、クラスター内の他のポッドとの接続に使用されます。

:::tip GitLab の教訓 最大の IP 割り当ての課題は、大量の IP アドレスブロックを消費する Kubernetes クラスターとノードに関連しています。数十人から数百人のユーザーが Kubernetes を使用する場合、必要な IP アドレスブロックだけを割り当てるように注意が必要な設計上の考慮事項がいくつかあります(例:デフォルトのノードサブネットは /20 で、ノードは /24 サブネットを消費します)。

各ユーザーが 3 ノードのプールを持つ独自のクラスターを持つと、大規模では IP がすぐに枯渇します。これは私たちが苦労して学んだ教訓です。 :::

Kubernetes と GKE の制限事項

単一 Kubernetes クラスターには私たちのニーズを超えているように見える既知の制限がありますが、適切な設計と将来の成長のために考慮が必要です。

Kubernetes の制限の詳細はこちら

GKE 設計制限の詳細はこちら

Kubernetes の制限

数量名前空間あたりの制限クラスターあたりの制限
ノード数n/a5000
名前空間数n/a10000
ポッド数3000150000
ノードあたりのポッド数min(110, 10*#cores)min(110, 10*#cores)
Service 数500010000
Service あたりのポッド数250n/a

ポッド CIDR 範囲

ノードあたりのポッド数ノードあたりの CIDR 範囲
8/28
9-16/27
17-32/26
33-64/25
65-110/24

ノード CIDR 範囲

サブネットあたりのノード数サブネット CIDR
4/29
12/28
28/27
60/26
124/25
252/24
508/23
1,020/22
2,044/21
4,092(GKE デフォルト)/20
8,188/19
16,777,212/8

Service CIDR 範囲

サブネットあたりの Service 数サブネット CIDR
32/27
64/26
128/25
256/24
512/23
1,024/22
2,048/21
4,096(GKE デフォルト)/20
8,192/19
16,384/18
32,768/17
65,536/16

Kubernetes リソースの多次元制限

ポッドのセカンダリ IP 範囲ポッド IP アドレス数ノード数ポッド数
/242561110
/235122220
/221,0244440
/212,0488880
/204,096161,760
/198,192323,520
/1816,384647,040
/1732,76812814,080
/1665,53625628,160
/15131,07251256,320
/14(GKE デフォルト)262,1441,024112,640
/13524,2882,048225,280
/121,048,5764,096450,560
/112,097,1528,192901,120

IP 割り当て最適化のための Google ベストプラクティス

Flexible Pod CIDR の詳細はこちら

デフォルトでは、GKE はノードで最大 110 ポッドを実行するよう設定します。Kubernetes は各ノードに IP アドレスの範囲(CIDR ブロック)を割り当て、各ポッドが一意の IP アドレスを持てるようにします。CIDR ブロックのサイズはノードあたりの最大ポッド数に対応します。

デフォルトの最大 110 ポッド/ノードでは、Kubernetes は各ノードに /24 CIDR ブロック(256 アドレス)を割り当てます。ノードで作成できるポッド数の約 2 倍の利用可能な IP アドレスを確保することで、Kubernetes はノードのポッドの追加・削除時の IP アドレスの再利用を緩和します。

ノードあたり 110 ポッドがハードリミットですが、ノードあたりのポッド数を減らすことができます。デフォルト値から減らすと、Kubernetes はそれに応じて小さな CIDR ブロックをノードに割り当てます。このブロックには常に、ノードあたりの最大ポッド数の少なくとも 2 倍のアドレスが含まれます。以下の表は、Google Kubernetes Engine がノードあたりの最大ポッド数に基づいて各ノードに割り当てる CIDR ブロックのサイズを示しています。

ノードあたりの最大ポッド数を設定する際、間接的に各クラスターノードが必要とする IP アドレス空間を設定しています。例えば、ノードあたりの最大ポッド数を 30 に設定すると、上記の表に従って /26 CIDR 範囲が使用され、各ノードには 64 IP アドレスが割り当てられます。ノードあたりの最大ポッド数を設定しない場合、/24 CIDR 範囲が使用され、各ノードには 256 IP アドレスが割り当てられます。

ノードあたりの最大ポッド数を減らすことで、各ノードが必要とする IP アドレス空間が小さくなるため、クラスターのノード数を増やすことができます。また、クラスター作成時にポッド用の IP アドレス空間を小さく指定することで、同じノード数をサポートすることもできます。

ノードあたりの最大ポッド数を減らすと、より少ない IP アドレスで済む小規模なクラスターも作成できます。例えば、ノードあたり 8 ポッドの場合、各ノードには /28 CIDR が付与されます。これらのポッド IP アドレス範囲とユーザーが定義したサブネットおよびセカンダリ範囲により、クラスターを正常に作成するために必要な IP アドレス数が決まります。

ノードあたりの最大ポッド数は、クラスター作成時とノードプール作成時に設定できます。

ノードあたりの最大ポッド数は、クラスターまたはノードプールの作成時に設定できます。クラスターまたはノードプールの作成後にこの設定を変更することはできません。

ポッドアドレス範囲のサイズは、gcloud または Google Cloud Console でクラスターを作成する際に設定できます。

また、既存のクラスターにノードプールを作成する際に、ノードあたりの最大ポッド数を指定することもできます。新しいノードプールの作成により、クラスターレベルで default-max-pods-per-node が設定されていない既存のクラスターでも IP アドレス割り当てを最適化できます。

この値は、クラスターレベルで適用される default-max-pods-per-node オプションを上書きします。ノードプール作成時に max-pods-per-node オプションを省略した場合、クラスターレベルのデフォルト設定が使用されます。