すべてのプロダクト
Search
ドキュメントセンター

Container Service for Kubernetes:Spark ジョブのマルチクラスター間スケジューリングおよびディストリビューション

最終更新日:Mar 26, 2026

ACK One(Distributed Cloud Container Platform for Kubernetes)のフリートインスタンスを使用して、Apache Spark ジョブを複数のクラスターにスケジュールおよびディストリビューションします。これにより、オンラインサービスワークロードとリソースを競合させることなく、アイドル状態のクラスター容量を活用してバッチ処理型の Spark ワークロードを実行できます。

仕組み

image
  1. Spark ジョブを実行する各サブクラスターに、ack-spark-operator コンポーネントをインストールします。

  2. フリートインスタンス上で SparkApplication および PropagationPolicy を作成します。

  3. グローバルスケジューラ(フリートインスタンスのマルチクラスタースケジューリングコンポーネント)は、Spark ジョブのリソース要求を各関連サブクラスターの残り容量と比較し、最適なターゲットクラスターを選択します。

    Kubernetes 1.28 以降を実行するサブクラスターでは、フリートインスタンスがリソースの事前確保をサポートしており、スケジューリング成功率の向上に寄与します。

  4. フリートインスタンスは、選択されたサブクラスターへ SparkApplication をディストリビューションします。

  5. サブクラスター内の ACK Spark Operator が Spark driver および executor Pod を起動します。フリートインスタンスはジョブの実行ステータスを監視します。リソース不足により driver の起動に失敗した場合、フリートインスタンスはタイムアウト後に SparkApplication を回収し、十分な容量を持つ別のサブクラスターへ再スケジュールします。

前提条件

開始する前に、以下の条件を満たしていることを確認してください。

  • Kubernetes 1.18 以降を実行する 2 つ以上のクラスターと関連付けられたフリートインスタンス。詳細については、「関連クラスターの管理」をご参照ください。

  • リソースアクセス管理 (RAM) ポリシー AliyunAdcpFullAccess が、お客様の RAM ユーザーにアタッチされています。詳細については、「RAM ユーザーへの権限付与」をご参照ください。

  • AMC コマンドラインツールがインストールされています。詳細については、「AMC コマンドラインの使用」をご参照ください。

手順 1:サブクラスターへの ack-spark-operator のインストール

Spark ジョブを実行したい各サブクラスターに、ack-spark-operator コンポーネントをインストールします。

  1. ACK コンソールにログインします。左側ナビゲーションウィンドウで、マーケットプレイス > マーケットプレイス を選択します。

  2. マーケットプレイス ページで、アプリカタログ タブをクリックし、ack-spark-operator を検索してクリックします。

  3. ack-spark-operator ページで、デプロイ をクリックします。

  4. デプロイ パネルで、クラスターおよび名前空間を選択し、次へ をクリックします。

  5. パラメーター ステップで、パラメーターを設定し、OK をクリックします。

以下の表に、主なパラメーターを示します。パラメーター セクション(ack-spark-operator ページ)で、すべてのパラメーター構成をご確認いただけます。

パラメーター説明デフォルト値
controller.replicasコントローラーのレプリカ数。1
webhook.replicasWebhook のレプリカ数。1
spark.jobNamespacesSpark ジョブを実行できる名前空間。すべての名前空間を対象とする場合は [""] を指定し、特定の名前空間を対象とする場合はカンマ区切りで列記します(例:["ns1","ns2","ns3"])。["default"]
spark.serviceAccount.namespark.jobNamespaces にリストされた各名前空間に自動作成される ServiceAccount の名前。オペレーターは、対応するロールベースアクセス制御(RBAC)リソースも作成します。Spark ジョブの送信時にこの ServiceAccount を参照する予定がある場合は、ここにカスタム名を指定します。spark-operator-spark

手順 2:PriorityClass の作成およびサブクラスターへのディストリビューション

