プラットフォーム エンジニアは、カスタムの ComputeClasses を使用して、自動スケーリング中に Google Kubernetes Engine(GKE)がノードの作成に使用するノード設定とフォールバックの優先度を宣言的に構成できます。特定の戦略とワークロード要件に基づいて ComputeClass を作成できます。このドキュメントでは、クラスタで ComputeClass を設計して実装するためのベスト プラクティスについて説明します。読者は カスタム ComputeClass に精通している必要があります。すべての GKE ベスト プラクティスの概要については、GKE のベスト プラクティスをご覧ください。
ComputeClass の設計
以降のセクションでは、取得可能性やパフォーマンスの最大化などの目標に基づいて、クラスタで ComputeClass を設計して実装するためのベスト プラクティスについて説明します。ComputeClass は、手動で作成されたノードプールと自動で作成されたノードプールの両方で機能します。
戦略に基づいて各 ComputeClass を設計する
ワークロード、チーム、組織の特定の目標を満たすように各 ComputeClass を設計します。ComputeClass のフォールバック動作と、手動で作成したノードプールと自動作成されたノードプールの両方を選択する機能を使用して、手動オーバーヘッドの削減やスケジューリング パフォーマンスの向上など、特定の結果を優先します。以降のセクションでは、一般的な戦略について説明します。
取得可能性を改善し、手動によるオーバーヘッドを削減する
ノードプールの作成を GKE に委任するには、ComputeClass で自動作成されたノードプールのみを使用します。オートスケーラーは、ハードウェアの可用性、Pod のリソース要件、ゾーン容量に基づいてノードを構成します。この戦略により、ノードプールを手動で作成して調整する必要がなくなり、アイドル状態の未使用のノード容量に関連する費用を削減できます。
スケジューリングのパフォーマンスを改善し、ノードをファインチューニングする
優先度の高いノードを微調整し、スケジューリング レイテンシを短縮するには、ComputeClass で手動で作成したノードプールと自動作成されたノードプールを組み合わせて使用します。このハイブリッド戦略により、Pod が GKE による新しいノードプールの作成を待つ頻度が減ります。優先度の高いノードプールは手動で作成されるため、Pod の正確な要件を満たすようにハードウェアを微調整できます。
ハイブリッド戦略では、ComputeClass で次のタイプのノードプールが優先順位順に指定されます。
- 手動で作成したノードプール: これらのノードプールには、ほとんどの Pod を実行するのに最適な仕様が設定されています。これらのノードプールを、特定のノードラベル、ノード taint、容量予約、または
kubeletパラメータなどの特別な構成で構成します。これらのノードプールは、Pod に必要なノード数を見積もって作成します。ComputeClass で、これらのノードプールに最も高い優先度を割り当てます。 - 自動作成されたノードプール: フォールバック対策として、ComputeClass を使用して、Pod に最適化された追加のノードプールをリクエストします。これらの自動作成されたノードプールには、手動で作成したノードプールよりも低い優先度を割り当てます。
次の ComputeClass の例では、このハイブリッド戦略を使用しています。
apiVersion: cloud.google.com/v1
kind: ComputeClass
metadata:
name: hybrid-class
spec:
nodePoolAutoCreation:
enabled: true
priorities:
- nodepools: ['manual-pool1']
- machineFamily: n4
minCores: 16
minMemoryGb: 64
whenUnsatisfiable: DoNotScaleUp
この ComputeClass を使用するワークロードをデプロイすると、GKE は manual-pool1 の使用可能なノードに Pod を配置します。GKE は、手動で作成されたノードプールに使用可能な容量がない場合にのみ、新しいノードプールを作成します。手動で作成されたノードプール内の既存のノード数が増加すると、GKE が新しいノードを頻繁に作成する必要がなくなるため、スケジューリング レイテンシが減少します。
最後の手段のスケーリング動作を明示的に定義する
whenUnsatisfiable フィールドは、GKE が ComputeClass の優先度ルールの要件を満たせない場合に発生する処理を制御します。バージョン アップグレード後に予期しない動作が発生しないようにするには、すべての ComputeClass でこのフィールドの値を明示的に指定します。値を設定すると、ComputeClass ユーザーはワークロードでその ComputeClass を選択したときに何が起こるかを把握できます。このフィールドの推奨値は、ワークロードのタイプによって次のように異なります。
- 汎用ワークロード: ワークロードを任意のマシンシリーズで実行できる場合は、
ScaleUpAnywayの値を指定します。ComputeClass の優先度ルールに一致するノードが使用できない場合、GKE はクラスタのデフォルトのマシンシリーズを使用するノードをスケールアップします。 - 特殊なハードウェアを必要とするワークロード: GPU や特定の Compute Engine マシンシリーズなど、特定のハードウェアに依存するアクセラレータやハイ パフォーマンス コンピューティングのワークロードの場合は、
DoNotScaleUpの値を指定します。ComputeClass の優先度ルールに一致するノードが使用できない場合、リソースが使用可能になるまで Pod はPending状態のままになります。このアプローチにより、互換性のないハードウェアで Pod が実行されるのを防ぐことができます。
詳細については、優先度ルールが適用されない場合のスケーリングの動作を定義するをご覧ください。
ほとんどのワークロードに対してクラスタレベルのデフォルト ComputeClass を設定する
ほとんどのワークロードに同じハードウェア要件がある場合は、クラスタのデフォルトの ComputeClass を構成します。ComputeClass を明示的に選択していないワークロードには、デフォルトの ComputeClass が GKE によって適用されます。デフォルトの ComputeClass を設定すると、アプリケーション オペレーターはノードセレクタを変更したり、個々の Pod で特定のノードプールとハードウェアを手動でリクエストしたりする必要がなくなります。クラスタレベルのデフォルトの ComputeClass を設定する場合は、クラスタ内の既存のノードプールに他の ComputeClass のノードラベルと taint を追加しないでください。クラスタレベルのデフォルトの ComputeClass のスケジューリング中、GKE は他の ComputeClass のノードラベルまたはノード taint を持つノードプールを無視します。
Namespace のデフォルトの ComputeClass を設定してテナントを分離する
クラスタレベルのデフォルトの ComputeClass に加えて、特定の Namespace のデフォルトの ComputeClass を設定できます。マルチテナント環境がある場合や、専用ハードウェアで実行されるワークロードを分離する場合は、これらの Namespace のデフォルトの ComputeClass を構成します。システム Pod が GPU ノードなどの特殊なハードウェアで実行されないようにするには、汎用 ComputeClass をシステム名前空間のデフォルトの ComputeClass として追加します。
Autopilot モードで低インタラクション ワークロードを実行する
手動での操作や管理を必要としないワークロードがある場合は、ComputeClass を使用して Autopilot モードでワークロードを実行します。Standard クラスタがある場合でも、任意の ComputeClass で Autopilot モードを有効にできます。GKE は、GKE Autopilot のセキュリティ、スケーリング、課金機能を実装するフルマネージド ノードで、Autopilot ComputeClass を選択するワークロードを実行します。詳細については、GKE Standard での Autopilot モードのワークロードについてをご覧ください。
ステートフル ワークロード
以降のセクションでは、永続データに依存するステートフル ワークロードの中断や予期しない動作を軽減するためのベスト プラクティスについて説明します。
アクティブな移行を無効にする
アクティブな移行により、ComputeClass で優先度が高い新しいノード、またはスケジュールされていない DaemonSet Pod を実行できる容量を持つ新しいノードに Pod が自動的に移動します。アクティブな移行中、GKE は既存のノードで Pod を終了し、優先度の高いノードに新しい Pod を作成します。ローカル永続ストレージ内のデータに依存するワークロードがある場合、Pod を新しいノードに移動すると、Pod が永続データにアクセスできなくなるため、中断が発生する可能性があります。この問題を回避するには、ステートフル ワークロードを対象とする ComputeClass でアクティブな移行を無効にします。
StorageClass を使用してスケジューリングの信頼性を向上させる
StorageClass を使用すると、ステートフル ワークロードのスケジューリングの信頼性を次のように向上させることができます。
- Pod の作成後にのみボリュームを作成する: 動的ボリューム プロビジョニングを使用する場合は、StorageClass の
volumeBindingModeフィールドにWaitForFirstConsumerの値を指定します。このボリューム バインディング モードでは、GKE が対応する PersistentVolumeClaim を使用する Pod を作成するまで、PersistentVolume の作成が阻止されます。GKE は、Pod を実行するノードと同じゾーンに PersistentVolume をプロビジョニングします。 - トポロジ認識 StorageClass を使用する: ComputeClass がマシンシリーズの複数の世代(C4 や C3 など)にまたがる場合は、ディスクタイプの自動選択が有効になっていて、指定したディスクタイプをサポートするノードでのみスケジュール設定を行う StorageClass を使用します。組み込みの
dynamic-rwoStorageClass またはカスタム StorageClass を使用できます。クラスタ オートスケーラーが互換性のあるディスクタイプを動的に選択するため、ステートフル ワークロードは複数の Compute Engine インスタンス世代で実行できます。
取得可能性
以降のセクションでは、ComputeClass で取得可能性を改善し、Pod が Pending 状態になる時間を短縮するためのベスト プラクティスについて説明します。
マシンタイプではなくマシンシリーズをリクエストする
ComputeClass の優先度ルールで、Compute Engine マシンシリーズまたは特定のマシンタイプをリクエストできます。特定のマシンタイプに厳密な依存関係がない限り、machineFamily フィールドを使用してマシンシリーズを選択します。スケーリング オペレーション中に、GKE はそのマシンシリーズで使用可能なマシンタイプを使用するノードを作成できます。これにより、Pod が最も優先度の高いノード構成で実行される可能性が高まります。
需要の高いハードウェアに容量予約を使用する
ワークロードが TPU や高性能 GPU などのオンデマンド ハードウェアに依存している場合は、ハードウェアの Compute Engine 容量予約を作成し、ComputeClass でそれらの予約を使用します。容量予約により、リージョンまたはゾーンでハードウェアが利用可能になる可能性が高まり、リソースの取得可能性を高めることができます。フォールバック動作に影響を与えずに ComputeClass で予約を使用するには、Specific または AnyThenFail 予約アフィニティを使用します。AnyBestEffort または Automatic アフィニティを使用し、使用可能な予約済み容量がない場合、Compute Engine は ComputeClass 優先度ルールをバイパスして、オンデマンド ハードウェアにフォールバックする可能性があります。詳細については、予約済みゾーンリソースの使用をご覧ください。
新しい予約を少なくとも 1 時間は使用しない
クラスタ オートスケーラーは、容量予約に関する情報をキャッシュに保存します。新しい容量予約を作成すると、オートスケーラーがその予約を検出するまでに最大 1 時間かかることがあります。予約を作成したら、ワークロードでその予約を使用する前に少なくとも 1 時間待ちます。オートスケーラーが予約をキャッシュに保存する前に予約を使用するワークロードをデプロイすると、自動スケーリング オペレーションが失敗する可能性があります。
セキュリティ
以降のセクションでは、クラスタ内の ComputeClass のセキュリティを強化するためのおすすめの方法について説明します。これらの対策は、高価なハードウェアや在庫僅少のハードウェアを使用するノードの作成と構成に ComputeClass を使用できるため、重要です。意図的または偶発的な誤用により、ワークロードの中断、計画外のリソース使用料金、割り当ての枯渇が発生する可能性があります。
ComputeClass 構成への API アクセスを制限する
ワークロードは ComputeClass を使用して、GPU や TPU などの特殊なハードウェアを実行するノードを作成できます。ComputeClass の作成、変更、削除に対するアクセスを、クラスタ内のノードの作成、変更、削除を行うことができる同じプリンシパルに制限します。ComputeClass へのアクセスを制御するには、RBAC ポリシーを使用します。
名前空間で ComputeClass の可用性を制限する
GKE のお客様は、Kubernetes Namespace でさまざまなチームやワークロード タイプを分離することがよくあります。ComputeClass はクラスタ スコープのリソースです。つまり、デフォルトでは、任意の Namespace の任意のワークロードが任意の ComputeClass を選択できます。意図的または偶発的な誤用を避けるため、ValidatingAdmissionPolicies を使用して、各 Namespace のワークロードが選択できる ComputeClass のセットを制御します。たとえば、ウェブ フロントエンド Namespace の Pod がアクセラレータを作成する ComputeClass を選択できないようにすることができます。ValidatingAdmissionPolicies が次の一般的な構成を確認していることを確認します。
- すべての選択フィールドを確認する: ワークロードは、Pod 仕様の
nodeSelector、nodeAffinity、tolerationsフィールドを使用して ComputeClass を選択できます。意図しない ComputeClass の選択を回避するには、ValidatingAdmissionPolicy 式でこれらのフィールドをすべて確認します。 - ワイルドカード許容のバイパスを確認する: ワイルドカード許容(キーのない
operator: Exists許容など)を明示的にブロックまたは検証します。これらのワイルドカード セレクタは、ComputeClass テイントを含むほとんどのノード テイントを対象にできます。 - すべてのワークロード コントローラを確認する: すべてのワークロード コントローラ リソース(
Deployment、StatefulSet、DaemonSet、Job、CronJobなど)を対象とするように、ポリシーのmatchConstraintsを構成します。チェックの範囲をPodリソースのみに限定しないでください。
詳細については、ComputeClass の変更と選択へのアクセスを制限するをご覧ください。
信頼性
以降のセクションでは、ComputeClass の自動スケーリングと Pod 移行の信頼性を向上させ、中断や Pod の停止のリスクを軽減するためのベスト プラクティスについて説明します。
競合するノードセレクタの使用を防ぐ
Pod のノードセレクタは、GKE が Pod を配置する場所に影響します。また、Autopilot モードまたはノードプールの自動作成では、クラスタに新しいノードプールの作成をトリガーする可能性があります。ComputeClass を選択し、ノードセレクタを使用して ComputeClass 構成と競合するノードをリクエストする Pod がある場合、GKE は Pod をまったくスケジュールしないことがあります。
たとえば、オンデマンド インスタンスのみをリクエストする ComputeClass を考えてみましょう。Pod がその ComputeClass を選択し、ノードセレクタで Spot VM を選択すると、ComputeClass とノードセレクタが競合するため、GKE は Pod をスケジュールできません。この問題を回避するには、ValidatingAdmissionPolicies などのメソッドを使用して、ComputeClass を選択する Pod がシステムノードラベルも選択しないようにします。詳細については、システム ノードラベルのノードセレクタをご覧ください。
アクティブな移行と自動スケーリングの設定に対するすべての変更をテストする
ComputeClass のアクティブ移行と自動スケーリングの設定は、GKE が Pod を終了して、Pod を優先度の高いハードウェアに移動したり、使用率の低いノードを統合したりするタスクを実行する頻度に直接影響します。既存の ComputeClass でこれらの設定を変更すると、ワークロードが予期せず中断される可能性があります。既存の ComputeClass でこれらの設定に変更を加える前に、ステージング環境で変更をテストします。アノテーションを使用して、スケーリング中に重要なワークロードが強制排除されないように保護することもできます。
クラスタ アップグレードの前に ComputeClass CRD の更新をテストする
GKE は、ComputeClass CustomResourceDefinition(CRD)を定期的に更新して、フィールドの追加、フィールドの動作の変更、問題の修正を行います。通常、フィールドの追加と変更は特定の GKE バージョンで有効になります。本番環境クラスタを新しいマイナー バージョンまたはパッチ バージョンにアップグレードする前に、次のガイドラインを使用して、CRD の変更によってワークロードの問題が発生するかどうかを確認します。
- ステージング環境でアップグレードをテストします。
- ComputeClass CRD の変更または追加については、GKE リリースノートをご覧ください。
- ターゲット アップグレード バージョンのフィールドの更新については、ComputeClass CRD リファレンス ページをご覧ください。
PodDisruptionBudgets を使用してワークロードの可用性を向上させる
アクティブな移行など、Pod のエビクションを引き起こす ComputeClass オペレーションは、構成された PodDisruptionBudgets を尊重します。たとえば、70% 以上の Pod が使用可能であることを要求する PodDisruptionBudget を持つように、推論 Deployment を構成できます。アクティブな移行中に、Pod の削除がその予算に違反すると、GKE は Pod を削除しません。次のようなワークロードに PodDisruptionBudgets を指定します。
- 推論 Deployment などのステートレス ワークロード。
- 高可用性データベース アプリケーションなどのレプリケートされたステートフル ワークロード。
完了まで実行する必要があるワークロード、インスタンスが 1 つしかないワークロード、ローカルの永続データに依存するワークロードの保護に PodDisruptionBudget を使用しないでください。ワークロードの可用性とアップグレードなどの機能の完了のバランスが取れた予算を指定します。
重要なワークロードを強制排除から保護する
各 Pod が終了する前に完了する必要があるワークロードがある場合は、Pod 仕様に cluster-autoscaler.kubernetes.io/safe-to-evict:
"false" アノテーションを追加します。このアノテーションにより、GKE は自動スケーリング オペレーション中に Pod を強制排除できなくなります。このアノテーションを使用して、単一インスタンスのステートフル ワークロードや長時間実行されるバッチジョブなど、中断を許容できない Pod を保護します。
ベスト プラクティスの概要
このドキュメントでは、ComputeClass に関する次のベスト プラクティスについて説明します。
次のステップ
- GKE のその他のベスト プラクティスをご覧ください。
- ComputeClass を作成する方法を学習する。