Google Distributed Cloud クラスタをスケールアップする

他の Kubernetes クラスタと同様に、Google Distributed Cloud クラスタのスケーラビリティには多くの要素が相互に関連しています。このドキュメントは、ワークロードを中断することなくクラスタをスケールアップするために調整できる主要なディメンションについて理解することを目的としています。

上限について

Google Distributed Cloud は、大規模な統合サーフェスを備えた複雑なシステムです。クラスタのスケーラビリティに影響するディメンションは多数あります。たとえば、ノード数は Google Distributed Cloud がスケールできる多くの項目の 1 つにすぎません。他の項目には、Pod と Service の合計数が含まれます。ノードあたりの Pod 数やクラスタあたりのノード数など、これらのディメンションの多くは相互に関連しています。スケーラビリティに影響するディメンションの詳細については、GitHub の Kubernetes コミュニティ リポジトリの Scalability Special Interest Group(SIG)セクションにある Kubernetes スケーラビリティのしきい値をご覧ください。

また、スケーラビリティの上限には、クラスタが実行されているハードウェアとノードの構成も影響します。このドキュメントで説明する上限は、実際の環境とは異なる環境で検証されています。したがって、基盤となる環境が制限要因となる場合、同じ数字を再現できない可能性があります。

Google Distributed Cloud クラスタに適用される上限の詳細については、割り当てと上限をご覧ください。

スケールするための準備

Google Distributed Cloud クラスタをスケールする際には、以降のセクションで説明する要件と制限事項を確認してください。

コントロール プレーン ノードの CPU とメモリの要件

次の表に、本番環境ワークロードを実行するクラスタのコントロール プレーン ノードの推奨 CPU とメモリ構成を示します。

クラスタノードの数 推奨されるコントロール プレーン CPU 推奨されるコントロール プレーン メモリ
1-50 8 コア 32 GiB
51~100 人 16 コア 64 GiB

Pod と Service の数

クラスタで設定できる Pod と Service の数は、次の設定によって制御されます。

Pod の CIDR とノードの最大数

クラスタ内の Pod 用に予約されている IP アドレスの合計数は、クラスタをスケールアップする際の制限要因の 1 つです。この設定は、ノードあたりの 最大 Pod 数の設定と組み合わされることで、Pod の IP アドレスを使い果たす前にクラスタ内で使用可能なノードの最大数を決定します。

次の点を考慮してください。

  • クラスタ内で Pod 用に予約される IP アドレスの合計数は、clusterNetwork.pods.cidrBlocks で指定され、これには CIDR 表記で指定される IP アドレス範囲が使用されます。たとえば、事前入力値 192.168.0.0/16 は、192.168.0.0 から 192.168.255.255 まで 65,536 個の IP アドレスの範囲を指定します。

  • 単一ノードで実行できる Pod の最大数は、nodeConfig.podDensity.maxPodsPerNode で指定します。

  • ノードあたりの最大 Pod 数の設定に基づいて、Google Distributed Cloud は約 2 倍の IP アドレスをノードにプロビジョニングします。IP アドレスの追加により、短期間で Pod IP が誤って再利用されるのを防止できます。

  • Pod IP アドレスの合計数を各ノードにプロビジョニングされた Pod IP アドレスの数で割ると、クラスタ内で使用可能なノードの合計数がわかります。

たとえば、Pod CIDR が 192.168.0.0/17 の場合、IP アドレスの合計は 32,768 個となります(2(32-17) = 215 = 32,768)。ノードあたりの最大 Pod 数を 250 に設定すると、Google Distributed Cloud は約 500 個の IP アドレスの範囲をプロビジョニングします。これは、/23 CIDR ブロック(2(32-23) = 29 = 512)に相当します。したがって、この例のノードの最大数は 64(215アドレス/クラスタを 29 アドレス/ノードで割った数 = 2(15-9) ノード/クラスタ = 26 = 64 ノード/クラスタ)となります。

