Lancer un job Spark dans un cluster Kubernetes en local

Nous en avons déjà parlé, dans les dernières versions de Spark, Kubernetes peut être utilisé comme un orchestrateur à la place de Yarn ou de Mesos. Kubernetes utilise les images docker, ce qui permet de livrer des conteneurs Docker à la place du traditionnel jar ou paquet natif contenant le job Spark. Aussi le déploiement sur Kubernetes permet d'utiliser les ressources dédiées à Kubernetes, ce qui maximise l'utilisation de ces ressources en limitant la fragmentation entre plusieurs clusters, avec un cluster pour le Big Data, un autre pour le deep learning, ou un autre pour servir les API.

Faire tourner un job Spark sur Kubernetes est aussi un bon moyen d'en apprendre plus sur le fonctionnement de Kubernetes en tant qu'orchestrateur de conteneurs.

La documentation sur le site de Spark introduit en détails le sujet. Je vous propose d'ajouter ici des éléments en complémentaire.

Je vous propose de suivre ici le tutoriel proposé sur le site de Spark et d'ajouter des commentaires pertinents au guide déjà existant.

En pratique

Toutes les manipulations ont été réalisées sous Ubuntu 18.04.

En se basant sur la documentation fournie par Spark, ainsi que le Dockerfile fourni depuis Spark 2.3, nous allons voir comment lancer un job Spark à l'aide de Kubernetes (et de Docker).

Nous aurons ainsi besoin de :

Après avoir installé tout ce qu'il vous faut, il faut ensuite builder Spark avec Maven en lançant cette commande depuis le dossier contenant le code source de Spark :

./build/mvn -Pkubernetes -DskipTests clean package

Il faut aussi construire l'image Docker depuis Spark avec la commande suivante :

docker build -t spark:latest -f kubernetes/dockerfiles/spark/Dockerfile .

Vous pouvez maintenant lancer un cluster Kubernetes local grâce à minikube :

minikube start --cpus 3 --memory 4096

Il s'agit maintenant de construire l'image Docker de Spark dans le contexte de Kubernetes. En effet, pour pouvoir lancer des images Docker depuis votre cluster Kubernetes local, il est nécessaire de faire ces manipulations suivantes (placez vous à la racine du dossier contenant la distribution de Spark) :

eval $(minikube docker-env)
docker build -t spark:latest -f kubernetes/dockerfiles/spark/Dockerfile .

Récupérez ensuite l'adresse et le port de votre cluster avec :

kubectl cluster-info

Vous pourrez ensuite lancer un job Spark en mode cluster (en remplaçant hostname par l'adresse IP du cluster et port par le port du cluster) en lançant cette commande depuis la racine du dossier contenant Spark (et non pas le dossier contenant le code source de Spark) :

bin/spark-submit \
    --master k8s://https://<hostname>:<port> \
    --deploy-mode cluster \
    --name spark-pi \
    --class org.apache.spark.examples.SparkPi \
    --conf spark.executor.instances=5 \
    --conf spark.kubernetes.container.image=spark:latest \
    local:///path/to/examples.jar

Monitoring & logs

Conclusion

Le guide proposé sur le site de Spark est assez bien expliqué. Mais il passe assez vite sur certains points et ne mentionne pas par exemple le fait qu'il faille aussi builder Spark à partir du code source ou bien qu'il faille créer l'image Docker dans le contexte de Kubernetes.