このチュートリアルでは、Kueue を使用して Google Kubernetes Engine(GKE)で Job をスケジュール設定し、利用可能なリソースを最適化する方法について説明します。このチュートリアルでは、Kueue を使用してバッチジョブを効果的に管理およびスケジュール設定し、リソース使用率を向上させ、ワークロード管理を簡素化する方法について確認します。2 つのテナントチーム用に共有クラスタを設定します。各チームには独自の名前空間があり、各チームはグローバル リソースを共有する Job を作成します。また、定義したリソース割り当てに基づいて Job をスケジュール設定するように Kueue を構成します。
このチュートリアルは、GKE を使用したバッチシステムの実装に関心があるクラウド アーキテクトとプラットフォーム エンジニアを対象としています。 Google Cloudのコンテンツで使用されている一般的なロールとタスクの例の詳細については、一般的な GKE ユーザーのロールとタスクをご覧ください。
このページを読む前に、次のことをよく理解しておいてください。
背景
ジョブは、ML、レンダリング、シミュレーション、分析、CI / CD、その他の同様のワークロードなど、最後まで実行されるアプリケーションです。
Kueue は、デフォルトの Kubernetes スケジューラ、ジョブ コントローラ、クラスタ オートスケーラーと連携して、エンドツーエンドのバッチシステムを提供する、クラウド ネイティブなジョブ スケジューラです。Kueue は Job キューイングを実装しており、チーム間で公平にリソースを共有するための割り当てや階層に基づいて Job を待機するタイミングや開始するタイミングを決定します。
Kueue には次の特長があります。
- リソースが異種で交換可能でスケーラブルであるクラウド アーキテクチャに最適化されています。
- 弾力的な割り当てを管理し、ジョブ キューイングを管理するための一連の API を提供します。
- 自動スケーリング、Pod スケジューリング、ジョブのライフサイクル管理などの既存の機能は再実装されません。
- Kueue には、Kubernetes
batch/v1.Job
API の組み込みサポートがあります。 - 他のジョブ API と統合できます。
Kueue は、特定の Kubernetes Job API との混乱を避けるため、任意の API で定義されたジョブをワークロードと呼びます。
ResourceFlavor を作成する
ResourceFlavor は、ノードラベルと taint に関連付けることで、クラスタで使用可能なノードのバリエーションを表すオブジェクトです。たとえば、ResourceFlavors を使用して、異なるプロビジョニングの保証(例えば、Spot とオンデマンド)、アーキテクチャ(例えば、x86 と ARM の CPU)、ブランド、モデル(例えば、Nvidia A100 と T4 GPU)を持つ VM を表すことができます。
このチュートリアルでは、kueue-autopilot
クラスタに均質なリソースがあります。その結果、CPU、メモリ、エフェメラル ストレージ、GPU 用に、ラベルや taint のない単一の ResourceFlavor を作成します。
kubectl apply -f flavors.yaml
ClusterQueue を作成する
ClusterQueue は、CPU、メモリ、GPU などのリソースのプールを管理するクラスタ スコープド オブジェクトです。ResourceFlavors を管理して使用量を制限し、ワークロードが許可される順序を指定します。
ClusterQueue をデプロイするには:
kubectl apply -f cluster-queue.yaml
使用順序は .spec.queueingStrategy
によって決定されます。ここで、次の 2 つの構成があります。
BestEffortFIFO
- デフォルトのキューイング戦略構成。
- ワークロードの承諾は、先入れ先出し(FIFO)ルールに従いますが、キューの先頭にワークロードを承諾できるだけの十分な割り当てがない場合は、その次の行が試行されます。
StrictFIFO
- FIFO のセマンティクスを保証します。
- キューの先頭のワークロードは、ワークロードが承諾されるまでキューをブロックできます。
cluster-queue.yaml
で、cluster-queue
という新しい ClusterQueue を作成します。この ClusterQueue は、flavors.yaml
で作成されたフレーバーを使用して、cpu
、memory
、nvidia.com/gpu
、ephemeral-storage
の 4 つのリソースを管理します。割り当ては、ワークロード Pod 仕様のリクエストによって消費されます。
各フレーバーには、.spec.resourceGroups[].flavors[].resources[].nominalQuota
で表される使用制限が含まれています。この場合、ClusterQueue は、次の場合にのみワークロードを承諾します。
- CPU リクエストの合計が 10 以下
- メモリ リクエストの合計が 10 Gi 以下
- GPU リクエストの合計が 10 以下
- ストレージ; 保存容量の合計が 10Gi 以下
LocalQueue を作成する
LocalQueue は、Namespace 内のユーザーからのワークロードを受け入れる Namespace オブジェクトです。異なる Namespace の LocalQueue は、リソースの割り当てを共有できる同じ ClusterQueue を指すことができます。この場合、Namespace team-a
と team-b
の LocalQueue は、.spec.clusterQueue
の下の同じ ClusterQueue cluster-queue
を指します。
各チームは、ワークロードを独自の Namespace 内の LocalQueue に送信します。ClusterQueue によってリソースが割り当てられます。
LocalQueues をデプロイします。
kubectl apply -f local-queue.yaml
Job を作成して許可されたワークロードをモニタリングする
このセクションでは、Namespace team-a
に Kubernetes Job を作成します。Kubernetes の Job コントローラは、1 つ以上の Pod を作成し、特定のタスクが正常に実行されるようにします。
Namespace team-a
の Job には次の属性があります。
- これは
lq-team-a
LocalQueue を指します。 nodeSelector
フィールドをnvidia-tesla-t4
に設定して、GPU リソースをリクエストします。- これは、並行して 10 秒間スリープする 3 つの Pod で構成されています。Job は、
ttlSecondsAfterFinished
フィールドで定義された値に従って 60 秒後に削除されます。 - この Job には、3 つの Pod があるため、1,500 milliCPU、1,536 Mi のメモリ、1,536 Mi のエフェメラル ストレージ、3 つの GPU が必要です。
Job はファイル job-team-b.yaml
の下に作成され、その Namespace は team-b
に属し、異なるニーズが異なるチームを表すリクエストがあります。
詳細については、Autopilot での GPU ワークロードのデプロイをご覧ください。
新しいターミナルで、2 秒ごとに更新される ClusterQueue のステータスを確認します。
watch -n 2 kubectl get clusterqueue cluster-queue -o wide
新しいターミナルで、ノードのステータスを確認します。
watch -n 2 kubectl get nodes -o wide
新しいターミナルで、Namespace
team-a
とteam-b
から LocalQueue への Job を 10 秒ごとに作成します。./create_jobs.sh job-team-a.yaml job-team-b.yaml 10
Job がキューに格納され、ClusterQueue に承諾され、ノードが GKE Autopilot とともに起動することを確認します。
Namespace
team-a
から Job を取得します。kubectl -n team-a get jobs
結果は次のようになります。
NAME COMPLETIONS DURATION AGE sample-job-team-b-t6jnr 3/3 21s 3m27s sample-job-team-a-tm7kc 0/3 2m27s sample-job-team-a-vjtnw 3/3 30s 3m50s sample-job-team-b-vn6rp 0/3 40s sample-job-team-a-z86h2 0/3 2m15s sample-job-team-b-zfwj8 0/3 28s sample-job-team-a-zjkbj 0/3 4s sample-job-team-a-zzvjg 3/3 83s 4m50s
前の手順の Job 名をコピーし、Workloads API を通じて Job の承諾ステータスとイベントを確認します。
kubectl -n team-a describe workload JOB_NAME
保留中の Job が ClusterQueue から増加し始めたら、実行中のスクリプトで
CTRL + C
を押してスクリプトを終了します。すべての Job が完了したら、ノードがスケールダウンされています。