clusterNetwork.pods.cidrBlocksnodeConfig.podDensity.maxPodsPerNode はどちらも不変であるため、ノード容量が不足しないように、クラスタの将来の拡張を慎重に計画してください。テストに基づくクラスタあたりの Pod 数、ノードあたりの Pod 数、クラスタあたりのノード数の推奨最大値については、上限をご覧ください。

サービスの CIDR

Service CIDR を更新して、クラスタのスケールアップ時に Service をさらに追加できます。ただし、Service CIDR 範囲を縮小することはできません。詳細については、Service のネットワーク範囲を拡張するをご覧ください。

システム デーモン用に予約されたリソース

デフォルトでは、Google Distributed Cloud はシステム デーモン(sshdudev など)用にノードのリソースを自動的に予約します。CPU とメモリのリソースは、システム デーモン用にノード上で予約されているため、これらのデーモンには必要なリソースがあります。この機能がないと、Pod はノードのリソースの大半を使い切り、システム デーモンがタスクを完了できなくなる可能性があります。

具体的には、Google Distributed Cloud はシステム デーモン用に各ノードに 80 ミリコア(80 mCPU)と 280 メビバイト(280 MiB)のメモリを予約しています。CPU の単位「mCPU」 はコアの 1,000 分の 1 を表します。つまり、各ノードの 80/1000 すなわち 8% のコアはシステム デーモン用に予約されています。予約されるリソースの量は少ないため、Pod のパフォーマンスに大きな影響はありません。ただし、CPU またはメモリの使用量が割り当て量を超えると、ノード上の kubelet が Pod を強制排除する場合があります。

MetalLB によるネットワーキング

次の点に対処するために、MetalLB スピーカーの数を増やすことができます。

  • 帯域幅: ロード バランシング サービスのクラスタ帯域幅全体は、スピーカーの数と各スピーカー ノードの帯域幅によって異なります。ネットワーク トラフィックが増えると、より多くのスピーカーが必要になります。

  • フォールト トレランス: スピーカーが多くなるほど、1 つのスピーカーの障害による全体的な影響が軽減されます。

MetalLB では、ロード バランシング ノード間のレイヤ 2 接続が必要です。この場合、MetalLB スピーカーを配置できるレイヤ 2 接続のノードの数によって制限される可能性があります。

クラスタに配置する MetalLB スピーカーの数を慎重に計画し、必要なレイヤ 2 ノードの数を決定します。詳細については、MetalLB のスケーラビリティの問題をご覧ください。

これとは別に、バンドル型ロード バランシング モードを使用する場合は、コントロール プレーン ノードも同じレイヤ 2 ネットワーク内にある必要があります。手動ロード バランシングにはこの制限はありません。詳細については、手動ロードバランサ モードをご覧ください。

多数のノード、Pod、Service の実行

ノード、Pod、Service を追加すると、クラスタをスケールアップできます。以下のセクションでは、クラスタ内のノード、Pod、Service の数を増やす場合に考慮する必要がある、追加の設定と構成について説明します。これらのディメンションの上限と関係性については、上限をご覧ください。

kube-proxy を使用せずにクラスタを作成する

多数の Service とエンドポイントを使用するようにスケールアップできる高性能なクラスタを作成するには、kube-proxy を使用せずにクラスタを作成することをおすすめします。kube-proxy がない場合、クラスタは GKE Dataplane V2 を kube-proxy-replacement モードで使用します。このモードでは、大量の iptables ルールを維持するために必要なリソースの消費を回避できます。

既存のクラスタで kube-proxy の使用を無効にすることはできません。この構成は、クラスタの作成時に設定する必要があります。手順と詳細については、kube-proxy を使用せずにクラスタを作成するをご覧ください。

CoreDNS の構成

このセクションでは、クラスタのスケーラビリティに影響する CoreDNS の側面について説明します。

Pod DNS

デフォルトでは、Google Distributed Cloud クラスタは次のような resolv.conf を使用して Pod を挿入します。

nameserver KUBEDNS_CLUSTER_IP
search <NAMESPACE>.svc.cluster.local svc.cluster.local cluster.local c.PROJECT_ID.internal google.internal
options ndots:5

