スケーラビリティ

このページでは、Kubernetes のスケーラビリティの上限に近づいているワークロードに対応できるように、GKE On-Prem クラスタを作成、構成、運用するためのベスト プラクティスについて説明します。

スケーラビリティの上限

GKE On-Prem でアプリケーションを設計する際は、次の上限を考慮してください。

  • 各管理クラスタは、高可用性(HA)クラスタと非 HA ユーザー クラスタの両方を含め、最大 20 個のユーザー クラスタをサポートします。

  • 各ユーザー クラスタがサポートする最大数は次のとおりです。

  • 各ノードには、最大 110 個の Pod を作成できます(各 Pod は 1~2 個のコンテナで構成)。これには、アドオン システム サービスで実行される Pod も含まれます。

上限について

GKE On-Prem は、大規模な統合サーフェスを備えた複雑なシステムであるため、クラスタのスケーラビリティには多くの要素が相互に関連します。たとえば、GKE On-Prem は、ノード、Pod、Service の数をスケーリングできます。同時に複数の要素を引き上げると、たとえ小さなクラスタであっても問題を発生させる可能性があります。たとえば、ノード数 250 のクラスタで、ノードあたり 110 個の Pod のスケジュールを設定すると、Pod 数、ノードあたりの Pod 数、ノード数が過剰に増加する可能性があります。

詳細については、Kubernetes スケーラビリティのしきい値をご覧ください。

また、スケーラビリティの上限には、クラスタが実行されている vSphere の構成とハードウェアも影響します。これらの上限が検証された環境は、実際の環境とは異なる可能性が高いといえます。したがって、前提となる環境が制限要因となる場合、正確な数字を再現することはできません。

スケーリングに関する対策

スケーリングに関する対策を講じる際は、vSphere インフラストラクチャ、Kubernetes ネットワーキング、GKE Hub、Cloud Logging と Cloud Monitoring の要件と制限事項を考慮してください。

vSphere インフラストラクチャ

このセクションでは、CPU、メモリ、ストレージ、ディスク、ネットワークの I/O の要件とノード IP アドレスのスケーラビリティに関する検討事項について説明します。

CPU、メモリ、ストレージの要件

コントロール プレーン VM には、次の要件が適用されます。

  • 管理クラスタのコントロール プレーンとアドオンノードでは、HA クラスタと非 HA ユーザー クラスタの両方を含め、最大 20 個のユーザー クラスタをサポートできます。したがって、管理クラスタでの調整は必要ありません。

  • デフォルトのユーザー クラスタ コントロール プレーンの VM 構成(4 CPU、8 GB メモリ、40 GB ストレージ)は、ユーザー クラスタで最大 250 個のノードを実行するために必要な最小限の設定です。

各個別の VM については、CPU、RAM、ストレージの要件をご覧ください。

ディスク I/O とネットワーク I/O の要件

データ集約型のワークロードと特定のコントロール プレーン コンポーネントは、ディスクとネットワークの I/O レイテンシから影響を受けます。たとえば、数十個のノードと数千個の Pod を持つクラスタで etcd のパフォーマンスと安定性を確保するには、通常、500 シーケンシャル IOPS(標準的なローカル SSD や高パフォーマンスの仮想ブロック デバイスなど)が必要です。

ノードの IP アドレス

GKE On-Prem ノードには、DHCP または静的に割り当てられた IP アドレスが 1 つ必要です。

たとえば、ノード数 50 の非 HA ユーザー クラスタ 1 つと、ノード数 250 の HA ユーザー クラスタ 1 つを設定するには、設定段階で 308 個の IP アドレスが必要です。それらの IP アドレスの内訳を、次の表に示します。

ノードタイプ IP アドレスの数
管理クラスタのコントロール プレーン VM 1
管理クラスタのアドオンノード VM 3
ユーザー クラスタ 1(非 HA)のコントロール プレーン VM 1
ユーザー クラスタ 1 のノード VM 50
ユーザー クラスタ 2(HA)のコントロール プレーン VM 3
ユーザー クラスタ 2 のノード VM 250
合計 308

Kubernetes ネットワーキング

このセクションでは、Pod の CIDR ブロックと Kubernetes Service のスケーラビリティに関する検討事項について説明します。

Pod CIDR ブロック