Spark ジョブに低優先度を割り当てることで、オンラインサービスワークロードとのリソース競合を防止します。

  1. フリートインスタンスの kubeconfig ファイルを使用して、負の value を持つ低優先度の PriorityClass を作成します。

    apiVersion: scheduling.k8s.io/v1
    kind: PriorityClass
    metadata:
      name: low-priority
    value: -1000
    globalDefault: false
    description: "Low priority for Spark applications"
  2. フリートインスタンスで ClusterPropagationPolicy を作成し、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

手順 3:フリートインスタンス上での Spark ジョブの送信

(任意)名前空間の作成およびサブクラスターへのディストリビューション

SparkApplication を実行する名前空間がフリートインスタンス上にまだ存在しない場合は、まずその名前空間を作成してください。また、この名前空間は手順 1 で設定した spark.jobNamespaces パラメーターに含まれている必要があります。

  1. フリートインスタンス上で名前空間を作成します。

    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

SparkApplication の PropagationPolicy の作成

フリートインスタンスで PropagationPolicy を作成します。このポリシーにより、グローバルスケジューラは、Gang スケジューリングを用いて、SparkApplication リソース(API バージョン:sparkoperator.k8s.io/v1beta2)を対象サブクラスターへディストリビューションします。

apiVersion: policy.one.alibabacloud.com/v1alpha1
kind: PropagationPolicy
metadata:
  name: sparkapp-policy
  namespace: default
spec:
  preserveResourcesOnDeletion: false
  propagateDeps: true   # driver スペック内で参照される ServiceAccount などの依存リソースを、対象サブクラスターへ自動的にディストリビューションします。
  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

SparkApplication の送信

フリートインスタンス上で SparkApplication を作成します。priorityClassName を、手順 2 で作成した PriorityClass に設定し、driver および executor の両方で使用します。

グローバルスケジューラは、memory および cores の値(driver および executor スペック内)を Kubernetes リソース要求として解釈します。これらの合計要求リソースを各サブクラスターの残り容量と比較し、ターゲットクラスターを選択します。これらの値は、ジョブが実際に必要とするリソース量を正確に反映するよう設定してください。過小設定の場合、スケジューリングは成功してもランタイムでジョブが失敗する可能性があります。過大設定の場合、どのクラスターにも十分な容量がないため、スケジューリング自体が失敗する可能性があります。

SparkApplication を作成すると、前のステップで作成した 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   # 手順 1 で指定したカスタム名に置き換えてください。
  executor:
    instances: 1
    cores: 1
    memory: 512m
    priorityClassName: low-priority
  restartPolicy:
    type: Never

手順 4: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. ジョブがどのサブクラスターへスケジュールされたかを確認するには、以下のコマンドを実行します。

    kubectl describe sparkapp spark-pi

    期待される出力:

    Normal   ScheduleBindingSucceed  2m29s                  default-scheduler                   Binding has been scheduled successfully. Result: {c6xxxxx:0,[{driver 1} {executor 1}]}
  3. 関連サブクラスターにおけるジョブステータスを表示するには、以下のコマンドを実行します。

    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

トラブルシューティング

ジョブが COMPLETED ステータスに達しない場合は、以下のコマンドで問題を診断してください。

ジョブが `PENDING` ステータスで停止している、またはスケジュールされていない場合:

SparkApplication のイベントを確認し、グローバルスケジューラがスケジューリング失敗を報告していないかを調べます。

kubectl describe sparkapp spark-pi

ScheduleBindingFailed などの理由を持つイベントを確認してください。一般的な原因には、すべてのサブクラスターでリソースが不足していることや、ターゲットクラスターに PriorityClass が存在しないことが挙げられます。

Driver Pod が起動しない場合:

サブクラスター内の Driver Pod のイベントを確認します。

kubectl amc get pod -M
kubectl amc describe pod spark-pi-driver -m ${member clusterid}

サブクラスターでオペレーターが実行されていない場合:

サブクラスター内で ack-spark-operator が実行中であることを確認します。

kubectl amc get pod -n spark-operator -M

次のステップ