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.0192.168.255.255 の 65,536 個の IP アドレスの範囲を指定します。

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

  • Google Distributed Cloud は、ノードあたりの最大 Pod の設定に基づいて、その約 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

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

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

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

具体的には、Google Distributed Cloud は、システム デーモン用に各ノードに 80 ミリコアの CPU(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 を使用せずにクラスタを作成する

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

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

CoreDNS 構成

このセクションでは、クラスタの拡張性に影響する CoreDNS の側面について説明します。

Pod DNS

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

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 の構成をご覧ください。

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

デフォルトでは、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 状態指標では、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 アーキテクチャ センターのクラウドベースの Kubernetes アプリケーションを準備するをご覧ください。

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

大規模なデプロイには、GDC 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 カスタマーケアにお問い合わせください。

次のステップ