Uso di YuniKorn come pianificatore personalizzato per Apache Spark in Amazon EMR su EKS - Amazon EMR

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à.

Uso di YuniKorn come pianificatore personalizzato per Apache Spark in 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 processi Spark con un pianificatore YuniKorn su una coda personalizzata e una pianificazione di gruppo.

Panoramica

Apache YuniKorn può aiutarti a gestire la pianificazione di Spark con una pianificazione basata sulle app, così avrai un controllo preciso sulle quote e sulle priorità delle risorse. Con la pianificazione di gruppo, YuniKorn pianifica un'app solo quando è possibile soddisfare la richiesta minima di risorse per l'app. Per ulteriori informazioni, consulta Che cos'è la pianificazione di gruppo nel sito della documentazione di Apache YuniKorn.

Creazione di un cluster ed esecuzione della configurazione per YuniKorn

Utilizza la procedura seguente per implementare un cluster Amazon EKS. Puoi modificare la Regione AWS (region) e le zone di disponibilità (availabilityZones).

  1. 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
  2. Crea il cluster:

    eksctl create cluster -f eks-cluster.yaml
  3. Crea lo spazio dei nomi spark-job in cui eseguirai il processo Spark:

    kubectl create namespace spark-job
  4. Quindi, crea un ruolo e un'associazione di ruoli Kubernetes. Ciò è necessario per l'account di servizio utilizzato dall'esecuzione di processo Spark.

    1. 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
    2. 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 di YuniKorn

  1. Utilizza il seguente comando kubectl per creare uno spazio dei nomi yunikorn per l'implementazione del pianificatore Yunikorn:

    kubectl create namespace yunikorn
  2. 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

Esecuzione di un'applicazione Spark con pianificatore YuniKorn con l'operatore Spark

  1. Se non l'hai già fatto, completa la procedura nelle seguenti sezioni per effettuare la configurazione:

    1. Creazione di un cluster ed esecuzione della configurazione per YuniKorn

    2. Installazione e configurazione di YuniKorn

    3. Configurazione dell'operatore Spark per Amazon su EMR EKS

    4. 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
  2. Crea un file spark-pi.yaml di definizione SparkApplication.

    Per utilizzare YuniKorn come pianificatore per i tuoi processi, devi aggiungere alcune 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 Creazione di un cluster ed esecuzione della configurazione 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"
  3. Invia l'applicazione Spark con il comando seguente. Questa operazione crea anche un oggetto SparkApplication denominato spark-pi:

    kubectl apply -f spark-pi.yaml
  4. Controlla gli eventi dell'oggetto SparkApplication con il comando seguente:

    kubectl describe sparkapplication spark-pi --namespace spark-job

    Il primo evento di 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

Esecuzione di un'applicazione Spark con pianificatore YuniKorn con spark-submit

  1. Per prima cosa, completa le fasi indicate nella sezione Configurazione di spark-submit per Amazon EMR su EKS.

  2. Imposta i valori delle seguenti variabili di ambiente:

    export SPARK_HOME=spark-home export MASTER_URL=k8s://Amazon-EKS-cluster-endpoint
  3. 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 Creazione di un cluster ed esecuzione della configurazione 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
  4. Controlla gli eventi dell'oggetto SparkApplication con il comando seguente:

    kubectl describe pod spark-driver-pod --namespace spark-job

    Il primo evento di 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