はじめに
Kueueを使っている環境にアサインされました。んで、Kueue周りのあれこれを整備しないといけなくなりました。
キャッチアップのためにググってみましたが、Kueueは2022年にリリースされたばかりで、2024年夏現在もあまりインターネット上のラーニングリソースが豊富ではありません。
Kubernetesを実務で使うのも初めてだった僕にはこのキャッチアップは大変ハードルが高いです。
というわけで、ChatGPTさんにチュートリアルを作ってもらって、それをやっていくことで履修しようという試みです。
この記事はGPTさんが作ってくれたチュートリアルコースをやってみながら修正した結果なものです。
とりあえず2024年9月現在動くことは確認してますが、リリースサイクルが早いので時間がたったら動かなくなるかも。
それまでに何かいい資料が出てきていることを祈っています。
チュートリアルをやる前の事前知識
以下の記事が大変参考になりました。
チュートリアルをやる前の環境
- Minikubeが実行できる必要があります
- yamlファイルをいくつか作成するので、ファイルを作るのに都合がいいディレクトリではじめてください
チュートリアルおしながき
- 基本編
- ResourceFlavor編
基本編
1. インストールと前準備
まずはminikube起動。
minikube start
次に最新のリリースバージョンのkueueをインストールします。2024年9月現在 v0.8.0
が最新のようなのでそれを使います。
下のリンクからバージョンを確認できるので、確認しておくといいかもしれません
kubectl apply --server-side -f https://github.com/kubernetes-sigs/kueue/releases/download/v0.8.0/manifests.yaml
apply実行後は、以下のコマンドでpodsの様子を確認しましょう。
kubectl get pods -n kueue-system
STATUSが Running
になったら次に行きましょう。
こんなかんじになります
C:\Users\User>kubectl get pods -n kueue-system
NAME READY STATUS RESTARTS AGE
kueue-controller-manager-5cc87c9d87-snmrm 2/2 Running 0 4m9s
最後に、KueueのLocalQueueが使うnamespaceを作っておきます。
kubectl create namespace team-a
2. Queueの準備
空のResourceFlavorの作成
ResourceFlavorを使わないときにも、空のResourceFlavorの定義が必要になるようです。下のページに従って、空のファイルを作ってapplyしておきます。
apiVersion: kueue.x-k8s.io/v1beta1
kind: ResourceFlavor
metadata:
name: default-flavor
kubectl apply -f empty-resource-flavor.yaml
ClusterQueueの作成
ここから実際にいろいろやっていきます。
まずはClusterQueueを作りましょう。
以下のコードを cluster-queue.yaml
として保存します。
yamlは↓のページから持ってきたものなので、それぞれの項目の意味とかについては本家を読んでください。
apiVersion: kueue.x-k8s.io/v1beta1
kind: ClusterQueue
metadata:
name: "cluster-queue"
spec:
namespaceSelector: {} # match all.
resourceGroups:
- coveredResources: ["cpu", "memory", "pods"]
flavors:
- name: "default-flavor"
resources:
- name: "cpu"
nominalQuota: 9
- name: "memory"
nominalQuota: 36Gi
- name: "pods"
nominalQuota: 5
ファイルを保存したらapplyしてください。
kubectl apply -f cluster-queue.yaml
LocalQueueの作成
次にLocalQueueを用意します。出典と詳細は↓。
apiVersion: kueue.x-k8s.io/v1beta1
kind: LocalQueue
metadata:
namespace: team-a
name: team-a-queue
spec:
clusterQueue: cluster-queue
こちらもファイルを保存してからapplyしてください。
kubectl apply -f local-queue.yaml
ちなみに、LocalQueueは namespace
に属し、その空間内のリソース・スケジュール管理を行うという都合上、名前空間の指定が必須です。yamlで指定した名前空間が存在しないとこういうエラーが出ます。
C:\Users\User>kubectl apply -f local-queue.yaml
Error from server (NotFound): error when creating "local-queue.yaml": namespaces "team-a" not found
ClusterQueueは名前の通りクラスターを対象にするため、名前空間の指定が無くても動きます。
3. ジョブをスケジューリングする
作成したキューを使ってジョブをスケジューリングしていきます。
まず、以下のジョブファイルを保存します。これはGPTさんが作ってくれた。
apiVersion: batch/v1
kind: Job
metadata:
name: example-job
namespace: team-a
labels:
kueue.x-k8s.io/queue-name: team-a-queue
spec:
parallelism: 1
completions: 1
template:
spec:
containers:
- name: example-container
image: busybox
command: ["sh", "-c", "echo Hello, Kubernetes! && sleep 30"]
restartPolicy: Never
このジョブでは、先ほど作ったLocalQueueを使うように指定してあります。metadata.namespace
とmetadata.labels.queue-name
がLocalQueueと一致していることを確認してください。
保存したらapply。
kubectl apply -f example-job.yaml
apply後は以下のコマンドでジョブが実行されている様子を確認できます。
kubectl get workloads -n team-a
Kueueに渡されたJobは、Kueue内部でWorkloadに変換されます。WorkloadはKueueによって生成されるリソースなので、ユーザーが管理する必要はありません。
何回か実行して、FINISHEDがTrue
に変わったことを確認します。
C:\Users\User\Documents\learning_k8s\learning-kueue>kubectl get workloads -n team-a
NAME QUEUE RESERVED IN ADMITTED FINISHED AGE
job-example-job-ca089 team-a-queue cluster-queue True True 18m
では、ほんとに正常に実行できていたのか確認しましょう。logsからexample-jobのログを表示します。
kubectl logs job/example-job -n team-a
うまくいっていれば、echoした文字列が表示されているはずです。
C:\Users\User>kubectl logs job/example-job -n team-a
Hello, Kubernetes!
さらに、kueue-controller-managerのログも見ておきましょう。これはKueueのコントローラーマネージャー、つまり大元です。
これを見れば、Kueueがどのように一連のスケジューリングやジョブ実行をしたのかの流れを追うことができます。
うまく動作しているか確認したいときや、トラブルシュートをする必要があるときに見るところです。
kubectl logs -n kueue-system deployment/kueue-controller-manager
うむ、文字いっぱい。ジョブで指定したQueueの名前も含まれているので、うまくいってたんだろうなという感じがします。たぶん。
ここまで完了出来たら、以下の手順で一度minikube環境をリセットします。
minikube stop
minikube delete
ResourceFlavor編
次のハンズオンではResourceFlavorを使っていきます。
0. 準備
このハンズオンでは2つのノードを使うので、以下の方法でminikubeを2ノードの状態で立ち上げます。
minikube start --nodes 2
kubectl get nodes
次に、それぞれのノードにラベルを付けます。
kubectl label nodes minikube node-type=high-performance
kubectl label nodes minikube-m02 node-type=low-cost
もう一度インストールとnamespaceの作成も。
kubectl apply --server-side -f https://github.com/kubernetes-sigs/kueue/releases/download/v0.8.0/manifests.yaml
kubectl create namespace team-a
1. ResourceFlavorの作成
まずは、2つのリソースフレーバーを定義した resource-flavors.yaml
ファイルを保存します。
このファイルではhihg-performance
とlow-cost
の2つのリソースフレーバーを定義しています。
apiVersion: kueue.x-k8s.io/v1beta1
kind: ResourceFlavor
metadata:
name: high-performance
spec:
nodeLabels:
node-type: high-performance
nodeTaints:
- effect: NoSchedule
key: high-performance
value: "true"
tolerations:
- key: "high-performance-taint"
operator: "Exists"
effect: "NoSchedule"
---
apiVersion: kueue.x-k8s.io/v1beta1
kind: ResourceFlavor
metadata:
name: low-cost
spec:
nodeLabels:
node-type: low-cost
nodeTaints:
- effect: NoSchedule
key: low-cost
value: "true"
tolerations:
- key: "low-cost-taint"
operator: "Exists"
effect: "NoSchedule"
作ったらapply。
kubectl apply -f resource-flavors.yaml
2. ClusterQueueの作成
今回は2つのResourceFlavorを使ったので、ClusterQueueも2つ作っていきます。
別に同じキューに両方のFlavorを入れたりすることもできるんですけど、ハンズオンなのでキュー類は分離してます。わかりやすさ。
apiVersion: kueue.x-k8s.io/v1beta1
kind: ClusterQueue
metadata:
name: high-performance-queue
spec:
namespaceSelector: {}
resourceGroups:
- coveredResources: ["cpu", "memory"]
flavors:
- name: "high-performance"
resources:
- name: "cpu"
nominalQuota: 15
- name: "memory"
nominalQuota: 30Gi
---
apiVersion: kueue.x-k8s.io/v1beta1
kind: ClusterQueue
metadata:
name: low-cost-queue
spec:
namespaceSelector: {}
resourceGroups:
- coveredResources: ["cpu", "memory"]
flavors:
- name: "low-cost"
resources:
- name: "cpu"
nominalQuota: 10
- name: "memory"
nominalQuota: 20Gi
kubectl apply -f rf-cluster-queues.yaml
3. LocalQueueの作成
LocalQueueも2つずつ作ります。
apiVersion: kueue.x-k8s.io/v1beta1
kind: LocalQueue
metadata:
name: high-performance-localqueue
namespace: team-a
spec:
clusterQueue: high-performance-queue
---
apiVersion: kueue.x-k8s.io/v1beta1
kind: LocalQueue
metadata:
name: low-cost-localqueue
namespace: team-a
spec:
clusterQueue: low-cost-queue
kubectl apply -f rf-local-queues.yaml
4. 各リソースの確認
ここまで作ったリソースを確認しておきます。念のため。
すべてkubectl get
コマンドで確認できます。
ResourceFlavorの確認
kubectl get resourceflavors
ClusterQueueの確認
kubectl get clusterqueues -n team-a
LocalQueueの確認
kubectl get localqueues -n team-a
それぞれに、high-performanceとlow-costの2種類のリソースができていることを確認してください。
リソース名の指定と -o
コマンドの指定をすることで、さらなる詳細を見ることもできます。
kubectl get clusterqueue high-performance-queue -o yaml
5. ジョブの作成
最後に、実際に実行するジョブを投入します。
apiVersion: batch/v1
kind: Job
metadata:
name: high-performance-job
namespace: team-a
labels:
kueue.x-k8s.io/queue-name: high-performance-localqueue
spec:
template:
spec:
containers:
- name: example-container
image: busybox
command: ["sh", "-c", "echo Running on high-performance resources! && sleep 30"]
resources:
requests:
cpu: "4"
memory: "8Gi"
nodeSelector:
node-type: high-performance
restartPolicy: Never
backoffLimit: 4
---
apiVersion: batch/v1
kind: Job
metadata:
name: low-cost-job
namespace: team-a
labels:
kueue.x-k8s.io/queue-name: low-cost-localqueue
spec:
template:
spec:
containers:
- name: example-container
image: busybox
command: ["sh", "-c", "echo Running on low-cost resources! && sleep 30"]
resources:
requests:
cpu: "2"
memory: "4Gi"
nodeSelector:
node-type: low-cost
restartPolicy: Never
backoffLimit: 4
kubectl apply -f rf-jobs.yaml
applyしたらkubectl get workload -n team-a
で状況を確認します。ワークロードが受け入れられたことを確認できます。
C:\Users\User>kubectl -n team-a get workloads
NAME QUEUE RESERVED IN ADMITTED FINISHED AGE
job-high-performance-job-ab2f1 high-performance-localqueue high-performance-queue True True 18m
job-low-cost-job-9ad86 low-cost-localqueue low-cost-queue True True 18m
describeでも状況確認ができます。
kubectl describe workload job-high-performance-job-ab2f1 -n team-a
WIP
とりあえずなんとなく基本はわかったような気がしますがまだわからないことも多いです。稚拙な内容ご容赦。
勉強しながらこの記事を適宜更新していくつもりです。まだまだ学習中なので間違ってるところとかあったらコメントください。