Как упаковать приложение в образ docker, способный работать на кластере Spark в Kubernetes?

#docker #apache-spark #kubernetes

#docker #apache-spark #kubernetes

Вопрос:

Я новичок в запуске Spark в Kubernetes, и у меня есть очень простое приложение, которое я пытаюсь упаковать для запуска в кластере Spark на K8s, который я настроил. Проблема, с которой я сталкиваюсь, заключается в том, как упаковать мое приложение для запуска в Spark? Я установил Spark на K8 с помощью оператора Spark, и я заметил, что в примерах используется изображение gcr.io/spark-operator/spark:v3.0.0 .

Я заметил, что в документации Spark упоминается этот docker-image-tool.sh скрипт для создания приложения. но похоже, что это было бы для индивидуальной настройки среды. Мне просто нужен облегченный образ, который мое приложение может использовать для запуска в кластере Spark. Не уверен, как связать все это вместе.

Итак, я вижу 2 варианта из документации

  1. Используйте этот файл docker в качестве базового образа.
  2. используйте docker-image-tool.sh скрипт.

Но я не уверен, какой вариант мне нужно выбрать или когда использовать любой вариант? Зачем использовать одно поверх другого? Есть ли другой вариант? Есть ли готовый образ, в который я могу просто скопировать свое приложение и использовать его для запуска?

Ответ №1:

Spark docker-image-tool.sh — это инструментальный скрипт для создания образа Spark. Если вам нужен облегченный образ docker, вы можете просто настроить файл Dockerfile, который поставляется с проектом, или написать свой собственный — не забудьте также отредактировать entrypoint.sh скрипт.

Обычно шаги по доставке вашего приложения Spark в Kubernetes выглядят следующим образом:

  1. Создайте базовый образ spark для использования.
  2. Поместите его в реестр docker — если вы используете minikube, вы можете использовать -m флаг, чтобы переместить его в среду minikube.
  3. Напишите приложение Spark, упакуйте его, а затем запустите spark-submit команду.

Примечание: Если вы не так много инвестируете в Kubernetes и просто хотите быстро опробовать всю эту платформу, вы можете просто прокси kube-api-server , выполнив следующую команду:

 kubectl proxy
  

Оно начнет обслуживать сервер API на localhost:8001 , затем вы сможете отправить свое приложение Spark, выполнив команду типа

 bin/spark-submit 
--master k8s://http:localhost:8001  #If you don't specify the protocol here, it'd default to https
--deploy-mode client  #if you want to go for `cluster mode` then you'd have to set up a service account
--name sparkle 
--class edu.girdharshubham  
--conf spark.executor.instances=1  #Number of pods
--conf spark.kubernetes.container.image=<your-spark-image>
--conf spark.kubernetes.driver.pod.name="sparkle"
--conf spark.kubernetes.hadoop.configMapName="HADOOP_CONF_DIR"
--conf spark.kubernetes.executor.deleteOnTermination
path/to/jar
  

Рассмотрение для запуска в режиме клиента:

  • Убедитесь, что узел — виртуальная машина, с которой вы запускаете вышеупомянутую команду, адресуется по сети из модулей
  • исполнитель (pod) запустит процесс JAVA
  • В файле Dockerfile по умолчанию используется tini — tiny, но допустимый init для контейнеров.
  • spark.kubernetes.executor.deleteOnTermination — Этот conf должен быть вашим переходом к conf, если вы только начинаете, по умолчанию модули удаляются в случае сбоя или нормального завершения. Это помогло бы вам довольно быстро отладить то, что происходит с вашими исполнительными модулями — независимо от того, выходят они из строя или нет.

Комментарии:

1. Отличный вызов deleteOnTermination флага, который очень полезен.

2. Отдельный вопрос — должен ли образ docker, в который вы упаковываете свое приложение, содержать весь дистрибутив spark? Похоже, что даже в docker-image-tool.sh некоторые ненужные вещи упакованы как примеры. Я бы подумал, что может быть просто какая-то клиентская библиотека, которую вы могли бы упаковать в образ docker, а не всю библиотеку spark.

