このページでは、Google Kubernetes Engine(GKE)の Autopilot クラスタで Spot Pod を使用して、フォールト トレラントなワークロードをより低コストで実行する方法について説明します。
概要
GKE Autopilot クラスタの Spot Pod は、Compute Engine の Spot VM を基盤とするノードで実行される Pod です。Spot Pod の料金は標準の Autopilot Pod より低く設定されていますが、標準の Pod の実行でコンピューティング リソースが必要になると、GKE によって強制排除される場合があります。
Spot Pod は、ワークロードを標準の Pod として実行するよりも低コストで、ステートレス、バッチ、フォールト トレラントなワークロードを実行したい場合に適しています。Autopilot クラスタで Spot Pod を使用するには、Pod 仕様でマニフェストを変更して、Spot Pod をリクエストします。
Spot Pod は、デフォルトの汎用 Autopilot コンピューティング クラスと、特定のハードウェア要件を満たす特殊なコンピューティング クラスで実行できます。これらのコンピューティング クラスの詳細については、Autopilot のコンピューティング クラスをご覧ください。
Autopilot クラスタの Spot Pod の料金の詳細については、Google Kubernetes Engine の料金をご覧ください。
Spot Pod は、Autopilot サービスレベル契約からは除外されています。
利点
Autopilot クラスタで Spot Pod を使用すると、次の利点があります。
- 標準の Autopilot Pod で同じワークロードを実行する場合よりもコストを抑えることができます。
- GKE が自動スケーリングとスケジュールを自動的に管理します。
- GKE は、Spot Pod を実行するノードを自動的に taint して、それらのノードで重要なワークロードなどの標準 Pod がスケジュールされないようにします。Spot Pod を使用するデプロイは、対応する容認値で自動的に更新されます。
始める前に
始める前に、次の作業が完了していることを確認してください。
- Google Kubernetes Engine API を有効にする。 Google Kubernetes Engine API の有効化
- このタスクに Google Cloud CLI を使用する場合は、gcloud CLI をインストールして初期化する。すでに gcloud CLI をインストールしている場合は、
gcloud components update
を実行して最新のバージョンを取得する。
Autopilot ワークロードの Spot Pod をリクエストする
Pod を Spot Pod として実行するようリクエストするには、Pod 仕様の nodeSelector またはノード アフィニティで cloud.google.com/gke-spot=true
ラベルを使用します。GKE は、Spot Pod を実行できるノードを自動的にプロビジョニングします。
コンピューティング リソースが Google Cloud の別の場所で必要になる場合など、Spot Pod はいつでも強制排除され、終了する可能性があります。terminationGracePeriodSeconds
フィールドを指定すると、終了する場合に、終了するノード上の Spot Pod は最大 15 秒の猶予期間をリクエストできます。この期間はベスト エフォート ベースで付与されます。
プリエンプションでの Spot Pod の最大猶予期間は 15 秒です。terminationGracePeriodSeconds
で 15 秒を超える時間をリクエストしても、プリエンプションは 15 秒を超えて猶予されることはありません。強制排除の場合、Pod に SIGTERM シグナルが送信されます。猶予期間中にシャットダウンの手順を行う必要があります。
Autopilot では、GKE が Spot Pod の実行用に作成されたノードを自動的に taint し、対応する容認値でワークロードを変更します。taint により、Spot Pod を実行するノードで標準 Pod がスケジュールされなくなります。
nodeSelector を使用して Spot Pod を必須にする
nodeSelector を使用すると、Deployment で Spot Pod を必須にできます。次の例のように、Deployment に cloud.google.com/gke-spot=true
ラベルを追加します。
apiVersion: batch/v1
kind: Job
metadata:
name: pi
spec:
template:
metadata:
labels:
app: pi
spec:
nodeSelector:
cloud.google.com/gke-spot: "true"
terminationGracePeriodSeconds: 15
containers:
- name: pi
image: perl:5.34.0
command: ["perl", "-Mbignum=bpi", "-wle", "print bpi(2000)"]
restartPolicy: Never
backoffLimit: 4
ノード アフィニティを使用して Spot Pod をリクエストする
また、ノード アフィニティを使用して Spot Pod をリクエストすることもできます。ノード アフィニティを使用すると、ワークロードを実行するノードをより柔軟に選択できます。たとえば、複数の選択基準を組み合わせると、Pod の実行場所をきめ細かく制御できます。ノード アフィニティを使用して Spot Pod をリクエストする場合は、使用するノード アフィニティの種類を次のように指定できます。
requiredDuringSchedulingIgnoredDuringExecution
: Spot Pod の使用を必須にします。preferredDuringSchedulingIgnoredDuringExecution
: ベスト エフォート ベースで Spot Pod を使用します。
ノード アフィニティを使用して Deployment の Spot Pod を必須にするには、次の nodeAffinity
ルールを Deployment マニフェストに追加します。
apiVersion: batch/v1
kind: Job
metadata:
name: pi
spec:
template:
metadata:
labels:
app: pi
spec:
terminationGracePeriodSeconds: 15
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: cloud.google.com/gke-spot
operator: In
values:
- "true"
containers:
- name: pi
image: perl:5.34.0
command: ["perl", "-Mbignum=bpi", "-wle", "print bpi(2000)"]
restartPolicy: Never
backoffLimit: 4
ベストエフォート ベースで Spot Pod をリクエストする
ノード アフィニティを使用してベスト エフォート ベースで Spot Pod をリクエストするには、preferredDuringSchedulingIgnoredDuringExecution
を使用します。Spot Pod を優先してリクエストすると、GKE は次の順序で Pod をスケジュールします。
- 割り当て可能な容量がある Spot Pod を実行できる既存のノード。
- 割り当て可能な容量がある既存の標準ノード。
- Spot Pod を実行できる新しいノード(コンピューティング リソースが利用可能である場合)。
- 新しい標準ノード。
GKE は、Spot Pod の新しいノードを作成するよりも、割り当て可能な容量を持つ既存の標準ノードを優先するため、Spot Pod よりも標準 Pod として実行される Pod の数が多くなり、Spot Pod のコスト面のメリットを最大限に活用できなくなる可能性があります。
プリエンプティブル Pod のリクエスト
Autopilot クラスタは、cloud.google.com/gke-preemptible
セレクタを使用して、プリエンプティブル Pod のリクエストをサポートします。このセレクタを使用する Pod は、自動的に Spot Pod に移行され、セレクタが cloud.google.com/gke-spot
に変更されます。
終了した Pod を探して削除する
Pod が正常に終了している間、kubelet が Failed
ステータスと Shutdown
理由を終了する Pod に割り当てます。終了した Pod の数がしきい値 1,000 に達すると、ガベージ コレクションによって Pod がクリーンアップされます。次のコマンドを使用して、シャットダウンされる Pod を手動で削除することもできます。
kubectl get pods --all-namespaces | grep -i shutdown | awk '{print $1, $2}' | xargs -n2 kubectl delete pod -n