オプション ndots:5 は、ドットが 5 つ未満のホスト名は完全修飾ドメイン名(FQDN)とはみなされないことを意味します。DNS サーバーは、最初にリクエストされたホスト名を検索する前に、指定されたすべての検索ドメインを追加します。これにより、google.com を解決するときに次のように検索が行われます。

  1. google.com.NAMESPACE.svc.cluster.local
  2. google.com.svc.cluster.local
  3. google.com.cluster.local
  4. google.com.c.PROJECT_ID.internal
  5. google.com.google.internal
  6. google.com

各ルックアップは IPv4(A レコード)と IPv6(AAAA レコード)に対して実行され、FQDN 以外のクエリごとに 12 件の DNS リクエストが発生します。これにより、DNS トラフィックが大幅に増加します。この問題を軽減するには、末尾にドット(google.com.)を追加して、ホスト名を FQDN としてルックアップする宣言をすることをおすすめします。この宣言は、アプリケーション ワークロード レベルで行う必要があります。詳細については、resolv.conf のマニュアル ページをご覧ください。

IPv6

クラスタが IPv6 を使用していない場合は、アップストリーム DNS サーバーへの AAAA レコード ルックアップを半減することで、DNS リクエストを減らすことができます。AAAA ルックアップの無効化についてサポートが必要な場合は、Cloud カスタマーケアにお問い合わせください。

専用ノードプール

アプリケーションのライフサイクルでは DNS クエリが重要となるため、coredns Deployment 専用のノードを使用することをおすすめします。この Deployment は、通常のアプリケーションとは異なる障害発生ドメインに属します。coredns Deployment 専用のノードの設定についてサポートが必要な場合は、Cloud カスタマーケアにお問い合わせください。

MetalLB のスケーラビリティに関する問題

MetalLB はアクティブ / パッシブモードで実行されます。つまり、どの時点においても、特定の LoadBalancer VIP を処理する MetalLB スピーカーは 1 つだけです。

フェイルオーバー

Google Distributed Cloud リリース 1.28.0 より前の大規模な環境では、MetalLB のフェイルオーバーに時間がかかり、クラスタに信頼性のリスクをもたらす可能性があります。

接続制限

3 万近くまたはそれ以上の同時接続が予想される Ingress Service などの特定の LoadBalancer VIP がある場合、VIP を処理するスピーカー ノードは使用可能なポートを使い切る可能性があります。アーキテクチャの制限により、この問題は MetalLB による緩和策はありません。クラスタを作成する前に、BGP によるバンドル型ロード バランシングに切り替えるか、別の Ingress クラスを使用することを検討してください。詳細については、Ingress の構成をご覧ください。

ロードバランサのスピーカー

デフォルトでは、Google Distributed Cloud はコントロール プレーンとデータプレーンの両方に同じロードバランサ ノードプールを使用します。ロードバランサ ノードプール(loadBalancer.nodePoolSpec)を指定しない場合、コントロール プレーン ノードプール(controlPlane.nodePoolSpec)が使用されます。

ロード バランシングにコントロール プレーン ノードプールを使用するときにスピーカーの数を増やすには、コントロール プレーン マシンの数を増やす必要があります。本番環境のデプロイでは、高可用性のために 3 つのコントロール プレーン ノードを使用することをおすすめします。追加のスピーカーに対応するためにコントロール プレーン ノードの数を 3 つよりも多くすると、リソースを有効活用できない場合があります。

Ingress の構成

1 つの LoadBalancer Service VIP に対して 3 万近くの同時接続が予想される場合は、MetalLB ではサポートできない可能性があります。

F5 BIG-IP などの他の方法で VIP を公開することを検討してください。または、BGP によるバンドル型ロード バランシングを使用して新しいクラスタを作成することもできます。同じ制限はありません。

Cloud Logging と Cloud Monitoring のコンポーネントを微調整する

