【问题标题】:Dependency issue with Pyspark running on Kubernetes using spark-on-k8s-operator使用 spark-on-k8s-operator 在 Kubernetes 上运行 Pyspark 的依赖性问题
【发布时间】:2020-06-18 11:23:37
【问题描述】:

我花了几天时间试图找出在 Kubernetes 上运行 (Py)Spark 时遇到的依赖问题。我正在使用spark-on-k8s-operator 和 Spark 的 Google Cloud 连接器。

当我尝试使用带有以下 .yaml 文件的 sparkctl create sparkjob.yaml ... 提交我的 spark 作业没有依赖项时,它就像一个魅力。

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,然后在启动应用程序时从那里获取并复制到驱动程序 pod。每当我想提供我自己的 Python 模块 deps.zip 作为依赖项以便能够在我的主应用程序文件 sparkjob.py 中使用它时,问题就开始了。

这是我迄今为止尝试过的:

1

在 sparkjob.yaml 中的 spark.deps 中添加以下行

pyFiles:
   - ./deps.zip

这导致操作员甚至无法提交带有错误的 Spark 应用程序

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

./deps.zip 与主应用程序文件一起成功上传到 GCS 存储桶,但可以从 GCS 成功获取主应用程序文件(我在没有上述定义的作业日志中看到这一点),@987654332 @ 不能以某种方式从那里获取。我还尝试将 gcs-connector jar 显式添加到 spark.deps.jars 列表中 - 没有任何变化。

2

我将 ./deps.zip 添加到用于启动驱动程序和执行程序 pod 的基本 docker 映像中,方法是将 COPY ./deps.zip /mnt/ 添加到上述 Dockerfile 并在 sparkjob.yaml 中添加依赖项

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

这次可以提交 spark 作业并启动驱动程序 pod,但是在初始化 Spark 上下文时出现file:/mnt/deps.zip not found 错误 我还尝试在 Dockerfile 中另外设置ENV SPARK_EXTRA_CLASSPATH=/mnt/,但没有任何成功。我什至尝试使用卷挂载将整个 /mnt/ 目录显式挂载到驱动程序和执行程序 pod 中,但这也没有用。


编辑:

我的解决方法(2),将依赖项添加到 Docker 映像并在 Dockerfile 中设置 ENV SPARK_EXTRA_CLASSPATH=/mnt/ 确实有效!原来标签没有更新,我一直在使用旧版本的 Docker 镜像。呵呵。

我仍然不知道为什么通过 gcs-connector 的(更优雅的)解决方案 1 不起作用,但它可能与 MountVolume.Setup failed for volume "spark-conf-volume"

【问题讨论】:

    标签: docker apache-spark kubernetes pyspark dependency-management


    【解决方案1】:

    如果 zip 文件包含运行 spark 作业时始终需要的 jar,则面临我刚刚添加的类似问题

    FROM gcr.io/spark-operator/spark-py:v2.4.5
    COPY mydepjars/ /opt/spark/jars/
    

    一切都在我的 spark 会话中加载。可能是一种方法。

    【讨论】:

      【解决方案2】:

      使用 Python 依赖项的 Google Cloud Storage 路径,因为它们已上传到那里。

      spec:
        deps:
          pyFiles:
            - gs://gcs-bucket-name/deps.zip
      

      【讨论】:

      • 我也试过了,我得到了同样的class not found 错误。此外,首先需要将 zip 文件上传到 GCS。由于 spark 操作员在提交期间将主应用程序文件从本地上传到 GCS 并在驱动程序启动期间从那里获取它,我希望它对依赖项执行相同操作,而无需我进行任何手动上传
      猜你喜欢
      • 1970-01-01
      • 2020-11-17
      • 1970-01-01
      • 2016-08-22
      • 2020-07-27
      • 2020-04-03
      • 1970-01-01
      • 2021-08-18
      • 2020-05-08
      相关资源
      最近更新 更多