Pod CIDR ブロックは、ユーザー クラスタ内のすべての Pod の CIDR ブロックです。この範囲から、より小さい /24 ブロックが各ノードに割り当てられます。N 個のノードを持つクラスタが必要な場合は、N 個の /24 ブロックをサポートするうえで十分な大きさが、このブロックにあることを確認します。

次の表では、異なる Pod CIDR ブロックサイズごとにサポートされるノードの最大数を示します。

Pod CIDR ブロックサイズ サポートされるノードの最大数
/19 32
/18 64
/17 128
/16 256

デフォルトの Pod CIDR ブロックは 192.168.0.0/16 です。これは 256 個のノードをサポートします。デフォルトの Pod CIDR ブロックを使用すると、GKE On-Prem のユーザー クラスタでサポートされる最大数である 250 個のノードを持つクラスタを作成できます。

Kubernetes Service

このセクションでは、Service CIDR ブロックとロードバランサのスケーラビリティに関する考慮事項について説明します。

Service CIDR ブロック

Service CIDR ブロックは、ユーザー クラスタ内のすべての Service の CIDR ブロックです。このセクションで説明する Service は、LoadBalancer タイプの Kubernetes Service を指します。

次の表では、異なる Service CIDR ブロックサイズごとにサポートされる Service の最大数を示します。

Service CIDR ブロックサイズ サポートされる Service の最大数
/20 4,096
/19 8,192
/18 16,384

デフォルト値は 10.96.0.0/12 であり、1,048,576 個の Service がサポートされます。デフォルトの Service CIDR ブロックを使用すると、500 個の Service があるクラスタを作成できます。これは、GKE On-Prem がユーザー クラスタでサポートする最大数です。

ロードバランサ

クラスタ内のノード数と、ロードバランサで構成できる Service の数には上限があります。

バンドル型負荷分散(Seesaw)の場合は、ヘルスチェックの数にも上限があります。ヘルスチェックの数は、ノード数と、トラフィック ローカル Service の数によって異なります。トラフィック ローカル Service とは、externalTrafficPolicy が Local に設定された Service です。

次の表では、バンドル型負荷分散(Seesaw)と統合型負荷分散(F5)の Service、ノード、ヘルスチェックの最大数を示します。

バンドル型負荷分散(Seesaw) 統合型負荷分散(F5)
最大 Service 数 500 250 2
最大ノード数 250 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 / メモリ、ライセンスなどの要因に左右されます。

GKE Hub

デフォルトでは、最大 15 個のユーザー クラスタを登録できます。GKE Hub にさらにクラスタを登録するには、Google Cloud コンソールで割り当てを増やすリクエストを送信できます。

Cloud Logging と Cloud Monitoring

Cloud LoggingCloud Monitoring は、リソースのトラッキングを行う際に有用です。

1 つのユーザー クラスタで多数のノードを実行する

ユーザー クラスタにデプロイされているクラスタ内エージェントの CPU とメモリ使用量は、ユーザー クラスタ内のノードと Pod の数によって変わります。

prometheus-serverstackdriver-prometheus-sidecarstackdriver-log-aggregator など Cloud Logging と Monitoring のコンポーネントでは、ノード数と Pod 数に基づいて CPU とメモリリソースの使用量が変わります。クラスタをスケールアップする前に、これらのコンポーネントの推定平均使用量に従ってリソース リクエストと上限を設定してください。次の表に、各コンポーネントの推定平均使用量を示します。

ノード数 コンテナ名 推定 CPU 使用量 推定メモリ使用量
0 Pod / ノード 30 Pod / ノード 0 Pod / ノード 30 Pod / ノード
3~50 stackdriver-log-aggregator 150m 170m 1.6G 1.7G
prometheus-server 100m 390m 650M 1.3G
stackdriver-prometheus-sidecar 100m 340m 1.5G 1.6G
51~100 stackdriver-log-aggregator 220m 1100m 1.6G 1.8G
prometheus-server 160m 500m 1.8G 5.5G
stackdriver-prometheus-sidecar 200m 500m 1.9G 5.7G
101~250 stackdriver-log-aggregator 450m 1800m 1.7G 1.9G
prometheus-server 400m 2500m 6.5G 16G
stackdriver-prometheus-sidecar 400m 1300m 7.5G 12G