大規模なクラスタでは、アプリケーション プロファイルとトラフィック パターンによっては、Cloud Logging と Cloud Monitoring のコンポーネントのデフォルトのリソース構成では不十分な場合があります。オブザーバビリティ コンポーネントのリソース リクエストと制限を調整する手順については、Stackdriver コンポーネント リソースの構成をご覧ください。

特に、多数のサービスとエンドポイントを持つクラスタで kube-state-metrics を使用すると、kube-state-metrics 自体と同じノードの gke-metrics-agent の両方でメモリが過剰に使用される可能性があります。metrics-server のリソース使用量は、ノード、Pod、Service の単位でスケーリングすることもできます。これらのコンポーネントでリソースの問題が発生した場合は、Cloud カスタマーケアにお問い合わせください。

sysctl を使用したオペレーティング システムの構成

ノードのオペレーティング システム構成は、ワークロードのユースケースに最適なものに調整することをおすすめします。inotify リソースの数を制御する fs.inotify.max_user_watches パラメータと fs.inotify.max_user_instances パラメータは、多くの場合、調整が必要です。たとえば、次のようなエラー メッセージが表示された場合は、これらのパラメータを調整する必要があるかどうかを確認します。

The configured user limit (128) on the number of inotify instances has been reached
ENOSPC: System limit for number of file watchers reached...

調整は通常、ワークロードの種類やハードウェア構成によって異なります。特定の OS のベスト プラクティスについては、OS ベンダーにお問い合わせください。

おすすめの方法

このセクションでは、クラスタをスケールアップするためのベスト プラクティスについて説明します。

一度に 1 つのディメンションをスケーリングする

問題を最小限に抑え、変更のロールバックを容易にするため、一度に複数のディメンションを調整しないでください。同時に複数のディメンションをスケールアップすると、たとえ小さなクラスタであっても問題を発生させる可能性があります。たとえば、ノードあたりのスケジュール Pod 数を 110 に増やしながらクラスタ内のノード数を 250 に増やそうとしても、Pod 数、ノードあたりの Pod 数、ノード数が多くなりすぎるために失敗する可能性が高くなります。

クラスタを段階的にスケーリングする

クラスタのスケールアップはリソースを大量に消費する可能性があります。クラスタ オペレーションの失敗やクラスタ ワークロードの中断のリスクを軽減するために、1 回のオペレーションで多数のノードを持つ大規模なクラスタを作成することはおすすめしません。

ワーカーノードのないハイブリッド クラスタまたはスタンドアロン クラスタを作成する

50 個を超えるワーカーノードを持つ大規模なハイブリッド クラスタまたはスタンドアロン クラスタを作成する場合は、まずコントロール プレーン ノードを使用して高可用性(HA)クラスタを作成してから、徐々にスケールアップすることをおすすめします。クラスタ作成オペレーションではブートストラップ クラスタが使用されます。ブートストラップ クラスタは HA ではないため、信頼性は低くなります。HA ハイブリッド クラスタまたはスタンドアロン クラスタを作成したら、それを使用してより多くのノードにスケールアップできます。

バッチでワーカーノードの数を増やす

クラスタを拡張してより多くのワーカーノードを実行する場合は、段階的に拡張することをおすすめします。一度に追加するノードは 20 以下にすることをおすすめします。これは、重要なワークロードを実行しているクラスタに特に当てはまります。

イメージの並列 pull を有効にする

デフォルトでは、kubelet はイメージをひとつずつ順番に pull します。イメージ レジストリ サーバーへのアップストリーム接続が正しくない場合、不正なイメージの pull によって、特定のノードプールのキュー全体が停滞する可能性があります。

これを緩和するには、カスタム kubelet 構成で serializeImagePullsfalse に設定することをおすすめします。手順と詳細については、kubelet イメージの pull 設定を構成するをご覧ください。イメージの並列 pull を有効にすると、ネットワーク帯域幅またはディスク I/O の消費量が急増する可能性があります。

アプリケーション リソースのリクエストと上限を微調整する

密集した環境では、アプリケーションのワークロードが強制排除される可能性があります。Kubernetes は、この参照メカニズムを使用して、強制排除が発生した場合に Pod をランク付けします。

