本教學課程使用 Kueue,說明如何實作工作佇列系統、在 Google Kubernetes Engine (GKE) 上設定不同命名空間之間的工作負載資源和配額共用,以及盡量提高叢集使用率。
背景
身為基礎架構工程師或叢集管理員,盡量提高命名空間之間的資源用量非常重要。一個命名空間中的工作批次可能無法完全使用指派給該命名空間的完整配額,而另一個命名空間可能有多個待處理的工作。如要在不同命名空間的工作之間有效運用叢集資源,並提高配額管理彈性,可以在 Kueue 中設定同類群組。同類群組是一組 ClusterQueue,可互相借用未使用的配額。 ClusterQueue 會控管 CPU、記憶體和硬體加速器等資源集區。
如要進一步瞭解這些概念,請參閱 Kueue 說明文件。
建立 ResourceFlavors
ResourceFlavor 代表叢集節點中的資源變體,例如不同的 VM (例如 Spot 與隨選)、架構 (例如 x86 與 ARM CPU)、品牌和型號 (例如 Nvidia A100 與 T4 GPU)。
ResourceFlavor 會使用節點標籤和汙點,與叢集中的一組節點相符。
在這個資訊清單中:
- 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 是命名空間物件,批次使用者可以列出這些物件。這些指標會指向 ClusterQueues,資源會從中分配,以執行 LocalQueue 工作負載。
ClusterQueues 允許資源有多種風味。在本例中,兩個 ClusterQueue 都有兩種變種版本,分別是 on-demand
和 spot
,各自提供 cpu
資源。ResourceFlavor spot
的配額設為 0
,目前不會使用。
兩個 ClusterQueue 共用同一個群組 (稱為 all-teams
),定義於 .spec.cohort
中。
如果兩個以上的 ClusterQueue 共用同一個群組,彼此就能借用未使用的配額。
如要進一步瞭解同類群組的運作方式和借用語意,請參閱 Kueue 說明文件。
部署 ClusterQueue 和 LocalQueue:
kubectl apply -f cq-team-a.yaml
kubectl apply -f cq-team-b.yaml
(選用) 使用 kube-prometheus 監控工作負載
您可以使用 Prometheus 監控有效和待處理的 Kueue 工作負載。如要監控啟動的工作負載,並觀察每個 ClusterQueue 的負載,請將 kube-prometheus 部署至命名空間 monitoring
下的叢集:
下載 Prometheus 運算子的原始碼:
cd git clone https://github.com/prometheus-operator/kube-prometheus.git
建立 CustomResourceDefinitions(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
將通訊埠轉送設定為在 GKE 叢集中執行的 Prometheus 服務:
kubectl --namespace monitoring port-forward svc/prometheus-k8s 9090
在瀏覽器中開啟 localhost:9090 的 Prometheus 網頁 UI。
在 Cloud Shell 中:
按一下「網頁預覽」。
按一下「變更通訊埠」,然後將通訊埠編號設為
9090
。按一下「變更並預覽」。
系統會顯示下列 Prometheus 網頁版 UI。
在「Expression」(運算式) 查詢方塊中輸入下列查詢,建立第一個面板,監控
cq-team-a
ClusterQueue 的現行工作負載:kueue_pending_workloads{cluster_queue="cq-team-a", status="active"} or kueue_admitted_active_workloads{cluster_queue="cq-team-a"}
按一下「新增面板」。
在「Expression」(運算式) 查詢方塊中輸入下列查詢,建立另一個面板來監控
cq-team-b
ClusterQueue 的現行工作負載:kueue_pending_workloads{cluster_queue="cq-team-b", status="active"} or kueue_admitted_active_workloads{cluster_queue="cq-team-b"}
按一下「新增面板」。
在「Expression」(運算式) 查詢方塊中輸入下列查詢,建立監控叢集節點數量的面板:
count(kube_node_info)
(選用) 使用 Google Cloud Managed Service for Prometheus 監控工作負載
您可以使用 Google Cloud Managed Service for Prometheus 監控作用中和待處理的 Kueue 工作負載。如需完整的指標清單,請參閱 Kueue 說明文件。
設定身分和 RBAC,以存取指標:
下列設定會建立 4 個 Kubernetes 資源,為 Google Cloud Managed Service for Prometheus 收集器提供指標存取權。
存取 Kueue 指標時,系統會使用
kueue-system
命名空間中的kueue-metrics-reader
ServiceAccount 進行驗證。與
kueue-metrics-reader
服務帳戶相關聯的 Secret 會儲存驗證權杖,供收集器用來向 Kueue 部署作業公開的指標端點進行驗證。kueue-system
命名空間中名為kueue-secret-reader
的角色,可讀取含有服務帳戶權杖的密鑰。授予
kueue-metrics-reader
服務帳戶kueue-metrics-reader
ClusterRole 的 ClusterRoleBinding。
apiVersion: v1 kind: ServiceAccount metadata: name: kueue-metrics-reader namespace: kueue-system --- apiVersion: v1 kind: Secret metadata: name: kueue-metrics-reader-token namespace: kueue-system annotations: kubernetes.io/service-account.name: kueue-metrics-reader type: kubernetes.io/service-account-token --- apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: name: kueue-secret-reader namespace: kueue-system rules: - resources: - secrets apiGroups: [""] verbs: ["get", "list", "watch"] resourceNames: ["kueue-metrics-reader-token"] --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: kueue-metrics-reader subjects: - kind: ServiceAccount name: kueue-metrics-reader namespace: kueue-system roleRef: kind: ClusterRole name: kueue-metrics-reader apiGroup: rbac.authorization.k8s.io
為 Google Cloud Managed Service for Prometheus 設定 RoleBinding:
視您使用的是 Autopilot 或 Standard 叢集而定,您需要在
gke-gmp-system
或gmp-system
命名空間中建立 RoleBinding。這個資源可讓收集器服務帳戶存取kueue-metrics-reader-token
密鑰,以驗證及擷取 Kueue 指標。Autopilot
apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: gmp-system:collector:kueue-secret-reader namespace: kueue-system roleRef: name: kueue-secret-reader kind: Role apiGroup: rbac.authorization.k8s.io subjects: - name: collector namespace: gke-gmp-system kind: ServiceAccount
標準
apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: gmp-system:collector:kueue-secret-reader namespace: kueue-system roleRef: name: kueue-secret-reader kind: Role apiGroup: rbac.authorization.k8s.io subjects: - name: collector namespace: gmp-system kind: ServiceAccount
設定 PodMonitoring 資源:
下列資源會設定 Kueue 部署作業的監控功能,並指定透過 HTTPS 在 /metrics 路徑公開指標。在擷取指標時,系統會使用
kueue-metrics-reader-token
密鑰進行驗證。apiVersion: monitoring.googleapis.com/v1 kind: PodMonitoring metadata: name: kueue namespace: kueue-system spec: selector: matchLabels: control-plane: controller-manager endpoints: - port: 8443 interval: 30s path: /metrics scheme: https tls: insecureSkipVerify: true authorization: type: Bearer credentials: secret: name: kueue-metrics-reader-token key: token
查詢匯出的指標
監控以 Kueue 為基礎的系統時,可使用的 PromQL 查詢範例
您可以透過這些 PromQL 查詢監控重要的 Kueue 指標,例如工作輸送量、佇列的資源使用率和工作負載等待時間,瞭解系統效能並找出潛在瓶頸。
工作處理量
這會計算每個 cluster_queue 在 5 分鐘內允許的工作負載每秒速率。這項指標有助於按佇列細分,找出瓶頸,加總後則可得出整體系統輸送量。
查詢:
sum(rate(kueue_admitted_workloads_total[5m])) by (cluster_queue)
資源使用率
前提是 metrics.enableClusterQueueResources
已啟用。系統會計算每個佇列的目前 CPU 使用量與名義 CPU 配額比率。值越接近 1,表示用量越高。您可以變更資源標籤,將此範例用於記憶體或其他資源。
如要在叢集中安裝自訂設定的 Kueue 發布版本,請參閱 Kueue 說明文件。
查詢:
sum(kueue_cluster_queue_resource_usage{resource="cpu"}) by (cluster_queue) / sum(kueue_cluster_queue_nominal_quota{resource="cpu"}) by (cluster_queue)
佇列等待時間
這項指標會顯示特定佇列中工作負載的第 90 百分位等待時間。您可以修改分位數值 (例如中位數為 0.5,第 99 個百分位數為 0.99),瞭解等待時間分布情形。
查詢:
histogram_quantile(0.9, kueue_admission_wait_time_seconds_bucket{cluster_queue="QUEUE_NAME"})
建立工作並觀察允許的工作負載
在本節中,您將在 team-a
和 team-b
命名空間下建立 Kubernetes Job。Kubernetes 中的 Job 控制器會建立一或多個 Pod,並確保這些 Pod 成功執行特定工作。
產生要傳送至兩個 ClusterQueue 的工作,這些工作會休眠 10 秒,並以三個平行工作完成。然後在 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 中排入佇列的工作。或使用下列指令:
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
透過同類群組借用未使用的配額
ClusterQueues 可能無法隨時達到最大容量。如果工作負載未平均分配到 ClusterQueues,配額用量就不會達到上限。如果 ClusterQueue 之間共用相同同類群組,ClusterQueue 可以從其他 ClusterQueue 借用配額,盡量提高配額使用率。
當 ClusterQueues
cq-team-a
和cq-team-b
都有排隊等待的作業時,請在對應的終端機上按下CTRL+c
,停止team-b
命名空間的指令碼。處理完命名空間
team-b
的所有待處理工作後,命名空間team-a
的工作即可借用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 VM 增加配額
如果需要暫時增加配額 (例如滿足待處理工作負載的高需求),您可以將更多 ClusterQueue 新增至同類群組,藉此設定 Kueue 來滿足需求。如果 ClusterQueue 有未使用的資源,可以與同類群組的其他 ClusterQueue 共用這些資源。
在本教學課程的開頭,您使用 Spot VM 建立名為 spot
的節點集區,並建立名為 spot
的 ResourceFlavor,標籤設為 cloud.google.com/gke-provisioning: spot
。建立 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-spot
新增配額,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
針對
team-a
和team-b
命名空間按下CTRL+c
,停止兩個指令碼。