本教程使用 Kueue 介绍如何实现 Job 排队系统、配置 Google Kubernetes Engine (GKE) 上不同命名空间之间的工作负载资源和配额共享,以及如何最大限度地提高集群的利用率。
背景
作为基础架构工程师或集群管理员,最大限度地提高命名空间之间的利用率至关重要。一个命名空间中的一批 Job 可能无法充分利用分配给该命名空间的全部配额,而另一个命名空间可能有多个待处理的 Job。如需在不同命名空间的 Job 之间高效地利用集群资源,并提高配额管理的灵活性,您可以在 Kueue 中配置同类群组。同类群组是一组 ClusterQueue,它们可以相互借用未使用的配额。ClusterQueue 用于管理 CPU、内存和硬件加速器等资源池。
您可以参阅 Kueue 文档,了解所有这些概念的详细定义。
目标
本教程适用于希望使用 Kueue 和配额共享在 Kubernetes 上实现 Job 排队系统的基础架构工程师或集群管理员。本教程将模拟两个不同命名空间中的两个团队,每个团队都有自己的专用资源,但可以相互借用。第 3 组资源可以在 Job 累积时用作溢出。
利用 Prometheus Operator 来监控不同命名空间中的 Job 和资源分配。
本教程介绍以下步骤:
- 创建 GKE 集群
- 创建 ResourceFlavor
- 为每个团队创建一个 ClusterQueue 和 LocalQueue
- (可选)使用 Prometheus 部署 kube-prometheus 并监控工作负载
- 创建 Job 并观察允许的工作负载
- 使用同类群组借用未使用的配额
- 添加管理 Spot 虚拟机的溢出 ClusterQueue
费用
本教程使用 Google Cloud 的以下收费组件:您可使用价格计算器根据您的预计使用情况来估算费用。
完成本教程后,您可以删除所创建的资源以避免继续计费。如需了解详情,请参阅清理。
准备工作
设置项目
- Sign in to your Google Cloud account. If you're new to Google Cloud, create an account to evaluate how our products perform in real-world scenarios. New customers also get $300 in free credits to run, test, and deploy workloads.
-
In the Google Cloud console, on the project selector page, click Create project to begin creating a new Google Cloud project.
-
Make sure that billing is enabled for your Google Cloud project.
-
Enable the GKE API.
-
In the Google Cloud console, on the project selector page, click Create project to begin creating a new Google Cloud project.
-
Make sure that billing is enabled for your Google Cloud project.
-
Enable the GKE API.
设置 Google Cloud CLI 的默认值
在 Google Cloud 控制台中,启动 Cloud Shell 实例:
打开 Cloud Shell下载此示例应用的源代码:
git clone https://github.com/GoogleCloudPlatform/kubernetes-engine-samples
设置默认环境变量:
gcloud config set project PROJECT_ID gcloud config set compute/region COMPUTE_REGION
替换以下值:
- PROJECT_ID:您的 Google Cloud 项目 ID。
- COMPUTE_REGION:Compute Engine 区域。
创建 GKE 集群
创建名为
kueue-cohort
的 GKE 集群:您将创建一个集群,该集群在默认池中有 6 个节点(每个可用区 2 个),并且没有自动扩缩功能。 这些是一开始可供团队使用的所有资源,因此它们必须展开竞争。
稍后您将了解 Kueue 如何管理两个团队将发送到相应队列的工作负载。
gcloud container clusters create kueue-cohort --region COMPUTE_REGION \ --release-channel rapid --machine-type e2-standard-4 --num-nodes 2
创建集群后,结果类似于以下内容:
kubeconfig entry generated for kueue-cohort. NAME: kueue-cohort LOCATION: us-central1 MASTER_VERSION: 1.26.2-gke.1000 MASTER_IP: 35.224.108.58 MACHINE_TYPE: e2-medium NODE_VERSION: 1.26.2-gke.1000 NUM_NODES: 6 STATUS: RUNNING
其中,
kueue-cluster
的STATUS
是RUNNING
。创建一个名为
spot
的节点池。此节点池使用 Spot 虚拟机并启用了自动扩缩功能。它从 0 个节点开始,但稍后您会将其提供给团队以用作溢出容量。
gcloud container node-pools create spot --cluster=kueue-cohort --region COMPUTE_REGION \ --spot --enable-autoscaling --max-nodes 20 --num-nodes 0 \ --machine-type e2-standard-4
将 Kueue 的发布版本安装到集群:
VERSION=VERSION kubectl apply -f \ https://github.com/kubernetes-sigs/kueue/releases/download/$VERSION/manifests.yaml
将 VERSION 替换为字母 v 后跟 Kueue 的最新版本,例如
v0.4.0
。如需详细了解 Kueue 版本,请参阅 Kueue 版本。等待 Kueue 控制器准备就绪:
watch kubectl -n kueue-system get pods
在继续下一步之前,输出应类似于以下内容:
NAME READY STATUS RESTARTS AGE kueue-controller-manager-6cfcbb5dc5-rsf8k 2/2 Running 0 3m
创建两个名为
team-a
和team-b
的新命名空间:kubectl create namespace team-a kubectl create namespace team-b
每个命名空间上都将生成 Job。
创建 ResourceFlavor
ResourceFlavor 表示集群节点中的资源变体,例如不同的虚拟机(例如 Spot 与按需)、架构(例如 x86 与 ARM CPU)、品牌和型号(例如 Nvidia A100 与 T4 GPU)。
ResourceFlavors 使用节点标签和污点与集群中的一组节点匹配。
在此清单中:
- ResourceFlavor
on-demand
的标签设置为cloud.google.com/gke-provisioning: standard
。 - ResourceFlavor
spot
的标签设置为cloud.google.com/gke-provisioning: spot
。
为工作负载分配 ResourceFlavor 时,Kueue 会将工作负载的 Pod 分配给匹配为 ResourceFlavor 定义的节点标签的节点。
部署 ResourceFlavor:
kubectl apply -f flavors.yaml
创建 ClusterQueue 和 LocalQueue
创建两个 ClusterQueue cq-team-a
和 cq-team-b
,以及相应的 LocalQueue lq-team-a
和 lq-team-b
,分别加入命名空间 team-a
和 team-b
。
ClusterQueue 是集群范围对象,用于管理 CPU、内存和硬件加速器等资源池。批处理管理员可以将这些对象的公开范围限制为批处理用户。
LocalQueue 是批处理用户可以列出的命名空间内对象。它们指向 CluterQueue,资源将从中分配,以运行 LocalQueue 工作负载。
ClusterQueue 允许资源有多个变体。在本例中,每个 ClusterQueue 都有两种变体(on-demand
和 spot
),均提供 cpu
资源。ResourceFlavor spot
的配额设置为 0
,暂时不使用。
这两个 ClusterQueue 共享在 .spec.cohort
中定义的名为 all-teams
的同类群组。当两个或更多 ClusterQueue 共享一个同类群组时,它们可以向彼此借用未使用的配额。
如需详细了解同类群组的工作原理以及借用语义,请参阅 Kueue 文档。
部署 ClusterQueue 和 LocalQueue:
kubectl apply -f cq-team-a.yaml
kubectl apply -f cq-team-b.yaml
(可选)使用 Prometheus 部署 kube-prometheus 并监控工作负载
您可以使用 Prometheus 监控 Kueue 待处理工作负载和活跃工作负载。如需监控启动的工作负载并观察每个 ClusterQueue 的负载,请将 Prometheus 设置到命名空间监控下的集群。
下载 Prometheus Operator 源代码以进行监控:
cd git clone https://github.com/prometheus-operator/kube-prometheus.git
创建 CustomResourceDefinition (CRD):
kubectl create -f kube-prometheus/manifests/setup
创建监控组件:
kubectl create -f kube-prometheus/manifests
允许 prometheus-operator 从 Kueue 组件中抓取指标:
kubectl apply -f https://github.com/kubernetes-sigs/kueue/releases/download/$VERSION/prometheus.yaml
切换到工作目录:
cd kubernetes-engine-samples/batch/kueue-cohort
启动一个新终端以通过端口转发服务访问 Prometheus:
kubectl --namespace monitoring port-forward svc/prometheus-k8s 9090
在浏览器中通过 localhost:9090 打开 Prometheus
如果使用 Cloud Shell,请点击网页预览,选择“更改端口”,将端口号设置为 9090,然后选择
Change and Preview
。输入监控活跃 ClusterQueue
cq-team-a
的第一个面板的查询:kueue_pending_workloads{cluster_queue="cq-team-a", status="active"} or kueue_admitted_active_workloads{cluster_queue="cq-team-a"}
添加另一个面板,并输入监控活跃 ClusterQueue
cq-team-b
的查询:kueue_pending_workloads{cluster_queue="cq-team-b", status="active"} or kueue_admitted_active_workloads{cluster_queue="cq-team-b"}
添加另一个面板,并输入监控集群中的节点的查询:
count(kube_node_info)
创建 Job 并观察允许的工作负载
为这两个 ClusterQueue(将休眠 10 秒)生成 Job,包含三个并行 Job,三个 Job 都完成才算完成。然后,Job 会在 60 秒后进行清理。
job-team-a.yaml
在命名空间 team-a
下创建 Job,并指向 LocalQueue lq-team-a
和 ClusterQueue cq-team-a
。
同样,job-team-b.yaml
在 team-b
命名空间下创建 Job,并指向 LocalQueue lq-team-b
和 ClusterQueue cq-team-b
。
启动新终端并运行以下脚本,每秒生成一个 Job:
./create_jobs.sh job-team-a.yaml 1
启动另一个终端,并为
team-b
命名空间创建 Job:./create_jobs.sh job-team-b.yaml 1
观察 Prometheus 中正在排队的 Job。或使用以下命令:
watch -n 2 kubectl get clusterqueues -o wide
输出应类似如下所示:
NAME COHORT STRATEGY PENDING WORKLOADS ADMITTED WORKLOADS
cq-team-a all-teams BestEffortFIFO 0 5
cq-team-b all-teams BestEffortFIFO 0 4
使用同类群组借用未使用的配额
ClusterQueue 可能无法始终达到最大容量。当工作负载在 ClusterQueue 中分布不均匀时,配额用量无法最大化。如果 ClusterQueue 彼此共享相同的同类群组,则 ClusterQueue 可以从其他 ClusterQueue 借用配额,以最大限度地提高配额利用率。
当 ClusterQueue
cq-team-a
和cq-team-b
都有 Job 排队后,在相应的终端上按CTRL+c
停止team-b
命名空间的脚本。命名空间
team-b
中的所有待处理 Job 都得到处理后,命名空间team-a
中的 Job 可以借用cq-team-b
中的可用资源:kubectl describe clusterqueue cq-team-a
由于
cq-team-a
和cq-team-b
共享名为all-teams
的同类群组,因此这些 ClusterQueue 能够共享未使用的资源。Flavors Usage: Name: on-demand Resources: Borrowed: 5 Name: cpu Total: 15 Borrowed: 5Gi Name: memory Total: 15Gi
恢复
team-b
命名空间的脚本。./create_jobs.sh job-team-b.yaml 3
观察被借用的
cq-team-a
资源如何变为0
,而cq-team-b
中的资源用于它自己的工作负载:kubectl describe clusterqueue cq-team-a
Flavors Usage: Name: on-demand Resources: Borrowed: 0 Name: cpu Total: 9 Borrowed: 0 Name: memory Total: 9Gi
使用 Spot 虚拟机增加配额
当需要临时增加配额时(例如,为了满足待处理工作负载中的高需求),您可以通过向同类群组添加更多 ClusterQueue 来配置 Kueue 以满足需求。具有未使用资源的 ClusterQueue 可与属于同一同类群组的其他 ClusterQueue 共享这些资源。
在本教程开始时,您使用 Spot 虚拟机创建了名为 spot
的节点池和名为 spot
且标签设置为 cloud.google.com/gke-provisioning: spot
的 ResourceFlavor。创建一个 ClusterQueue 以使用此节点池和表示它的 ResourceFlavor:
创建一个名为
cq-spot
的新 ClusterQueue,同类群组设置为all-teams
:由于此 ClusterQueue 与
cq-team-a
和cq-team-b
共享一个同类群组,因此 ClusterQueuecq-team-a
和cq-team-b
都可以最多借用 15 个 CPU 请求和 15 Gi 内存的资源。kubectl apply -f cq-spot.yaml
在 Prometheus 中,观察
cq-team-a
和cq-team-b
的允许工作负载如何因共享一个同类群组的cq-spot
的配额增加而激增。或使用以下命令:watch -n 2 kubectl get clusterqueues -o wide
在 Prometheus 中,观察集群中的节点数。或使用以下命令:
watch -n 2 kubectl get nodes -o wide
按
CTRL+c
为team-a
和team-b
命名空间停止这两个脚本。
清理
为避免因本教程中使用的资源导致您的 Google Cloud 账号产生费用,请删除包含这些资源的项目,或者保留项目但删除各个资源。
删除项目
- In the Google Cloud console, go to the Manage resources page.
- In the project list, select the project that you want to delete, and then click Delete.
- In the dialog, type the project ID, and then click Shut down to delete the project.
逐个删除资源
删除 Kueue 配额系统:
kubectl delete -n team-a localqueue lq-team-a kubectl delete -n team-b localqueue lq-team-b kubectl delete clusterqueue cq-team-a kubectl delete clusterqueue cq-team-b kubectl delete clusterqueue cq-spot kubectl delete resourceflavor default kubectl delete resourceflavor on-demand kubectl delete resourceflavor spot
删除 Kueue 清单:
VERSION=VERSION kubectl delete -f \ https://github.com/kubernetes-sigs/kueue/releases/download/$VERSION/manifests.yaml
删除集群:
gcloud container clusters delete kueue-cohort --region=COMPUTE_REGION
后续步骤
详细了解如何使用 Kueue 部署批处理系统。
详细了解 GKE 上的作业。