コンテナ リソースを設定する場合は、リクエストと上限に同じ量のメモリを使用し、より大きい CPU 上限を使用する、または CPU 上限を無制限にすることをおすすめします。詳細については、Cloud Architecture Center のクラウドベースの Kubernetes アプリケーションを準備するをご覧ください。

ストレージ パートナーを使用する

大規模なデプロイには、GDCV Ready ストレージ パートナーのいずれかを使用することをおすすめします。特定のストレージ パートナーに次の情報を確認することが重要です。

  • ストレージのデプロイが、高可用性、優先度設定、ノード アフィニティ、リソース リクエストと上限など、ストレージに関するベスト プラクティスに従っている。
  • ストレージ バージョンが、特定の Google Distributed Cloud バージョンで認定されている。
  • ストレージ ベンダーが、デプロイする高スケールをサポートできる。

高可用性対応のクラスタを構成する

高スケールのデプロイを監査し、可能な限り重要なコンポーネントが HA 用に構成されていることを確認することが重要です。Google Distributed Cloud は、すべてのクラスタタイプに対して HA デプロイ オプションをサポートしています。詳細については、デプロイモデルを選択するをご覧ください。HA デプロイメントのクラスタ構成ファイルの例については、クラスタ構成サンプルをご覧ください。

次のような他のコンポーネントを監査することも重要です。

  • ストレージ ベンダー
  • クラスタ Webhook

リソース使用状況のモニタリング

このセクションでは、大規模なクラスタ向けの基本的なモニタリングの推奨事項について説明します。

使用率の指標を詳細にモニタリングする

ノードと個々のシステム コンポーネントの両方の使用状況をモニタリングし、これらのコンポーネントに十分に安全なマージンを確保することが重要です。デフォルトで使用できる標準のモニタリング機能を確認するには、事前定義されたダッシュボードを使用するをご覧ください。

帯域幅の消費をモニタリングする

帯域幅の消費を注意深くモニタリングして、ネットワークが飽和状態にならないようにします。これにより、クラスタのパフォーマンスが低下します。

etcd のパフォーマンスを向上させる

etcd のパフォーマンスと安定性には、ディスクの速度が重要な役割を果たします。ディスクが低速な場合は etcd のリクエストのレイテンシが増加し、クラスタの安定性に問題が発生する可能性があります。クラスタのパフォーマンスを向上させるには、Google Distributed Cloud では Event オブジェクトを個別の専用の etcd インスタンスに保存します。標準の etcd インスタンスは、データ ディレクトリとして /var/lib/etcd を使用し、クライアント リクエスト用にポート 2379 を使用します。etcd-events インスタンスは、データ ディレクトリとして /var/lib/etcd-events を使用し、クライアント リクエスト用にポート 2382 を使用します。

etcd ストアにはソリッド ステート ディスク(SSD)を使用することをおすすめします。最適なパフォーマンスを得るには、別々のディスクを /var/lib/etcd/var/lib/etcd-events にマウントします。専用ディスクを使用すると、2 つの etcd インスタンスがディスク I/O を共有しなくなります。

etcd のドキュメントには、本番環境でクラスタを実行するときに最適な etcd パフォーマンスを実現するための、追加のハードウェアの最適化案が記載されています。

etcd とディスクのパフォーマンスを確認するには、Metrics Explorer で次の etcd I/O レイテンシ指標を使用します。

  • etcd_disk_backend_commit_duration_seconds: 期間は 99 パーセンタイル(p99)に対して 25 ミリ秒未満にする必要があります。
  • etcd_disk_wal_fsync_duration_seconds: 期間は 99 パーセンタイル(p99)に対して 10 ミリ秒未満にする必要があります。

etcd のパフォーマンスの詳細については、etcd の警告「エントリの適用に時間がかかりすぎた」は何を意味しますか?etcd の警告「ハートビートの定刻での送信に失敗した」は何を意味しますか?をご覧ください。

さらにサポートを必要とされる場合は、Cloud カスタマーケアにお問い合わせください。

次のステップ