3. Я добавил дополнительный вопрос об использовании базового файла dockerfile в docker-image-tool.sh скрипте — если у вас есть какие-либо идеи по этому вопросу, пожалуйста, поделитесь! Спасибо

4. Привет — когда вы говорите «не забудьте также отредактировать entrypoint.sh скрипт». — что вы имели в виду? Что нам нужно отредактировать в этом файле?

Ответ №2:

Я думаю, что я вас немного смутил. Подготовка образа дистрибутива spark и упаковка вашего приложения — это две разные вещи. Вот как вы могли бы развернуть свое приложение, используя Kuberentes в качестве планировщика.

Шаг 1: Создайте образ Spark

 ./bin/docker-image-tool.sh -r asia.gcr.io/menace -t v3.0.0 build
  

Шаг 2. Поместите образ в реестр Docker

 ./bin/docker-image-tool.sh -r asia.gcr.io/menace -t v3.0.0 push

  

Шаг 3. Настройте свой Kubernetes, чтобы иметь возможность извлекать ваш образ, В большинстве случаев это просто требует настройки imagePullSecrets .

Извлекать изображения из частного реестра

Шаг 4: напишите свое приложение Spark

 package edu.girdharshubham

import scala.math.random

import org.apache.spark.rdd.RDD
import org.apache.spark.sql.SparkSession


object Solution {
  def main(args: Array[String]) {
    val spark = SparkSession
      .builder
      .master("k8s://http://localhost:8001")
      .config("spark.submit.deployMode","client")
      .config("spark.executor.instances", "2")
      .config("spark.kubernetes.container.image", "asia.gcr.io/menace/spark:v3.0.0")
      .appName("sparkle")
      .getOrCreate()

    import spark.implicits._
    val someDF = Seq(
      (8, "bat"),
      (64, "mouse"),
      (-27, "horse")
    ).toDF("number", "word")


    println("========================================================")
    println(someDF.take(1).foreach(println))
    println("========================================================")

    spark.stop()
  }
}
  

Шаг 4. Запустите ваше приложение

 sbt run
  

Это приведет к тому, что в вашем кластере будут созданы модули-исполнители.

Шаг 5: Упакуйте свое приложение

 sbt package
  

Шаг 6: Используйте команду отправки spark для запуска вашего приложения — см. Мой первоначальный ответ

Теперь, возвращаясь к вашему вопросу о упаковке дистрибутива Spark, будьте осторожны с версией, которую вы упаковываете, и зависимостями, которые вы используете. Spark немного не уверен в версиях.

Комментарии:

1. Итак, мой вопрос касается упаковки моего приложения, а не распространения spark. Я установил Spark из spark-operator и мне нужно, чтобы мое приложение было образом docker

2. О! В этом случае вам нужно указать только следующее в своем манифесте. Базовым образом будет ваш дистрибутив spark. « mainApplicationFile: local:///opt/spark/examples/jars/spark-examples_2.12-2.3.0.jar Основной класс: org.apache.spark.examples. SparkPi « Или, если вы просто тестируете его в atm, вы можете упаковать свое приложение вместе с. Поместите свой код в каталог spark и измените файл Dockerfile, чтобы также СКОПИРОВАТЬ это приложение в образ spark

3. Хорошо, я думаю, я понимаю. Итак, мне все еще нужно создать образ со всеми зависимостями spark в нем? Нужно ли мне менять docker-image-tool.sh скрипт, чтобы СКОПИРОВАТЬ в него мой новый код? Или изменить один из файлов docker?

4. Да, вам все равно нужно будет создать базовый образ spark, если вы не планируете использовать образ, предоставленный сообществом. добавьте директиву КОПИРОВАНИЯ в исходный файл dockerfile в kubernetes/dockerfiles/spark/Dockerfile. После этого запустите инструмент docker image с флагом сборки, а затем с флагом push