Cloud Logging と Cloud Monitoring のコンポーネントのスケジュールを設定するために十分なノード数を確保します。これを行う方法の一つは、まず小さなクラスタを作成し、上の表に従い Cloud Logging と Cloud Monitoring のコンポーネント リソースを編集して、コンポーネントに対応するノードプールを作成することです。その後、クラスタをより大きなサイズに徐々にスケールアップします。

モニタリングとロギングのコンポーネントにちょうどよい大きさのノードプールを維持すると、ノードプールに他の Pod のスケジュールが設定されることを防止できます。これを行うには、次の taints をノードプールに追加する必要があります。

taints:
  - effect: NoSchedule
    key: node-role.gke.io/observability

これにより、他のコンポーネントがノードプールでスケジュール設定されなくなり、モニタリング コンポーネントのリソース消費が原因でユーザー ワークロードが強制排除されることを防止します。

1 つの管理クラスタで多数のユーザー クラスタを実行する

管理クラスタにデプロイされたロギングとモニタリングのコンポーネントの CPU とメモリ使用量は、ユーザー クラスタの数によって決まります。

次の表では、多数のユーザー クラスタの実行に必要な管理クラスタノードの CPU とメモリの量を示します。

ユーザー クラスタの数 管理クラスタノードの CPU 管理クラスタノードのメモリ
0~10 4 個の CPU 16 GB
11~20 4 個の CPU 32 GB

たとえば、2 つの管理クラスタノードがあり、それぞれに 4 個の CPU と 16 GB のメモリがある場合、0~10 個のユーザー クラスタを実行できます。10 個を超えるユーザー クラスタを作成するには、まず管理クラスタノードのメモリを 16 GB から 32 GB にサイズ変更する必要があります。

管理クラスタノードのメモリを変更するには、次の手順で MachineDeployment 構成を編集します。

  1. 次のコマンドを実行します。

    kubectl --kubeconfig ADMIN_CLUSTER_KUBECONFIG edit machinedeployment gke-admin-node

    ここで、ADMIN_CLUSTER_KUBECONFIG は管理クラスタの kubeconfig ファイルのパスです。

  2. spec.template.spec.providerSpec.value.machineVariables.memory フィールドを 32768 に変更します。

  3. 編集内容を保存します。管理クラスタノードは、32 GB のメモリで再作成されます。

システム コンポーネントの自動スケーリング

GKE On-Prem では、構成を変更しなくても、クラスタ内のシステム コンポーネントの数は自動的に調整されます。このセクションの情報を使用して、リソース計画を行ってください。

  • GKE On-Prem では、addon-resizer を使用して次のシステム コンポーネントの CPU とメモリのリクエスト / 上限をスケーリングすることで、自動的に垂直方向のスケーリングを行います。

    • kube-state-metrics は、クラスタ ワーカーノードで実行される Deployment で、Kubernetes API サーバーをリッスンしてオブジェクトの状態に関する指標を生成します。CPU とメモリのリクエストと上限は、ノード数に基づきます。

      次の表に、クラスタ内のノード数に対する、システムで設定されるリソースのリクエスト / 上限を示します。

      ノード数 おおよそ 1 の CPU リクエスト / 上限(ミリ) おおよそ 1 のメモリ リクエスト / 上限(Mi)
      3~5 105 110
      6~250 100 + num_nodes 100 + (2 * num_nodes)

      1 スケーリング時のコンポーネントの再起動数を減らすために ±5% のマージンが設定されます。

      たとえば、ノード数が 50 のクラスタでは、CPU リクエスト / 上限が 150m / 150m に設定され、メモリ リクエスト / 上限が 200Mi / 200Mi に設定されます。ノード数が 250 のクラスタでは、CPU のリクエスト / 上限は 350m / 350m に設定され、メモリのリクエスト / 上限は 600Mi に設定されます。

    • metrics-server は、クラスタ ワーカーノードで実行される Deployment であり、Kubernetes の組み込み自動スケーリング パイプラインで使用されます。

  • GKE On-Prem では、次のシステム コンポーネントのレプリカ数をスケーリングして、水平方向のスケーリングを自動的に実行します。

    • kube-dns は、GKE On-Prem でサービス ディスカバリに使用される DNS ソリューションです。これは、ユーザー クラスタ ワーカーノードで Deployment として動作します。GKE On-Prem では、クラスタ内のノードと CPU コアの数に応じてレプリカの数を自動的にスケーリングします。16 個のノードまたは 256 個のコアが追加、削除されるたびに、1 つのレプリカが増減します。N 個のノードと C 個のコアを含むクラスタが存在する場合は、max(N/16, C/256) 個のレプリカを想定できます。なお、GKE On-Prem 1.4 以降では、毎秒 1,500 件の同時リクエストをサポートするよう、kube-dns が更新されています。

    • calico-typha は、GKE On-Prem で Pod ネットワーキングをサポートするコンポーネントです。これは、ユーザー クラスタ ワーカーノードで Deployment として動作します。GKE On-Prem では、クラスタ内のノード数に基づいてレプリカの数を自動的に調整します。ノード数が 200 未満のクラスタには calico-typha のレプリカが 1 つあり、ノード数が 200 以上のクラスタには 2 つのレプリカがあります。

    • ingress-gateway / istio-pilot は、クラスタ Ingress をサポートするためのコンポーネントであり、ユーザー クラスタ ワーカーノードで Deployment として動作します。ingress-gateway が処理するトラフィックの量に応じて、GKE On-Prem では、HorizontalPodAutoscaler を使用して、レプリカの数を CPU 使用量に基づいて 2~5 の範囲でスケーリングします。

