全部產品
Search
文件中心

Container Service for Kubernetes:Spark作業的多叢集調度與分發

更新時間:Mar 08, 2025

Apache Spark是一種專門用於大規模資料處理的計算引擎,廣泛應用於資料分析和機器學習等情境。本文介紹如何通過ACK One艦隊將Spark作業在多叢集中進行調度和分發運行,協助您提升多叢集中空閑資源使用率。

工作原理

  1. 為關聯集群安裝ack-spark-operator組件。

  2. 為艦隊建立SparkApplicationPropagationPolicy

  3. 艦隊的多叢集調度組件(Global Scheduler)會根據每個關聯子叢集的剩餘資源,來匹配Spark作業資源請求完成調度。

    對叢集版本為1.28及以上的子叢集,艦隊支援通過資源預占來提高Spark作業調度的成功率。

  4. 艦隊調度完作業後,通過多叢集應用分發SparkApplication至調度選中的關聯集群中。

  5. 在關聯集群中,ACK Spark Operator負責運行Spark作業的driverexecutor。同時艦隊會監視子叢集中Spark作業運行狀態,若driver由於資源不足而無法運行,艦隊會在一定時間後回收該SparkApplication,並重調度到其他資源充足的關聯集群中。

前提條件

  • 艦隊執行個體已添加多個關聯集群,且關聯集群版本為1.18及以上。具體操作,請參見管理關聯集群

  • 已授予RAM使用者AliyunAdcpFullAccess許可權。具體操作,請參見為RAM使用者授權

  • 已安裝AMC命令列工具。具體操作,請參見AMC命令列協助

步驟一:為關聯集群安裝ack-spark-operator組件

請先在期望運行Spark作業的子叢集上安裝ack-spark-operator組件。

  1. 登入Container Service管理主控台,在左側導覽列選擇市場 > 應用市場

  2. 應用市場頁面單擊應用目錄頁簽,然後搜尋並選中ack-spark-operator

  3. ack-spark-operator頁面,單擊一鍵部署

  4. 建立面板中,選擇叢集和命名空間,然後單擊下一步

  5. 參數配置頁面,設定相應參數,然後單擊確定

    下表列出了部分配置參數的說明。完整的參數配置詳情,您可以在ack-spark-operator頁面中的配置項查看。

    參數

    描述

    樣本值

    controller.replicas

    控制器副本數量。

    1(預設值)

    webhook.replicas

    Webhook副本數量。

    1(預設值)

    spark.jobNamespaces

    可運行Spark任務的命名空間列表。包含Null 字元串表示允許所有命名空間。多個命名空間使用英文半形逗號 , 隔開。

    • ["default"](預設值)

    • [""](所有命名空間)

    • ["ns1","ns2","ns3"](多個命名空間)

    spark.serviceAccount.name

    Spark作業會在spark.jobNamespaces指定的每個命名空間中自動建立名為spark-operator-spark的ServiceAccount和RBAC資源並進行相關授權。您可以自訂ServiceAccount名稱,後續提交Spark作業時請指定自訂建立的ServiceAccount名稱。

    spark-operator-spark(預設值)

步驟二:在艦隊上建立PriorityClass,並分發到子叢集

為了保證提交的Spark作業不會搶佔線上服務資源、影響線上服務產品的正常運行,建議對要提交的Spark作業設定低優先順序。

  1. 使用艦隊的KubeConfig,建立一個低優先順序的PriorityClass,其value設定為負數。

    apiVersion: scheduling.k8s.io/v1
    kind: PriorityClass
    metadata:
      name: low-priority
    value: -1000
    globalDefault: false
    description: "Low priority for Spark applications"
  2. 在艦隊中建立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

步驟三:在艦隊上提交Spark作業,並調度到子叢集

  1. (可選)在艦隊中建立Namespace,並下發到子叢集。

    1. 如果待分發應用所在的命名空間在艦隊中不存在,則需要先在艦隊執行個體中建立該命名空間,並確保步驟一中安裝組件的spark.jobNamespaces中包含該命名空間。如果命名空間已存在,則可以跳過此步驟。

      使用艦隊的KubeConfig,執行以下命令,建立相應命名空間。

      kubectl create ns xxx
    2. 子叢集也需要相應的命名空間。如果尚未建立,可以使用ClusterPropagationPolicy將艦隊中的命名空間下發至各個子叢集。

      apiVersion: policy.one.alibabacloud.com/v1alpha1
      kind: ClusterPropagationPolicy
      metadata:
        name: ns-policy
      spec:
        resourceSelectors:
        - apiVersion: v1
          kind: Namespace
          name: xxx
        placement:
          clusterAffinity:
            clusterNames:
            - ${cluster1-id} # 您的叢集ID。
            - ${cluster2-id} # 您的叢集ID。
          replicaScheduling:
            replicaSchedulingType: Duplicated
  2. 在艦隊中建立如下的PropagationPolicy,即可將所有sparkoperator.k8s.io/v1beta2SparkApplication資源下發至相應的叢集中。

    apiVersion: policy.one.alibabacloud.com/v1alpha1
    kind: PropagationPolicy
    metadata:
      name: sparkapp-policy 
      namespace: default
    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
  3. 在艦隊中建立SparkApplication,並在driverexecutor中指定priorityClassName。建立完成後,該應用將由第2步中的PropagationPolicy分發到調度選中的叢集中。

    apiVersion: sparkoperator.k8s.io/v1beta2
    kind: SparkApplication
    metadata:
      name: spark-pi
      namespace: default     # 需要確保命名空間在spark.jobNamespaces指定的命名空間列表中。
    spec:
      type: Scala
      mode: cluster
      image: registry-cn-hangzhou.ack.aliyuncs.com/ack-demo/spark:3.5.4
      imagePullPolicy: IfNotPresent
      mainClass: org.apache.spark.examples.SparkPi
      mainApplicationFile: local:///opt/spark/examples/jars/spark-examples_2.12-3.5.4.jar
      arguments:
      - "1000"
      sparkVersion: 3.5.4
      driver:
        cores: 1
        memory: 512m
        priorityClassName: low-priority
        serviceAccount: spark-operator-spark   # 如果您自訂了ServiceAccount名稱,則需要進行相應修改。
      executor:
        instances: 1
        cores: 1
        memory: 512m
        priorityClassName: low-priority
      restartPolicy:
        type: Never

步驟四:查看Spark作業

  1. 在艦隊中執行以下命令,查看艦隊中Spark作業的狀態。

    kubectl get sparkapp

    預期輸出:

    NAME       STATUS    ATTEMPTS   START                  FINISH       AGE
    spark-pi   RUNNING   1          2025-02-24T12:10:34Z   <no value>   11s
  2. 在艦隊中執行以下命令,在事件中查看Spark作業調度至哪個關聯集群。

    kubectl describe sparkapp spark-pi

    預期輸出:

     Normal   ScheduleBindingSucceed  2m29s                  default-scheduler                   Binding has been scheduled successfully. Result: {c6xxxxx:0,[{driver 1} {executor 1}]}
  3. 在艦隊中執行以下命令,查看關聯集群中Spark作業的狀態。

    kubectl amc get sparkapp -M

    預期輸出:

    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
  4. 在艦隊中執行以下命令,查看Pod狀態。

    kubectl amc get pod -M     

    預期輸出:

    NAME              CLUSTER     READY   STATUS      RESTARTS   AGE
    spark-pi-driver   c6xxxxxxx   0/1     Completed   0          68s
  5. 在艦隊中執行以下命令,查看關聯集群中Spark作業的詳情。

    kubectl amc get sparkapp spark-pi -m ${member clusterid} -oyaml