ACK One(Distributed Cloud Container Platform for Kubernetes)のフリートインスタンスを使用して、Apache Spark ジョブを複数のクラスターにスケジュールおよびディストリビューションします。これにより、オンラインサービスワークロードとリソースを競合させることなく、アイドル状態のクラスター容量を活用してバッチ処理型の Spark ワークロードを実行できます。
仕組み
Spark ジョブを実行する各サブクラスターに、
ack-spark-operatorコンポーネントをインストールします。フリートインスタンス上で
SparkApplicationおよびPropagationPolicyを作成します。グローバルスケジューラ(フリートインスタンスのマルチクラスタースケジューリングコンポーネント)は、Spark ジョブのリソース要求を各関連サブクラスターの残り容量と比較し、最適なターゲットクラスターを選択します。
Kubernetes 1.28 以降を実行するサブクラスターでは、フリートインスタンスがリソースの事前確保をサポートしており、スケジューリング成功率の向上に寄与します。
フリートインスタンスは、選択されたサブクラスターへ
SparkApplicationをディストリビューションします。サブクラスター内の ACK Spark Operator が Spark
driverおよびexecutorPod を起動します。フリートインスタンスはジョブの実行ステータスを監視します。リソース不足によりdriverの起動に失敗した場合、フリートインスタンスはタイムアウト後にSparkApplicationを回収し、十分な容量を持つ別のサブクラスターへ再スケジュールします。
前提条件
開始する前に、以下の条件を満たしていることを確認してください。
Kubernetes 1.18 以降を実行する 2 つ以上のクラスターと関連付けられたフリートインスタンス。詳細については、「関連クラスターの管理」をご参照ください。
リソースアクセス管理 (RAM) ポリシー
AliyunAdcpFullAccessが、お客様の RAM ユーザーにアタッチされています。詳細については、「RAM ユーザーへの権限付与」をご参照ください。AMC コマンドラインツールがインストールされています。詳細については、「AMC コマンドラインの使用」をご参照ください。
手順 1:サブクラスターへの ack-spark-operator のインストール
Spark ジョブを実行したい各サブクラスターに、ack-spark-operator コンポーネントをインストールします。
ACK コンソールにログインします。左側ナビゲーションウィンドウで、マーケットプレイス > マーケットプレイス を選択します。
マーケットプレイス ページで、アプリカタログ タブをクリックし、ack-spark-operator を検索してクリックします。
ack-spark-operator ページで、デプロイ をクリックします。
デプロイ パネルで、クラスターおよび名前空間を選択し、次へ をクリックします。
パラメーター ステップで、パラメーターを設定し、OK をクリックします。
以下の表に、主なパラメーターを示します。パラメーター セクション(ack-spark-operator ページ)で、すべてのパラメーター構成をご確認いただけます。
| パラメーター | 説明 | デフォルト値 |
|---|---|---|
controller.replicas | コントローラーのレプリカ数。 | 1 |
webhook.replicas | Webhook のレプリカ数。 | 1 |
spark.jobNamespaces | Spark ジョブを実行できる名前空間。すべての名前空間を対象とする場合は [""] を指定し、特定の名前空間を対象とする場合はカンマ区切りで列記します(例:["ns1","ns2","ns3"])。 | ["default"] |
spark.serviceAccount.name | spark.jobNamespaces にリストされた各名前空間に自動作成される ServiceAccount の名前。オペレーターは、対応するロールベースアクセス制御(RBAC)リソースも作成します。Spark ジョブの送信時にこの ServiceAccount を参照する予定がある場合は、ここにカスタム名を指定します。 | spark-operator-spark |
手順 2:PriorityClass の作成およびサブクラスターへのディストリビューション
Spark ジョブに低優先度を割り当てることで、オンラインサービスワークロードとのリソース競合を防止します。
フリートインスタンスの kubeconfig ファイルを使用して、負の
valueを持つ低優先度のPriorityClassを作成します。apiVersion: scheduling.k8s.io/v1 kind: PriorityClass metadata: name: low-priority value: -1000 globalDefault: false description: "Low priority for Spark applications"フリートインスタンスで
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 パラメーターに含まれている必要があります。
フリートインスタンス上で名前空間を作成します。
kubectl create ns xxxClusterPropagationPolicyを作成し、名前空間を各サブクラスターへディストリビューションします。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: SparkApplicationSparkApplication の送信
フリートインスタンス上で 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 ジョブの検証
ジョブステータスおよびスケジューリング結果の確認
フリートインスタンスで以下のコマンドを実行し、Spark ジョブのステータスを表示します。
kubectl get sparkapp期待される出力:
NAME STATUS ATTEMPTS START FINISH AGE spark-pi RUNNING 1 2025-02-24T12:10:34Z <no value> 11sジョブがどのサブクラスターへスケジュールされたかを確認するには、以下のコマンドを実行します。
kubectl describe sparkapp spark-pi期待される出力:
Normal ScheduleBindingSucceed 2m29s default-scheduler Binding has been scheduled successfully. Result: {c6xxxxx:0,[{driver 1} {executor 1}]}関連サブクラスターにおけるジョブステータスを表示するには、以下のコマンドを実行します。
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 YPod ステータスを表示するには、以下のコマンドを実行します。
kubectl amc get pod -M期待される出力:
NAME CLUSTER READY STATUS RESTARTS AGE spark-pi-driver c6xxxxxxx 0/1 Completed 0 68sサブクラスターにおける Spark ジョブの詳細情報を表示するには、以下のコマンドを実行します。
kubectl amc get sparkapp spark-pi -m ${member clusterid} -oyaml
トラブルシューティング
ジョブが COMPLETED ステータスに達しない場合は、以下のコマンドで問題を診断してください。
ジョブが `PENDING` ステータスで停止している、またはスケジュールされていない場合:
SparkApplication のイベントを確認し、グローバルスケジューラがスケジューリング失敗を報告していないかを調べます。
kubectl describe sparkapp spark-piScheduleBindingFailed などの理由を持つイベントを確認してください。一般的な原因には、すべてのサブクラスターでリソースが不足していることや、ターゲットクラスターに 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