ベスト プラクティス

このセクションでは、リソースのスケーリングに関するベスト プラクティスについて説明します。

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

Kubernetes ノードの作成では、ノード OS イメージ テンプレートを新しいディスク ファイルにクローン作成する必要があります。これは、I/O 集約型 vSphere オペレーションです。クローン作成オペレーションとワークロードの I/O オペレーションの間に I/O の分離はありません。同時に作成されたノードの数が多すぎると、クローン作成オペレーションの完了に時間がかかり、クラスタと既存のワークロードのパフォーマンスと安定性に影響する可能性があります。

vSphere リソースに応じてクラスタが段階的にスケーリングされるようにします。たとえば、クラスタのサイズを 3 ノードから 250 ノードに拡大するには、80、160、250 と、段階的にスケーリングすることを検討してください。こうすることで、vSphere インフラストラクチャの負荷が軽減されます。

etcd ディスクの I/O パフォーマンスを最適化する

etcd は、Kubernetes ですべてのクラスタデータのバックアップ保存先として使用される Key-Value ストアです。その性能と安定性は、クラスタの健全性にとって不可欠であり、ディスクとネットワークの I/O レイテンシの影響を受けます。

  • 次の推奨事項に従って、コントロール プレーン VM に使用される vSphere データストアの I/O パフォーマンスを最適化します。

  • 数百ミリ秒のレイテンシは、ディスクまたはネットワーク I/O にボトルネックが存在することを示しており、異常なクラスタの原因になる可能性があります。次に挙げる etcd の I/O レイテンシ指標をモニタリングし、アラートのしきい値も設定します。

    • etcd_disk_backend_commit_duration_seconds
    • etcd_disk_wal_fsync_duration_seconds

ノード ブートディスクの I/O パフォーマンスを最適化する

Pod では、一時ファイルの保存などの内部オペレーションに、エフェメラル ストレージを使用します。エフェメラル ストレージは、コンテナの書き込み可能なレイヤ、ログ ディレクトリ、emptyDir ボリュームによって消費されます。このストレージは、GKE On-Prem ノードのファイル システムに基づくものであり、ノードのブートディスクを基盤としています。

Kubernetes ノードではストレージ I/O が分離されていないため、エフェメラル ストレージ上で非常に高い I/O を消費するアプリケーションは、Kubelet や Docker デーモンなどのシステム コンポーネントのリソースを枯渇させることでノードを不安定にする可能性があります。

ブートディスクをプロビジョニングするデータストアの I/O パフォーマンス特性で、アプリケーションでのエフェメラル ストレージとロギング トラフィックの使用に適したパフォーマンスが得られるようにします。

物理リソースの競合をモニタリングする

vCPU と pCPU の比率メモリの過剰な使用に注意してください。物理ホストでの最適化されていない比率やメモリの競合は、VM のパフォーマンス低下につながることがあります。ホストレベルで物理リソースの使用量をモニタリングし、大規模なクラスタを実行するために十分なリソースを割り当てる必要があります。