このページでは、Kubernetes のスケーラビリティの上限に近づいているワークロードに対応できるように、VMware 用 Google Distributed Cloud(ソフトウェアのみ)を使用して作成されたクラスタを作成、構成、運用するためのベスト プラクティスについて説明します。
クラスタ名のルール
各 Google Cloud プロジェクト:
- 各ユーザー クラスタに、単一の Google Cloud プロジェクト内のすべての管理者クラスタ内で一意の名前を付ける必要があります。
スケーラビリティの上限
アプリケーションを設計する際は、次の上限を考慮してください。
各管理クラスタは、バンドルされたロード バランシング モード(Seesaw、MetalLB)または統合ロード バランシング モード(F5)を使用して、最大 100 個のユーザー クラスタをサポートします。これには、高可用性(HA)ユーザー クラスタと非 HA ユーザー クラスタの両方が含まれます。
各ユーザー クラスタがサポートする最大数は次のとおりです。
バンドルされたロード バランシング モード(Seesaw または MetalLB)を使用する場合は 500 ノード。統合ロード バランシング モード(F5)を使用する場合は 250 ノード。
15,000 個の Pod
バンドルされたロード バランシング モード(Seesaw または MetalLB)を使用する場合は 500 個の LoadBalancer Service。統合ロード バランシング モード(F5)を使用する場合は 250 個の LoadBalancer Service。
各ノードには、最大 110 個の Pod を作成できます(各 Pod は 1~2 個のコンテナで構成)。これには、アドオン システム サービスで実行される Pod も含まれます。
上限について
Google Distributed Cloud は、大規模な統合サーフェスを備えた複雑なシステムであるため、クラスタのスケーラビリティには多くの要素が相互に関連します。たとえば、Google Distributed Cloud は、ノード、Pod、Service の数をスケーリングできます。同時に複数の要素を引き上げると、たとえ小さなクラスタであっても問題を発生させる可能性があります。たとえば、ノード数 500 のクラスタで、ノードあたり 110 個の Pod のスケジュールを設定すると、Pod 数、ノードあたりの Pod 数、ノード数が過剰に増加する可能性があります。
詳細については、Kubernetes スケーラビリティのしきい値をご覧ください。
また、スケーラビリティの上限には、クラスタが実行されている vSphere の構成とハードウェアも影響します。これらの上限が検証された環境は、実際の環境とは異なる可能性が高いといえます。したがって、前提となる環境が制限要因となる場合、正確な数字を再現することはできません。
スケーリングに関する準備
管理クラスタまたはユーザー クラスタをスケーリングする際には、次の要件と制限事項を確認してください。
CPU、メモリ、ストレージの要件
各個別の VM については、CPU、RAM、ストレージの要件をご覧ください。
ディスク I/O とネットワーク I/O の要件
データ集約型のワークロードと特定のコントロール プレーン コンポーネントは、ディスクとネットワークの I/O レイテンシから影響を受けます。たとえば、数十個のノードと数千個の Pod を持つクラスタで etcd のパフォーマンスと安定性を確保するには、通常、500 シーケンシャル IOPS(標準的なローカル SSD や高パフォーマンスの仮想ブロック デバイスなど)が必要です。
ノードの IP アドレス
各ノードには、DHCP または静的に割り当てられた IP アドレスが 1 つ必要です。
たとえば、ノード数 50 の非 HA ユーザー クラスタ 1 つと、ノード数 250 の HA ユーザー クラスタ 1 つを設定するには、設定段階で 307 個の IP アドレスが必要です。
次の表に、この IP アドレスの内訳を示します。
ノードタイプ | IP アドレスの数 |
---|---|
管理クラスタのコントロール プレーン VM | 3 |
ユーザー クラスタ 1(非 HA)のコントロール プレーン VM | 1 |
ユーザー クラスタ 1 のワーカーノード VM | 50 |
ユーザー クラスタ 2(HA)のコントロール プレーン VM | 3 |
ユーザー クラスタ 2 のワーカーノード VM | 250 |
合計 | 307 |
1 つの管理クラスタで多数のユーザー クラスタを実行する
管理クラスタで多くのユーザー クラスタを実行する準備ができたら、管理クラスタの作成時に次の操作を行います。
管理クラスタの Pod CIDR ブロック
Pod の CIDR ブロックは、管理クラスタ内のすべての Pod の CIDR ブロックです。これは、admin-cluster.yaml
の network.podCIDR
フィールドで構成されます。
この範囲から、より小さい /24 ブロックが各ノードに割り当てられます。すべてのユーザー クラスタで Controlplane V2 が有効になっている場合、管理クラスタには 3 つのノードしかありませんが、使用可能な Pod IP アドレスが多数あります。ただし、Controlplane V2 ではなく kubeception を使用するユーザー クラスタを作成するたびに、1 個または 3 個のノードが管理クラスタに追加されます。
各高可用性(HA)kubeception ユーザー クラスタは、管理クラスタに 3 個のノードを追加します。
非 HA kubeception ユーザー クラスタごとに、管理クラスタに 1 個のノードが追加されます。
N 個のノードを持つ管理クラスタが必要な場合は、N 個の /24 ブロックをサポートする十分な大きさの CIDR ブロックが Pod に必要です。
次の表では、異なる Pod CIDR ブロックサイズごとにサポートされるノードの最大数を示します。
Pod CIDR ブロックサイズ | サポートされるノードの最大数 |
---|---|
/18 | 64 |
/17 | 128 |
/16 | 256 |
/15 | 512 |
管理クラスタのデフォルトの Pod の CIDR ブロックは 192.168.0.0/16 で、これは 256 ノードをサポートします。
HA kubeception ユーザー クラスタが 100 個ある管理クラスタには、3 個の管理クラスタ コントロール プレーン ノードと 300 個のユーザー クラスタ コントロール プレーン ノードがあります。ノードの総数は 303 です(256 より多い)。したがって、最大 100 個の HA kubeception ユーザー クラスタをサポートするには、Pod の CIDR ブロックを /15 に更新する必要があります。
Pod の CIDR ブロックを構成するには、管理クラスタの構成ファイルで network.podCIDR
フィールドを設定します。
管理クラスタの Service の CIDR ブロック
Service の CIDR ブロックは、管理クラスタ内のすべての Service の CIDR ブロックです。これは、admin-cluster.yaml
の network.serviceCIDR
フィールドで構成されます。
次の表では、異なる Service CIDR ブロックサイズごとにサポートされる Service の最大数を示します。
Service CIDR ブロックサイズ | サポートされる Service の最大数 |
---|---|
/24 | 256 |
/23 | 512 |
/22 | 1,024 |
デフォルト値は 10.96.232.0/24 であり、256 個の Service がサポートされます。
各 kubeception ユーザー クラスタは 6 個の Service を使用し、管理クラスタのコントロール プレーンは 14 個の Service を使用します。したがって、100 個の kubeception ユーザー クラスタを実行するには、/22 範囲を使用するように管理クラスタの Service の CIDR ブロックを変更する必要があります。
Cloud Logging と Cloud Monitoring
Cloud Logging と Cloud Monitoring は、リソースのトラッキングを行う際に有用です。
管理クラスタにデプロイされたロギングとモニタリングのコンポーネントの CPU とメモリ使用量は、kubeception ユーザー クラスタの数によって決まります。
次の表では、多くの kubeception ユーザー クラスタを実行するために必要な管理クラスタノードの CPU とメモリの量を示します。
kubeception ユーザー クラスタの数 | 管理クラスタノードの CPU | 管理クラスタノードのメモリ |
---|---|---|
0~10 | 4 個の CPU | 16 GB |
11~20 | 4 個の CPU | 32 GB |
20~100 | 4 個の CPU | 90 GB |
たとえば、2 つの管理クラスタノードがあり、それぞれに 4 個の CPU と 16 GB のメモリがある場合、0~10 個の kubeception ユーザー クラスタを実行できます。20 個を超える kubeception ユーザー クラスタを作成するには、まず管理クラスタノードのメモリを 16 GB から 90 GB に変更する必要があります。
GKE Hub
デフォルトでは、フリートごとに最大 250 個のクラスタをグローバル メンバーシップで登録できます。GKE Hub にさらにクラスタを登録するには、Google Cloud コンソールで割り当て引き上げのリクエストを送信できます。
メンバーシップ設定に基づくクラスタの割り当ての詳細については、数量に基づく割り当てをご覧ください。
ユーザー クラスタで多数のノードと Pod を実行する
ユーザー クラスタで多くのノードと Pod を実行するには、ユーザー クラスタを作成するときに次の操作を行います。
ユーザー クラスタの Pod の CIDR ブロック
Pod の CIDR ブロックは、ユーザー クラスタ内のすべての Pod の CIDR ブロックです。これは、user-cluster.yaml
の network.podCIDR
フィールドで構成されます。
この範囲から、より小さな /24 ブロックが各ノードに割り当てられます。N 個のノードを持つクラスタが必要な場合は、N 個の /24 ブロックをサポートするうえで十分な大きさが、このブロックにあることを確認します。
次の表では、異なる Pod CIDR ブロックサイズごとにサポートされるノードの最大数を示します。
Pod CIDR ブロックサイズ | サポートされるノードの最大数 |
---|---|
/18 | 64 |
/17 | 128 |
/16 | 256 |
/15 | 512 |
デフォルトの Pod の CIDR ブロックは 192.168.0.0/16 です。これは 256 個のノードをサポートします。たとえば、500 ノードを持つクラスタを作成するには、ユーザー クラスタの Pod の CIDR ブロックを変更して /15 範囲を使用する必要があります。
ユーザー クラスタの Service の CIDR ブロック
Service の CIDR ブロックは、ユーザー クラスタ内のすべての Service の CIDR ブロックです。これは、user-cluster.yaml
の network.serviceCIDR
フィールドで構成されます。
次の表では、異なる Service CIDR ブロックサイズごとにサポートされる Service の最大数を示します。
Service CIDR ブロックサイズ | サポートされる Service の最大数 |
---|---|
/21 | 2,048 |
/20 | 4,096 |
/19 | 8,192 |
/18 | 16,384 |
ユーザー クラスタ コントロール プレーン ノード
ユーザー クラスタ コントロール プレーンのコンポーネントのメモリ使用量は、ユーザー クラスタ内のノード数に応じて変わります。
次の表では、ユーザー クラスタのサイズに応じて、ユーザー クラスタのコントロール プレーン ノードに必要な CPU とメモリを示します。
ユーザー クラスタ ノードの数 | コントロール プレーン ノードの CPU | コントロール プレーン ノードのメモリ |
---|---|---|
0~20 | 3 個の CPU | 5 GB |
21~75 | 3 個の CPU | 6 GB |
76~250 | 4 個の CPU | 8 GB |
251~500 | 4 個の CPU | 16 GB |
たとえば、1 つのユーザー クラスタに 250 個を超えるノードを作成するには、16 GB 以上のメモリを備えたユーザー クラスタ コントロール プレーン ノードを使用する必要があります。
ユーザー クラスタ コントロール プレーン ノードの仕様は、user-cluster.yaml
の masterNode
フィールドで変更できます。
Dataplane v2
Dataplane V2 を使用する 500 ノードのユーザー クラスタの場合、ユーザー クラスタのコントロール プレーン ノードには 120 GB のメモリと 32 個の CPU コアを使用することをおすすめします。
Cloud Logging と Cloud Monitoring
Cloud Logging と Cloud Monitoring は、リソースのトラッキングを行う際に有用です。
ユーザー クラスタにデプロイされているクラスタ内エージェントの CPU とメモリ使用量は、ユーザー クラスタ内のノードと Pod の数によって変わります。
prometheus-server
や stackdriver-prometheus-sidecar
など Cloud Logging と Monitoring のコンポーネントでは、ノード数と Pod 数に基づいて CPU とメモリリソースの使用量が変わります。クラスタをスケールアップする前に、これらのコンポーネントの推定平均使用量に従ってリソース リクエストと上限を設定してください。次の表に、各コンポーネントの推定平均使用量を示します。
ノード数 | コンテナ名 | 推定 CPU 使用量 | 推定メモリ使用量 | ||
---|---|---|---|---|---|
0 Pod / ノード | 30 Pod / ノード | 0 Pod / ノード | 30 Pod / ノード | ||
3~50 | prometheus-server | 100m | 390m | 650M | 1.3G |
stackdriver-prometheus-sidecar | 100m | 340m | 1.5G | 1.6G | |
51~100 | prometheus-server | 160m | 500m | 1.8G | 5.5G |
stackdriver-prometheus-sidecar | 200m | 500m | 1.9G | 5.7G | |
101~250 | prometheus-server | 400m | 2500m | 6.5G | 16G |
stackdriver-prometheus-sidecar | 400m | 1300m | 7.5G | 12G | |
250~500 | prometheus-server | 1200m | 2600m | 22G | 25G |
stackdriver-prometheus-sidecar | 400m | 2250m | 65G | 78G |
Cloud Logging と Cloud Monitoring のコンポーネントのスケジュールを設定するために十分なノード数を確保します。これを行う方法の一つは、まず小さなクラスタを作成し、上の表に従い Cloud Logging と Cloud Monitoring のコンポーネント リソースを編集して、コンポーネントに対応するノードプールを作成することです。その後、クラスタをより大きなサイズに徐々にスケールアップします。
モニタリングとロギングのコンポーネントにちょうどよい大きさのノードプールを維持すると、ノードプールに他の Pod のスケジュールが設定されることを防止できます。これを行うには、次の taints をノードプールに追加する必要があります。
taints: - effect: NoSchedule key: node-role.gke.io/observability
これにより、他のコンポーネントがノードプールでスケジュール設定されなくなり、モニタリング コンポーネントのリソース消費が原因でユーザー ワークロードが強制排除されることを防止します。
ロードバランサ
このセクションで説明する Service は、LoadBalancer タイプの Kubernetes Service を指します。
クラスタ内のノード数と、ロードバランサで構成できる Service の数には上限があります。
バンドル型負荷分散(Seesaw)の場合は、ヘルスチェックの数にも上限があります。ヘルスチェックの数は、ノード数と、トラフィック ローカル Service の数によって異なります。トラフィック ローカル Service とは、externalTrafficPolicy が Local
に設定された Service です。
次の表では、バンドル型負荷分散(Seesaw)と統合型負荷分散(F5)の Service、ノード、ヘルスチェックの最大数を示します。
バンドル型負荷分散(Seesaw) | 統合型負荷分散(F5) | |
---|---|---|
最大 Service 数 | 500 | 250 2 |
最大ノード数 | 500 | 250 2 |
最大ヘルスチェック数 | N + (L * N) <= 10,000、ここで、N はノード数、L はトラフィック ローカル Service の数 1 | なし 2 |
1 たとえば、100 個のノードと 99 個のトラフィック ローカル Service があるとします。この場合、ヘルスチェックの数は 100 + 99 × 100 = 10,000 となります。これは上限 10,000 の範囲内です。
2 詳細については、F5 にお問い合わせください。この数は、F5 ハードウェアのモデル番号、仮想インスタンスの CPU / メモリ、ライセンスなどの要因に左右されます。
システム コンポーネントの自動スケーリング
Google Distributed Cloud は、ユーザー クラスタ内のシステム コンポーネントをノードの数に応じて自動的に調整します。構成を変更する必要はありません。このセクションの情報を使用して、リソース計画を行ってください。
Google Distributed Cloud では、addon-resizer を使用して次のシステム コンポーネントの CPU とメモリのリクエスト / 上限をスケーリングすることで、自動的に垂直方向のスケーリングを行います。
kube-state-metrics は、クラスタ ワーカーノードで実行される Deployment で、Kubernetes API サーバーをリッスンしてオブジェクトの状態に関する指標を生成します。CPU とメモリのリクエストと上限は、ノード数に基づきます。
次の表に、クラスタ内のノード数に対する、システムで設定されるリソースのリクエスト / 上限を示します。
ノード数 おおよそ 1 の CPU リクエスト / 上限(ミリ) おおよそ 1 のメモリ リクエスト / 上限(Mi) 3~5 105 110 6~500 100 + num_nodes 100 + (2 * num_nodes) 1 スケーリング時のコンポーネントの再起動数を減らすために ±5% のマージンが設定されます。
たとえば、ノード数が 50 のクラスタでは、CPU リクエスト / 上限が 150m / 150m に設定され、メモリ リクエスト / 上限が 200Mi / 200Mi に設定されます。ノード数が 250 のクラスタでは、CPU のリクエスト / 上限は 350m / 350m に設定され、メモリのリクエスト / 上限は 600Mi に設定されます。
metrics-server は、クラスタ ワーカーノードで実行される Deployment であり、Kubernetes の組み込み自動スケーリング パイプラインで使用されます。CPU とメモリのリクエストと上限は、ノード数に基づきます。
Google Distributed Cloud は、次のシステム コンポーネントのレプリカの数をスケーリングして、管理クラスタとユーザー クラスタの両方で水平方向のスケーリングを自動的に実行します。
core-dns は、サービス ディスカバリに使用される DNS ソリューションです。これは、ユーザー クラスタ ワーカーノードで Deployment として動作します。Google Distributed Cloud では、クラスタ内のノードと CPU コアの数に応じてレプリカの数を自動的にスケーリングします。16 個のノードまたは 256 個のコアが追加、削除されるたびに、1 つのレプリカが増減します。
N
個のノードとC
個のコアを含むクラスタが存在する場合は、max(N/16, C/256)
個のレプリカを想定できます。calico-typha は、Pod ネットワーキングをサポートするコンポーネントです。これは、ユーザー クラスタ ワーカーノードで Deployment として動作します。Google Distributed Cloud では、クラスタ内のノード数に応じて calico-typha レプリカの数が自動的に調整されます。
ノード数(N) calico-typha レプリカの数 N = 1 1 1 < N < 200 2 N >= 200 3 以上 Istio ingress-gateway は、クラスタ Ingress をサポートするためのコンポーネントであり、ユーザー クラスタ ワーカーノードで Deployment として動作します。ingress-gateway が処理するトラフィックの量に応じて、Google Distributed Cloud では、HorizontalPodAutoscaler を使用して、レプリカの数を CPU 使用量に基づいて 2~5 の範囲でスケーリングします。
konnectivity ネットワーク プロキシ(KNP)は、ユーザー クラスタのコントロール プレーン ノードからの下り(外向き)用の TCP レベルのプロキシを提供します。このプロキシは、ユーザー クラスタノードを宛先とするユーザーの kube-apiserver 下り(外向き)トラフィックをトンネリングします。Konnectivity エージェントは、ユーザー クラスタ ワーカーノードで Deployment として動作します。Google Distributed Cloud では、クラスタ内のノード数に応じて konnectivity エージェント レプリカの数が自動的に調整されます。
ノード数(N) konnectivity エージェント レプリカの数 1 <= N <= 6 N 6 < N < 10 6 10 <= N < 100 8 N >= 100 12 以上
ベスト プラクティス
このセクションでは、リソースのスケーリングに関するベスト プラクティスについて説明します。
クラスタを段階的にスケーリングする
Kubernetes ノードの作成では、ノード OS イメージ テンプレートを新しいディスク ファイルにクローン作成する必要があります。これは、I/O 集約型 vSphere オペレーションです。クローン作成オペレーションとワークロードの I/O オペレーションの間に I/O の分離はありません。同時に作成されたノードの数が多すぎると、クローン作成オペレーションの完了に時間がかかり、クラスタと既存のワークロードのパフォーマンスと安定性に影響する可能性があります。
vSphere リソースに応じてクラスタが段階的にスケーリングされるようにします。たとえば、クラスタのサイズを 3 から 500 に拡大するには、150、350、500 と、段階的にスケーリングすることを検討してください。こうすることで、vSphere インフラストラクチャの負荷が軽減されます。
etcd ディスクの I/O パフォーマンスを最適化する
etcd は、Kubernetes ですべてのクラスタデータのバックアップ保存先として使用される Key-Value ストアです。その性能と安定性は、クラスタの健全性にとって不可欠であり、ディスクとネットワークの I/O レイテンシの影響を受けます。
次の推奨事項に従って、コントロール プレーン VM に使用される vSphere データストアの I/O パフォーマンスを最適化します。
- etcd のハードウェア要件に従います。
- SSD またはオール フラッシュ ストレージを使用します。
数百ミリ秒のレイテンシは、ディスクまたはネットワーク I/O にボトルネックが存在することを示しており、異常なクラスタの原因になる可能性があります。次に挙げる etcd の I/O レイテンシ指標をモニタリングし、アラートのしきい値も設定します。
etcd_disk_backend_commit_duration_seconds
etcd_disk_wal_fsync_duration_seconds
ノード ブートディスクの I/O パフォーマンスを最適化する
Pod では、一時ファイルの保存などの内部オペレーションに、エフェメラル ストレージを使用します。エフェメラル ストレージは、コンテナの書き込み可能なレイヤ、ログ ディレクトリ、emptyDir ボリュームによって消費されます。このストレージは、ノードのファイル システムに基づくものであり、ノードのブートディスクを基盤としています。
Kubernetes ノードではストレージ I/O が分離されていないため、エフェメラル ストレージ上で非常に高い I/O を消費するアプリケーションは、Kubelet や Docker デーモンなどのシステム コンポーネントのリソースを枯渇させることでノードを不安定にする可能性があります。
ブートディスクをプロビジョニングするデータストアの I/O パフォーマンス特性で、アプリケーションでのエフェメラル ストレージとロギング トラフィックの使用に適したパフォーマンスが得られるようにします。
物理リソースの競合をモニタリングする
vCPU と pCPU の比率とメモリの過剰な使用に注意してください。物理ホストでの最適化されていない比率やメモリの競合は、VM のパフォーマンス低下につながることがあります。ホストレベルで物理リソースの使用量をモニタリングし、大規模なクラスタを実行するために十分なリソースを割り当てる必要があります。