[Spark-k8s] — Начало работы # Часть 1


Это первая часть серии постов о запуске Spark на Kubernetes. Подробнее о преимуществах использования этого подхода вы можете прочитать в этом посте на Spot.io.

К концу этого поста у вас будет локальная среда, готовая к использованию minikube для запуска spark.

Создание локального окружения

За исключением автомасштабирования, которое я буду моделировать с помощью AWS EKS, Cluster Autoscaler и Karpenter, мы будем использовать эту локальную среду для работы со spark на протяжении всего цикла статей. Пост о масштабируемости будет опубликован в ближайшее время.

Вы должны установить minikube, чтобы использовать его локально. Процедура очень проста, а официальная документация доступна здесь.

Совет: я настоятельно рекомендую установить этот плагин, если вы используете ohmyzsh, поскольку он предоставляет вам альтернативу алиасингу популярных команд kubectl.

Давайте создадим многоузловой кластер с 2 узлами после установки minikube

minikube start --nodes 2 -p my-local-cluster
Войдите в полноэкранный режим Выход из полноэкранного режима

Возможно, вам интересно, почему существует два локальных узла, и ответ заключается в том, что Kubernetes позволяет нам указать, на какой узел мы можем устанавливать наши приложения.
В этом посте мы смоделируем небольшую производственную среду, а в следующем посте драйвер spark будет работать на узлах ON_DEMAND, а исполнители — на узлах SPOT. В результате мы сможем сократить расходы на облако.

Вы можете убедиться, что все получилось, посмотрев на этот вывод в консоли.

Представьте себе следующий гипотетический сценарий: my-local-cluster — это экземпляр ON_DEMAND, а my-local-cluster-m02 — экземпляр SPOT.

Создайте пространство имен обработки, из которого будет выполняться наше задание spark.

$ k create namespace processing

Вход в полноэкранный режим Выход из полноэкранного режима

Установка Spark

Прежде чем мы сможем использовать Spark на Kubernetes, необходимо установить оператор SparkOperator. Google создал этот оператор, который доступен на Github. В двух словах, оператор отвечает за мониторинг кластера на предмет определенных событий, связанных с заданием Spark, известным как kind: SparkApplication.

Самый простой способ установки — следовать документации, используя Helm, но мы можем настроить некоторые интересные функции, загрузив шлем SparkOperator

$ helm repo add spark-operator https://googlecloudplatform.github.io/spark-on-k8s-operator
$ helm pull spark-operator/spark-operator
Вход в полноэкранный режим Выйти из полноэкранного режима

Вы получите следующий результат

Давайте откроем файл values.yaml и внесем некоторые изменения.

...
sparkJobNamespace: "processing"
...
webhook:
  enable: true
  ...
  namespaceSelector: kubernetes.io/metadata.name=processing
...
nodeSelector:
    kubernetes.io/hostname=my-local-cluster
Войти в полноэкранный режим Выйти из полноэкранного режима

sparkJobNamescape указывает, какое пространство имен будет использовать SparkOperator для получения событий spark job.

Поскольку в следующем посте мы будем управлять типами экземпляров для драйверов и исполнителей spark, webhook установлен в true. Сейчас не стоит беспокоиться.

Параметр nodeSelector указывает, на какой экземпляр узла будет установлен модуль SparkOperator. Нам нужно убедиться, что мы не потеряем капсулу spark-оператора, поэтому в нашем гипотетическом примере мы используем экземпляр ON_DEMAND.

Запуск для установки

$ helm install <chart-name> <chart-folder> -n <namespace>
$ helm install spark-operator spark-operator -n spark-operator --create-namespace
Войдите в полноэкранный режим Выйти из полноэкранного режима

Теперь у нас установлен и работает SparkOperator.

Последним шагом будет настройка задания spark для запуска.

Пример задания spark, определенного с помощью файла YAML, приведен ниже. Как видите, мы определяем пространство имен обработки, в котором будут выполняться все наши задания spark, а SparkOperator будет получать от него события.

Кроме того, указан тип: SparkApplication.

apiVersion: "sparkoperator.k8s.io/v1beta2"
kind: SparkApplication
metadata:
  name: my-job-with-operator
  namespace: processing
spec:
  type: Scala
  mode: cluster
  image: "tiagotxm/spark3.1:latest"
  imagePullPolicy: Always 
  mainClass: org.apache.spark.examples.SparkPi
  mainApplicationFile: "local:///opt/spark/examples/jars/spark-examples_2.12-3.1.1.jar"
  sparkVersion: "3.1.1"
  restartPolicy:
    type: Never
  volumes:
    - name: "test-volume"
      hostPath:
        path: "/tmp"
        type: Directory
  driver:
    cores: 1
    coreLimit: "1200m"
    memory: "512m"
    labels:
      version: 3.1.1
    serviceAccount: spark-operator-spark
    volumeMounts:
      - name: "test-volume"
        mountPath: "/tmp"     
  executor:
    cores: 3
    instances: 3
    memory: "512m"
    labels:
      version: 3.1.1
    volumeMounts:
      - name: "test-volume"
        mountPath: "/tmp"
Вход в полноэкранный режим Выйти из полноэкранного режима

Мы будем использовать образ spark и запустим простое задание spark, определенное в файле mainApplicationFile, который содержится в образе.

Давайте приступим к выполнению нашего простого задания.

$ k apply -f hello-spark-operator.yaml
Вход в полноэкранный режим Выход из полноэкранного режима

Мы можем отслеживать запуск задания и все связанные с spark события, такие как создание драйвера prod и исполнителя.

$ kgpw -n processing
Войти в полноэкранный режим Выход из полноэкранного режима

Также можно дважды проверить конечное состояние

$ k get sparkapplications -n processing
Войти в полноэкранный режим Выход из полноэкранного режима

Заключение

В этом посте мы создали локальную среду для запуска заданий spark с двумя пространствами имен. SparkOperator был установлен в пространстве имен spark-operator, и теперь он обрабатывает события spark из пространства имен processing.

Надеюсь, этот пост был полезен, а полный пример вы можете найти в моем git-репозитории.

Спасибо за ваше время!

Вы также можете прочитать на Medium, если хотите
Присоединяйтесь ко мне: https://www.linkedin.com/in/tiagotxm/

Оцените статью
devanswers.ru
Добавить комментарий