L'exécution de tâches Spark sur ECI au sein d'un cluster Kubernetes offre une mise à l'échelle automatique, un déploiement automatisé et une haute disponibilité, améliorant ainsi l'efficacité et la stabilité. Installez Spark Operator dans un ACK Serverless cluster pour exécuter et gérer des tâches Spark sur ECI.
Contexte
Apache Spark est un projet open source largement utilisé dans le domaine de l'analyse de données, notamment pour les charges de travail liées au big data et au machine learning. Depuis la version 2.3.0 d'Apache Spark, il est possible d'exécuter et de gérer des ressources Spark sur Kubernetes.
Spark Operator, conçu spécifiquement pour Spark sur Kubernetes, vous permet de soumettre des tâches Spark à un cluster Kubernetes en les définissant comme des Custom Resource Definitions (CRD). Spark Operator présente les avantages suivants :
Il surmonte les limites du support natif de Spark pour Kubernetes.
Il permet une intégration rapide avec les composants de l'écosystème Kubernetes, tels que le stockage, la surveillance et la journalisation.
Il prend en charge des fonctionnalités avancées de Kubernetes, telles que la récupération après incident, la mise à l'échelle automatique et l'optimisation de la planification.
Prérequis
-
Créez un ACK Serverless cluster.
Créez un ACK Serverless cluster dans la console Container Service for Kubernetes. Pour plus d'informations, consultez la rubrique Créer un ACK Serverless cluster.
ImportantSi vous devez extraire des images depuis Internet ou si votre tâche d'entraînement nécessite un accès Internet, configurez une passerelle NAT.
Vous pouvez utiliser kubectl pour gérer et accéder au ACK Serverless cluster de la manière suivante :
Pour gérer le cluster depuis votre ordinateur local, installez et configurez le client kubectl. Pour plus d'informations, consultez la rubrique Obtenir le fichier kubeconfig d'un cluster et utiliser kubectl pour se connecter au cluster.
Vous pouvez également utiliser kubectl dans Cloud Shell pour gérer le cluster. Pour plus d'informations, consultez la rubrique Utiliser kubectl pour gérer un cluster Kubernetes dans Cloud Shell.
-
Créez un compartiment OSS.
Vous devez créer un compartiment OSS pour stocker les données de test, les résultats des tests et les journaux. Pour plus d'informations, consultez la rubrique Créer un compartiment.
Installer Spark Operator
-
Installez Spark Operator.
Dans le volet de navigation de gauche de la console ACK, choisissez Marketplace > Marketplace.
Sous l'onglet App Catalog, recherchez et cliquez sur ack-spark-operator.
Dans le coin supérieur droit, cliquez sur Deploy.
Dans le panneau qui s'affiche, sélectionnez le cluster cible et configurez-le selon les instructions.
-
Créez un ServiceAccount, un Role et un RoleBinding.
Une tâche Spark nécessite un ServiceAccount disposant des permissions nécessaires pour créer des pods. Créez un ServiceAccount, un Role et un RoleBinding à l'aide du manifeste YAML suivant. Modifiez le namespace si nécessaire.
apiVersion: v1 kind: ServiceAccount metadata: name: spark namespace: default --- apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: namespace: default name: spark-role rules: - apiGroups: [""] resources: ["pods"] verbs: ["*"] - apiGroups: [""] resources: ["services"] verbs: ["*"] --- apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: spark-role-binding namespace: default subjects: - kind: ServiceAccount name: spark namespace: default roleRef: kind: Role name: spark-role apiGroup: rbac.authorization.k8s.io
Créer une image pour la tâche Spark
Compilez le package JAR de votre tâche Spark et empaquetez-le dans une image à l'aide d'un Dockerfile.
Le Dockerfile suivant est basé sur l'image Spark de base fournie par Alibaba Cloud Container Service :
FROM registry.aliyuncs.com/acs/spark:ack-2.4.5-latest
RUN mkdir -p /opt/spark/jars
# If you need to use OSS (for example, to read data from or write events to OSS), add the following JAR packages to the image.
ADD https://repo1.maven.org/maven2/com/aliyun/odps/hadoop-fs-oss/3.3.8-public/hadoop-fs-oss-3.3.8-public.jar $SPARK_HOME/jars
ADD https://repo1.maven.org/maven2/com/aliyun/oss/aliyun-sdk-oss/3.8.1/aliyun-sdk-oss-3.8.1.jar $SPARK_HOME/jars
ADD https://repo1.maven.org/maven2/org/aspectj/aspectjweaver/1.9.5/aspectjweaver-1.9.5.jar $SPARK_HOME/jars
ADD https://repo1.maven.org/maven2/org/jdom/jdom/1.1.3/jdom-1.1.3.jar $SPARK_HOME/jars
COPY SparkExampleScala-assembly-0.1.jar /opt/spark/jars
L'extraction d'une image Spark volumineuse peut prendre du temps. Utilisez ImageCache pour accélérer les extractions d'images. Pour plus d'informations, consultez les rubriques Gérer ImageCache et Utiliser ImageCache pour accélérer la création de pods.
Alibaba Cloud fournit une image de base pour Spark 2.4.5 optimisée pour la planification et l'élasticité Kubernetes, ce qui améliore considérablement les vitesses de planification et de démarrage. Activez cette optimisation en définissant la variable enableAlibabaCloudFeatureGates: true dans le chart Helm. Pour un démarrage encore plus rapide, définissez enableWebhook: false.
operatorImageName: registry.aliyuncs.com/acs/spark-operator
operatorImageVersion: ack-2.4.5-latest
operatorVersion: v2.4.5-v1beta2
imagePullPolicy: IfNotPresent
rbac:
create: true
serviceAccounts:
spark:
create: true
name: spark
sparkoperator:
create: true
name: ack-spark-operator
sparkJobNamespace: "default"
enableWebhook: false
enableMetrics: true
enableAlibabaCloudFeatureGates: false
Créer et soumettre un manifeste de tâche
Créez un fichier de configuration YAML pour la tâche Spark et déployez-la.
-
Créez un fichier spark-pi.yaml.
Voici un exemple de manifeste de tâche. Pour plus d'informations, consultez la documentation spark-on-k8s-operator.
apiVersion: "sparkoperator.k8s.io/v1beta2" kind: SparkApplication metadata: name: spark-pi namespace: default spec: type: Scala mode: cluster image: "registry.aliyuncs.com/acs/spark:ack-2.4.5-latest" imagePullPolicy: Always mainClass: org.apache.spark.examples.SparkPi mainApplicationFile: "local:///opt/spark/examples/jars/spark-examples_2.11-2.4.5.jar" sparkVersion: "2.4.5" restartPolicy: type: Never driver: cores: 2 coreLimit: "2" memory: "3g" memoryOverhead: "1g" labels: version: 2.4.5 serviceAccount: spark annotations: k8s.aliyun.com/eci-kube-proxy-enabled: 'true' k8s.aliyun.com/eci-auto-imc: "true" tolerations: - key: "virtual-kubelet.io/provider" operator: "Exists" executor: cores: 2 instances: 1 memory: "3g" memoryOverhead: "1g" labels: version: 2.4.5 annotations: k8s.aliyun.com/eci-kube-proxy-enabled: 'true' k8s.aliyun.com/eci-auto-imc: "true" tolerations: - key: "virtual-kubelet.io/provider" operator: "Exists" -
Déployez une tâche de calcul Spark.
kubectl apply -f spark-pi.yaml
Configurer la collecte des journaux
Pour collecter les journaux de sortie standard du pilote (driver) et des exécuteurs (executor) Spark, injectez des variables d'environnement dans leur champ envVars. Pour plus d'informations, consultez la rubrique Personnaliser la collecte des journaux pour ECI.
envVars:
aliyun_logs_test-stdout_project: test-k8s-spark
aliyun_logs_test-stdout_machinegroup: k8s-group-app-spark
aliyun_logs_test-stdout: stdout
Définissez ces variables d'environnement pour le pilote et les exécuteurs lors de la soumission de la tâche. Après configuration, consultez les journaux collectés sous l'onglet Raw Logs du Project correspondant dans la console Log Service. Les entrées de journal contiennent des champs tels que __source__, __tag__:__hostname__, __tag__:__path__, __tag__:__user_defined_id__ et __tag__:eci_id, ainsi que le contenu du journal dans le champ content.
Configurer le serveur d'historique
Le serveur d'historique assure le suivi et l'audit des tâches Spark. Ajoutez le champ SparkConf à la CRD SparkApplication pour écrire les événements dans OSS. Le serveur d'historique lit ces événements pour afficher les informations relatives aux tâches. Voici un exemple de configuration :
sparkConf:
"spark.eventLog.enabled": "true"
"spark.eventLog.dir": "oss://bigdatastore/spark-events"
"spark.hadoop.fs.oss.impl": "org.apache.hadoop.fs.aliyun.oss.AliyunOSSFileSystem"
# oss bucket endpoint such as oss-cn-beijing.aliyuncs.com
"spark.hadoop.fs.oss.endpoint": "oss-cn-beijing.aliyuncs.com"
"spark.hadoop.fs.oss.accessKeySecret": ""
"spark.hadoop.fs.oss.accessKeyId": ""
Alibaba Cloud propose également un chart Helm spark-history-server. Recherchez ack-spark-history-server sur la page Marketplace > Marketplace de la console ACK et installez-le. Lors de l'installation, configurez les informations relatives à OSS dans la section Parameters. Exemple :
oss:
enableOSS: true
# Please input your accessKeyId
alibabaCloudAccessKeyId: ""
# Please input your accessKeySecret
alibabaCloudAccessKeySecret: ""
# oss bucket endpoint such as oss-cn-beijing.aliyuncs.com
alibabaCloudOSSEndpoint: "oss-cn-beijing.aliyuncs.com"
# oss file path such as oss://bucket-name/path
eventsDir: "oss://bigdatastore/spark-events"
Après l'installation, repérez le point de terminaison externe de ack-spark-history-server sous Services sur la page des détails du cluster. Accédez à ce point de terminaison pour afficher les tâches archivées. La page Spark History Server répertorie les applications Spark terminées avec des colonnes telles que App ID, App Name, Started, Completed, Duration, Spark User, Last Updated et Event Log. Pour télécharger un journal d'événements, cliquez sur Download dans la ligne correspondante.
Afficher le résultat de la tâche
-
Vérifiez l'état d'exécution des pods.
kubectl get podsSortie attendue :
NAME READY STATUS RESTARTS AGE spark-pi-1547981232122-driver 1/1 Running 0 12s spark-pi-1547981232122-exec-1 1/1 Running 0 3s -
Consultez l'interface utilisateur Spark en temps réel.
kubectl port-forward spark-pi-1547981232122-driver 4040:4040 -
Vérifiez l'état de la SparkApplication.
kubectl describe sparkapplication spark-piSortie attendue :
Name: spark-pi Namespace: default Labels: <none> Annotations: kubectl.kubernetes.io/last-applied-configuration: {"apiVersion":"sparkoperator.k8s.io/v1alpha1","kind":"SparkApplication","metadata":{"annotations":{},"name":"spark-pi","namespace":"default"...}} API Version: sparkoperator.k8s.io/v1alpha1 Kind: SparkApplication Metadata: Creation Timestamp: 2019-01-20T10:47:08Z Generation: 1 Resource Version: 4923532 Self Link: /apis/sparkoperator.k8s.io/v1alpha1/namespaces/default/sparkapplications/spark-pi UID: bbe7445c-1ca0-11e9-9ad4-062fd7c19a7b Spec: Deps: Driver: Core Limit: 200m Cores: 0.1 Labels: Version: 2.4.0 Memory: 512m Service Account: spark Volume Mounts: Mount Path: /tmp Name: test-volume Executor: Cores: 1 Instances: 1 Labels: Version: 2.4.0 Memory: 512m Volume Mounts: Mount Path: /tmp Name: test-volume Image: gcr.io/spark-operator/spark:v2.4.0 Image Pull Policy: Always Main Application File: local:///opt/spark/examples/jars/spark-examples_2.11-2.4.0.jar Main Class: org.apache.spark.examples.SparkPi Mode: cluster Restart Policy: Type: Never Type: Scala Volumes: Host Path: Path: /tmp Type: Directory Name: test-volume Status: Application State: Error Message: State: COMPLETED Driver Info: Pod Name: spark-pi-driver Web UI Port: 31182 Web UI Service Name: spark-pi-ui-svc Execution Attempts: 1 Executor State: Spark - Pi - 1547981232122 - Exec - 1: COMPLETED Last Submission Attempt Time: 2019-01-20T10:47:14Z Spark Application Id: spark-application-1547981285779 Submission Attempts: 1 Termination Time: 2019-01-20T10:48:56Z Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal SparkApplicationAdded 55m spark-operator SparkApplication spark-pi was added, Enqueuing it for submission Normal SparkApplicationSubmitted 55m spark-operator SparkApplication spark-pi was submitted successfully Normal SparkDriverPending 55m (x2 over 55m) spark-operator Driver spark-pi-driver is pending Normal SparkExecutorPending 54m (x3 over 54m) spark-operator Executor spark-pi-1547981232122-exec-1 is pending Normal SparkExecutorRunning 53m (x4 over 54m) spark-operator Executor spark-pi-1547981232122-exec-1 is running Normal SparkDriverRunning 53m (x12 over 55m) spark-operator Driver spark-pi-driver is running Normal SparkExecutorCompleted 53m (x2 over 53m) spark-operator Executor spark-pi-1547981232122-exec-1 completed -
Consultez les journaux pour voir le résultat.
NAME READY STATUS RESTARTS AGE spark-pi-1547981232122-driver 0/1 Completed 0 1mLorsque l'état de la SparkApplication est
COMPLETEDou que l'état du pod pilote Spark estCompleted, consultez les journaux pour vérifier le résultat.kubectl logs spark-pi-1547981232122-driver Pi is roughly 3.152155760778804