Le traduzioni sono generate tramite traduzione automatica. In caso di conflitto tra il contenuto di una traduzione e la versione originale in Inglese, quest'ultima prevarrà.
Utilizzo YuniKorn come scheduler personalizzato per Apache Spark su Amazon EMR su EKS
Con Amazon EMR su EKS, puoi utilizzare l'operatore Spark o spark-submit per eseguire processi Spark con pianificatori personalizzati di Kubernetes. Questo tutorial spiega come eseguire i job Spark con uno YuniKorn scheduler su una coda personalizzata e la pianificazione di gruppo.
Panoramica
Apache YuniKorn
Crea il tuo cluster e preparati per YuniKorn
Utilizza la procedura seguente per implementare un cluster Amazon EKS. Puoi modificare la Regione AWS
(region
) e le zone di disponibilità (availabilityZones
).
-
Definisci il cluster Amazon EKS:
cat <<EOF >eks-cluster.yaml --- apiVersion: eksctl.io/v1alpha5 kind: ClusterConfig metadata: name: emr-eks-cluster region:
eu-west-1
vpc: clusterEndpoints: publicAccess: true privateAccess: true iam: withOIDC: true nodeGroups: - name: spark-jobs labels: { app: spark } instanceType: m5.xlarge desiredCapacity: 2 minSize: 2 maxSize: 3 availabilityZones: ["eu-west-1a"
] EOF -
Crea il cluster:
eksctl create cluster -f eks-cluster.yaml
-
Crea lo spazio dei nomi
spark-job
in cui eseguirai il processo Spark:kubectl create namespace spark-job
-
Quindi, crea un ruolo e un'associazione di ruoli Kubernetes. Ciò è necessario per l'account di servizio utilizzato dall'esecuzione di processo Spark.
-
Definisci l'account di servizio, il ruolo e l'associazione di ruoli per i processi Spark.
cat <<EOF >emr-job-execution-rbac.yaml --- apiVersion: v1 kind: ServiceAccount metadata: name: spark-sa namespace: spark-job automountServiceAccountToken: false --- apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: name: spark-role namespace: spark-job rules: - apiGroups: ["", "batch","extensions"] resources: ["configmaps","serviceaccounts","events","pods","pods/exec","pods/log","pods/portforward","secrets","services","persistentvolumeclaims"] verbs: ["create","delete","get","list","patch","update","watch"] --- apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: spark-sa-rb namespace: spark-job roleRef: apiGroup: rbac.authorization.k8s.io kind: Role name: spark-role subjects: - kind: ServiceAccount name: spark-sa namespace: spark-job EOF
-
Applica la definizione del ruolo e dell'associazione di ruoli Kubernetes con il comando seguente:
kubectl apply -f emr-job-execution-rbac.yaml
-
Installazione e configurazione YuniKorn
-
Utilizza il seguente comando kubectl per creare uno spazio dei nomi
yunikorn
per l'implementazione del pianificatore Yunikorn:kubectl create namespace yunikorn
-
Per installare il pianificatore, esegui i seguenti comandi Helm:
helm repo add yunikorn https://apache.github.io/yunikorn-release
helm repo update
helm install yunikorn yunikorn/yunikorn --namespace yunikorn
Esegui un'applicazione Spark con YuniKorn scheduler con l'operatore Spark
-
Se non l'hai già fatto, completa la procedura nelle seguenti sezioni per effettuare la configurazione:
-
Installazione dell'operatore Spark
Quando esegui il comando
helm install spark-operator-demo
, includi gli argomenti seguenti:--set batchScheduler.enable=true --set webhook.enable=true
-
Crea un file
spark-pi.yaml
di definizioneSparkApplication
.Per utilizzarlo YuniKorn come strumento di pianificazione per i tuoi lavori, devi aggiungere determinate annotazioni ed etichette alla definizione dell'applicazione. Le annotazioni e le etichette specificano la coda per il processo e la strategia di pianificazione che desideri utilizzare.
Nell'esempio seguente, l'annotazione
schedulingPolicyParameters
imposta la pianificazione di gruppo per l'applicazione. Quindi, l'esempio crea gruppi di attività per specificare la capacità minima che deve essere disponibile prima di pianificare i pod per l'avvio dell'esecuzione di processo. Infine, specifica nella definizione del gruppo di attività di utilizzare i gruppi di nodi con l'etichetta"app": "spark"
, come definito nella sezione Crea il tuo cluster e preparati per YuniKorn.apiVersion: "sparkoperator.k8s.io/v1beta2" kind: SparkApplication metadata: name: spark-pi namespace: spark-job spec: type: Scala mode: cluster image: "895885662937.dkr.ecr.
us-west-2
.amazonaws.com/spark/emr-6.10.0:latest
" imagePullPolicy: Always mainClass: org.apache.spark.examples.SparkPi mainApplicationFile: "local:///usr/lib/spark/examples/jars/spark-examples.jar" sparkVersion: "3.3.1" restartPolicy: type: Never volumes: - name: "test-volume" hostPath: path: "/tmp" type: Directory driver: cores: 1 coreLimit: "1200m" memory: "512m" labels: version: 3.3.1 annotations: yunikorn.apache.org/schedulingPolicyParameters: "placeholderTimeoutSeconds=30 gangSchedulingStyle=Hard" yunikorn.apache.org/task-group-name: "spark-driver" yunikorn.apache.org/task-groups: |- [{ "name": "spark-driver", "minMember": 1, "minResource": { "cpu": "1200m", "memory": "1Gi" }, "nodeSelector": { "app": "spark" } }, { "name": "spark-executor", "minMember": 1, "minResource": { "cpu": "1200m", "memory": "1Gi" }, "nodeSelector": { "app": "spark" } }] serviceAccount: spark-sa volumeMounts: - name: "test-volume
" mountPath: "/tmp" executor: cores: 1 instances: 1 memory: "512m" labels: version: 3.3.1 annotations: yunikorn.apache.org/task-group-name: "spark-executor" volumeMounts: - name: "test-volume
" mountPath: "/tmp" -
Invia l'applicazione Spark con il comando seguente. Questa operazione crea anche un oggetto
SparkApplication
denominatospark-pi
:kubectl apply -f spark-pi.yaml
-
Controlla gli eventi dell'oggetto
SparkApplication
con il comando seguente:kubectl describe sparkapplication spark-pi --namespace spark-job
Il primo evento pod mostrerà che YuniKorn ha pianificato i pod:
Type Reason Age From Message ---- ------ ---- ---- ------- Normal Scheduling 3m12s yunikorn spark-operator/org-apache-spark-examples-sparkpi-2a777a88b98b8a95-driver is queued and waiting for allocation Normal GangScheduling 3m12s yunikorn Pod belongs to the taskGroup spark-driver, it will be scheduled as a gang member Normal Scheduled 3m10s yunikorn Successfully assigned spark Normal PodBindSuccessful 3m10s yunikorn Pod spark-operator/ Normal TaskCompleted 2m3s yunikorn Task spark-operator/ Normal Pulling 3m10s kubelet Pulling
Esegui un'applicazione Spark con scheduler con YuniKorn spark-submit
-
Per prima cosa, completa le fasi indicate nella sezione Configurazione di spark-submit per Amazon EMR su EKS.
-
Imposta i valori delle seguenti variabili di ambiente:
export SPARK_HOME=spark-home export MASTER_URL=k8s://
Amazon-EKS-cluster-endpoint
-
Invia l'applicazione Spark con il comando seguente:
Nell'esempio seguente, l'annotazione
schedulingPolicyParameters
imposta la pianificazione di gruppo per l'applicazione. Quindi, l'esempio crea gruppi di attività per specificare la capacità minima che deve essere disponibile prima di pianificare i pod per l'avvio dell'esecuzione di processo. Infine, specifica nella definizione del gruppo di attività di utilizzare i gruppi di nodi con l'etichetta"app": "spark"
, come definito nella sezione Crea il tuo cluster e preparati per YuniKorn.$SPARK_HOME/bin/spark-submit \ --class org.apache.spark.examples.SparkPi \ --master $MASTER_URL \ --conf spark.kubernetes.container.image=895885662937.dkr.ecr.
us-west-2
.amazonaws.com/spark/emr-6.10.0:latest
\ --conf spark.kubernetes.authenticate.driver.serviceAccountName=spark-sa \ --deploy-mode cluster \ --conf spark.kubernetes.namespace=spark-job \ --conf spark.kubernetes.scheduler.name=yunikorn \ --conf spark.kubernetes.driver.annotation.yunikorn.apache.org/schedulingPolicyParameters="placeholderTimeoutSeconds=30 gangSchedulingStyle=Hard" \ --conf spark.kubernetes.driver.annotation.yunikorn.apache.org/task-group-name="spark-driver" \ --conf spark.kubernetes.executor.annotation.yunikorn.apache.org/task-group-name="spark-executor" \ --conf spark.kubernetes.driver.annotation.yunikorn.apache.org/task-groups='[{ "name": "spark-driver", "minMember": 1, "minResource": { "cpu": "1200m", "memory": "1Gi" }, "nodeSelector": { "app": "spark" } }, { "name": "spark-executor", "minMember": 1, "minResource": { "cpu": "1200m", "memory": "1Gi" }, "nodeSelector": { "app": "spark" } }]' \ local:///usr/lib/spark/examples/jars/spark-examples.jar 20 -
Controlla gli eventi dell'oggetto
SparkApplication
con il comando seguente:kubectl describe pod
spark-driver-pod
--namespace spark-jobIl primo evento pod mostrerà che YuniKorn ha programmato i pod:
Type Reason Age From Message ---- ------ ---- ---- ------- Normal Scheduling 3m12s yunikorn spark-operator/org-apache-spark-examples-sparkpi-2a777a88b98b8a95-driver is queued and waiting for allocation Normal GangScheduling 3m12s yunikorn Pod belongs to the taskGroup spark-driver, it will be scheduled as a gang member Normal Scheduled 3m10s yunikorn Successfully assigned spark Normal PodBindSuccessful 3m10s yunikorn Pod spark-operator/ Normal TaskCompleted 2m3s yunikorn Task spark-operator/ Normal Pulling 3m10s kubelet Pulling