Проблема зависимости с Pyspark, работающим в Kubernetes, с использованием spark-on-k8s-operator - PullRequest
4 голосов
/ 18 июня 2020

Я потратил несколько дней, пытаясь выяснить проблему зависимости, с которой я столкнулся с (Py) Spark, работающим в Kubernetes. Я использую spark-on-k8s-operator и соединитель Google Cloud от Spark.

Когда я пытаюсь отправить свое искровое задание без зависимости, используя sparkctl create sparkjob.yaml ... с файлом .yaml ниже, он работает как шарм.

apiVersion: "sparkoperator.k8s.io/v1beta2"
kind: SparkApplication
metadata:
  name: spark-job
  namespace: my-namespace
spec:
  type: Python
  pythonVersion: "3"
  hadoopConf:
    "fs.gs.impl": "com.google.cloud.hadoop.fs.gcs.GoogleHadoopFileSystem"
    "fs.AbstractFileSystem.gs.impl": "com.google.cloud.hadoop.fs.gcs.GoogleHadoopFS"
    "fs.gs.project.id": "our-project-id"
    "fs.gs.system.bucket": "gcs-bucket-name"
    "google.cloud.auth.service.account.enable": "true"
    "google.cloud.auth.service.account.json.keyfile": "/mnt/secrets/keyfile.json"
  mode: cluster
  image: "image-registry/spark-base-image"
  imagePullPolicy: Always
  mainApplicationFile: ./sparkjob.py
  deps:
    jars:
      - https://repo1.maven.org/maven2/org/apache/spark/spark-sql-kafka-0-10_2.11/2.4.5/spark-sql-kafka-0-10_2.11-2.4.5.jar
  sparkVersion: "2.4.5"
  restartPolicy:
    type: OnFailure
    onFailureRetries: 3
    onFailureRetryInterval: 10
    onSubmissionFailureRetries: 5
    onSubmissionFailureRetryInterval: 20
  driver:
    cores: 1
    coreLimit: "1200m"
    memory: "512m"
    labels:
      version: 2.4.5
    serviceAccount: spark-operator-spark
    secrets:
    - name: "keyfile"
      path: "/mnt/secrets"
      secretType: GCPServiceAccount
    envVars:
      GCS_PROJECT_ID: our-project-id
  executor:
    cores: 1
    instances: 1
    memory: "512m"
    labels:
      version: 2.4.5
    secrets:
    - name: "keyfile"
      path: "/mnt/secrets"
      secretType: GCPServiceAccount
    envVars:
      GCS_PROJECT_ID: our-project-id

Образ Docker spark-base-image построен с помощью Dockerfile

FROM gcr.io/spark-operator/spark-py:v2.4.5

RUN rm $SPARK_HOME/jars/guava-14.0.1.jar
ADD https://repo1.maven.org/maven2/com/google/guava/guava/28.0-jre/guava-28.0-jre.jar $SPARK_HOME/jars

ADD https://repo1.maven.org/maven2/com/google/cloud/bigdataoss/gcs-connector/hadoop2-2.0.1/gcs-connector-hadoop2-2.0.1-shaded.jar $SPARK_HOME/jars

ENTRYPOINT [ "/opt/entrypoint.sh" ]

основной файл приложения загружается в GCS при отправке приложения, а затем извлекается оттуда и копируется в модуль драйвера при запуске приложения. Проблема начинается всякий раз, когда я хочу предоставить свой собственный Python модуль deps.zip в качестве зависимости, чтобы иметь возможность использовать его в моем основном файле приложения sparkjob.py.

Вот что я пробовал до сих пор:

1

Добавлены следующие строки в spark.deps в sparkjob.yaml

pyFiles:
   - ./deps.zip

, что привело к тому, что оператор не мог даже отправить приложение Spark с ошибкой

java.lang.RuntimeException: java.lang.ClassNotFoundException: Class com.google.cloud.hadoop.fs.gcs.GoogleHadoopFileSystem not found

./deps.zip успешно загружено в корзину GCS вместе с основным файлом приложения, но в то время как основной файл приложения может быть успешно извлечен из GCS (я вижу это в журналах в заданиях без зависимостей, как определено выше), ./deps.zip оттуда как-то не достать. Я также пробовал явно добавить банку gcs-connector в список spark.deps.jars - ничего не изменилось.

2

Я добавил ./deps.zip в базовый образ docker, используемый для запуска поднимите модули драйвера и исполнителя, добавив COPY ./deps.zip /mnt/ в указанный выше файл Docker и добавив зависимость в sparkjob.yaml через

pyFiles:
    - local:///mnt/deps.zip

На этот раз задание Spark может быть отправлено и модуль драйвера запущен, однако Я получаю ошибку file:/mnt/deps.zip not found при инициализации контекста Spark. Я также пытался дополнительно установить ENV SPARK_EXTRA_CLASSPATH=/mnt/ в Dockerfile, но безуспешно. Я даже попытался явно смонтировать весь каталог /mnt/ в модули драйвера и исполнителя, используя монтирование томов, но это тоже не сработало.

изменить:

Мой обходной путь (2), добавление зависимостей к образу Docker и настройка ENV SPARK_EXTRA_CLASSPATH=/mnt/ в Dockerfile действительно сработали! Оказалось, что тег не обновился, и я все время использовал старую версию изображения Docker. Да.

Я до сих пор не знаю, почему (более элегантное) решение 1 через gcs-коннектор не работает, но это может быть связано с MountVolume.Setup failed for volume "spark- conf-volume "

1 Ответ

0 голосов
/ 27 июня 2020

Используйте путь Google Cloud Storage к python зависимостям, поскольку они загружены туда.

spec:
  deps:
    pyFiles:
      - gs://gcs-bucket-name/deps.zip
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...