如果您已經擁有多個正在運行線上服務的ACK叢集,並希望在不影響這些服務的情況下,充分利用叢集的空閑資源來運行Spark作業,您可以利用ACK One艦隊的多叢集Spark作業調度和分發能力來提高資源使用率。本文將介紹如何通過ACK One艦隊和ACK Koordinator組件,根據各叢集實際剩餘資源(而非請求資源)來調度和分發多叢集Spark作業,協助您最大化多叢集中閑置資源的利用效率,並通過優先順序控制和離線混合部署能力,確保線上服務的正常運行。
背景資訊
基於叢集實際剩餘資源的多叢集Spark作業的調度和分發方案,主要依賴以下三部分能力:
ACK One艦隊的多叢集Spark作業的調度和分發,包括對實際剩餘資源的感知調度。
ACK Spark Operator支援Koordinator在離線混部特性。
ACK Koordinator的單叢集在離線混部能力。
整體流程如下:
將多個ACK叢集關聯到艦隊,並在各關聯集群中安裝ACK Koordinator組件和ACK Spark Operator組件。
為艦隊建立
SparkApplication和PropagationPolicy。艦隊的多叢集調度組件(Global Scheduler)會根據每個關聯子叢集的剩餘資源,來匹配Spark作業資源請求完成調度。
對叢集版本為1.28及以上的子叢集,艦隊支援通過資源預占來提高Spark作業調度的成功率。
艦隊調度完作業後,通過多叢集應用分發
SparkApplication至調度選中的關聯集群中。在關聯集群中,ACK Spark Operator負責運行Spark作業的
driver和executor。同時艦隊會監視子叢集中Spark作業運行狀態,若driver由於資源不足而無法運行,艦隊會在一定時間後回收該SparkApplication,並重調度到其他資源充足的關聯集群中。
前提條件
步驟一:在關聯集群中配置ack-koordinator
登入Container Service管理主控台,在左側導覽列選擇叢集列表。
在叢集列表頁面,單擊目的地組群名稱,然後在左側導覽列,選擇。
在配置項頁面,單擊使用YAML建立資源,使用以下樣本內容添加配置。詳情請參見在離線混部快速入門。
#ConfigMap ack-slo-config範例。 apiVersion: v1 kind: ConfigMap metadata: name: ack-slo-config namespace: kube-system data: colocation-config: |- { "enable": true } resource-qos-config: |- { "clusterStrategy": { "lsClass": { "cpuQOS": { "enable": true }, "memoryQOS": { "enable": true }, "resctrlQOS": { "enable": true } }, "beClass": { "cpuQOS": { "enable": true }, "memoryQOS": { "enable": true }, "resctrlQOS": { "enable": true } } } } resource-threshold-config: |- { "clusterStrategy": { "enable": true } }
步驟二:(可選)在艦隊中建立命名空間,並下發到子叢集
在各子叢集安裝ack-spark-operator之前,需要確保各子叢集已有待分發的spark應用的命名空間,否則組件安裝會異常。可以通過在艦隊中建立命名空間,使用ClusterPropagationPolicy將其分發至各叢集。本文樣本命名空間為spark。
使用艦隊的KubeConfig串連艦隊執行個體,執行以下命令,建立相應命名空間。
kubectl create ns spark使用
ClusterPropagationPolicy將艦隊的命名空間下發至指定子叢集,如想下發到所有艦隊的關聯集群,可以省略clusterAffinity欄位整個內容。apiVersion: policy.one.alibabacloud.com/v1alpha1 kind: ClusterPropagationPolicy metadata: name: ns-policy spec: resourceSelectors: - apiVersion: v1 kind: Namespace name: spark placement: clusterAffinity: clusterNames: - ${cluster1-id} # 您的叢集ID。 - ${cluster2-id} # 您的叢集ID。 replicaScheduling: replicaSchedulingType: Duplicated
步驟三:在關聯集群中安裝ack-spark-operator
請在期望運行Spark作業的子叢集上安裝ack-spark-operator組件,且版本為2.1.2及以上。
登入Container Service管理主控台,在左側導覽列選擇。
在應用市場頁面單擊應用目錄頁簽,然後搜尋並選中ack-spark-operator。
在ack-spark-operator頁面,單擊一鍵部署。
在建立面板中,選擇叢集和命名空間,然後單擊下一步。
在參數配置頁面,設定相應參數,選擇Chart 版本為2.1.2或更高版本,
jobNamespaces中添加spark,然後單擊確定。重要必須將
SparkApplication所在的namespace添加到spark.jobNamespaces中下表列出了部分配置參數的說明。完整的參數配置詳情,您可以在ack-spark-operator頁面中的配置項查看。
參數
描述
樣本值
controller.replicas控制器副本數量。
1(預設值)
webhook.replicasWebhook副本數量。
1(預設值)
spark.jobNamespaces可運行Spark任務的命名空間列表。包含Null 字元串表示允許所有命名空間。多個命名空間使用英文半形逗號
,隔開。["default"](預設值)[""](所有命名空間)["ns1","ns2","ns3"](多個命名空間)
spark.serviceAccount.nameSpark作業會在
spark.jobNamespaces指定的每個命名空間中自動建立名為spark-operator-spark的ServiceAccount和RBAC資源並進行相關授權。您可以自訂ServiceAccount名稱,後續提交Spark作業時請指定自訂建立的ServiceAccount名稱。spark-operator-spark(預設值)
步驟四:在艦隊上建立PriorityClass,並分發到子叢集
為了保證提交的Spark作業不會搶佔線上服務資源、影響線上服務產品的正常運行,建議對要提交的Spark作業設定低優先順序。
使用艦隊的KubeConfig,建立一個低優先順序的
PriorityClass,其value設定為負數。apiVersion: scheduling.k8s.io/v1 kind: PriorityClass metadata: name: low-priority value: -1000 globalDefault: false description: "Low priority for Spark applications"在艦隊中建立
ClusterPropagationPolicy,將PriorityClass分發到指定叢集中。若您希望將PriorityClass分發到所有關聯集群,可以將clusterAffinity部分刪除。apiVersion: policy.one.alibabacloud.com/v1alpha1 kind: ClusterPropagationPolicy metadata: name: priority-policy spec: preserveResourcesOnDeletion: false resourceSelectors: - apiVersion: scheduling.k8s.io/v1 kind: PriorityClass placement: clusterAffinity: clusterNames: - ${cluster1-id} # 您的叢集ID。 - ${cluster2-id} # 您的叢集ID。 # labelSelector: # matchLabels: # key: value replicaScheduling: replicaSchedulingType: Duplicated
步驟五:在艦隊中提交在離線混部策略的SparkApplicaiton
在艦隊中建立如下
PropagationPolicy,可以將所有sparkoperator.k8s.io/v1beta2的SparkApplication資源都分發到相應的叢集中,若要分發到所有關聯集群,可以省略clusterAffinity整個欄位內容。apiVersion: policy.one.alibabacloud.com/v1alpha1 kind: PropagationPolicy metadata: name: sparkapp-policy namespace: spark spec: preserveResourcesOnDeletion: false propagateDeps: true placement: clusterAffinity: clusterNames: - ${cluster1-id} # 您的叢集ID。 - ${cluster2-id} # 您的叢集ID。 # labelSelector: # matchLabels: # key: value replicaScheduling: replicaSchedulingType: Divided customSchedulingType: Gang resourceSelectors: - apiVersion: sparkoperator.k8s.io/v1beta2 kind: SparkApplication在艦隊中建立Spark作業。可以通過在
SparkApplication中添加註解sparkoperator.k8s.io/koordinator-colocation: "true"來標識driver和executor是否需要根據實際剩餘資源進行調度。本例配置如下所示,表示driver和executor都需要根據實際剩餘資源進行調度。apiVersion: sparkoperator.k8s.io/v1beta2 kind: SparkApplication metadata: name: spark-pi namespace: spark spec: arguments: - "50000" driver: coreLimit: 1000m cores: 1 memory: 512m priorityClassName: low-priority template: metadata: annotations: sparkoperator.k8s.io/koordinator-colocation: "true" spec: containers: - name: spark-kubernetes-driver serviceAccount: spark-operator-spark executor: coreLimit: 1000m cores: 1 instances: 1 memory: 1g priorityClassName: low-priority template: metadata: annotations: sparkoperator.k8s.io/koordinator-colocation: "true" spec: containers: - name: spark-kubernetes-executor image: registry-cn-hangzhou.ack.aliyuncs.com/ack-demo/spark:3.5.4 mainApplicationFile: local:///opt/spark/examples/jars/spark-examples_2.12-3.5.4.jar mainClass: org.apache.spark.examples.SparkPi mode: cluster restartPolicy: type: Never sparkVersion: 3.5.4 type: Scala
步驟六:查看Spark作業狀態
在艦隊中執行以下命令,查看艦隊中Spark作業的狀態。
kubectl get sparkapp -nspark預期輸出:
NAME STATUS ATTEMPTS START FINISH AGE spark-pi RUNNING 1 2025-03-05T11:19:43Z <no value> 48s在艦隊中執行以下命令,在事件中查看Spark作業調度至哪個關聯集群。
kubectl describe sparkapp spark-pi -nspark預期輸出:
Normal ScheduleBindingSucceed 2m29s default-scheduler Binding has been scheduled successfully. Result: {c6xxxxx:0,[{driver 1} {executor 1}]}在艦隊中執行以下命令,查看資源調度分髮狀態。
kubectl get rb spark-pi-sparkapplication -nspark預期輸出:
NAME SCHEDULED FULLYAPPLIED OVERRIDDEN ALLAVAILABLE AGE spark-pi-sparkapplication True True True True在艦隊中執行以下命令,查看關聯集群中Spark作業的狀態。
kubectl amc get sparkapp -M -nspark預期輸出:
NAME CLUSTER STATUS ATTEMPTS START FINISH AGE ADOPTION spark-pi c6xxxxxxx COMPLETED 1 2025-02-24T12:10:34Z 2025-02-24T12:11:20Z 61s Y在艦隊中執行以下命令,查看Pod狀態。
kubectl amc get pod -M -nspark預期輸出:
NAME CLUSTER READY STATUS RESTARTS AGE spark-pi-3c0565956608ad6d-exec-1 c6xxxxxxx 1/1 Running 0 2m35s spark-pi-driver c6xxxxxxx 1/1 Running 0 2m50s在艦隊中執行以下命令,查看關聯集群中Spark作業的詳情。
kubectl amc get sparkapp spark-pi -m ${member clusterid} -oyaml -nspark