微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何在 GKE 上的 Spark 应用程序中修复“NullPointerException:projectId 不能为 null”?

如何解决如何在 GKE 上的 Spark 应用程序中修复“NullPointerException:projectId 不能为 null”?

我正在将 Spark Structured Streaming 应用程序部署到 Google Kubernetes Engine,在使用 gs:// URI 方案访问存储桶时,我遇到了以下异常:

Exception in thread "main" java.lang.NullPointerException: projectId must not be null
    at com.google.cloud.hadoop.repackaged.gcs.com.google.common.base.Preconditions.checkNotNull(Preconditions.java:897)
    at com.google.cloud.hadoop.repackaged.gcs.com.google.cloud.hadoop.gcsio.GoogleCloudStorageImpl.createBucket(GoogleCloudStorageImpl.java:437)
    at com.google.cloud.hadoop.repackaged.gcs.com.google.cloud.hadoop.gcsio.GoogleCloudStorage.createBucket(GoogleCloudStorage.java:88)
    at com.google.cloud.hadoop.repackaged.gcs.com.google.cloud.hadoop.gcsio.GoogleCloudStorageFileSystem.mkdirsInternal(GoogleCloudStorageFileSystem.java:456)
    at com.google.cloud.hadoop.repackaged.gcs.com.google.cloud.hadoop.gcsio.GoogleCloudStorageFileSystem.mkdirs(GoogleCloudStorageFileSystem.java:444)
    at com.google.cloud.hadoop.fs.gcs.GoogleHadoopFileSystemBase.mkdirs(GoogleHadoopFileSystemBase.java:911)
    at org.apache.hadoop.fs.FileSystem.mkdirs(FileSystem.java:2275)
    at org.apache.spark.sql.execution.streaming.StreamExecution.<init>(StreamExecution.scala:137)
    at org.apache.spark.sql.execution.streaming.MicroBatchExecution.<init>(MicroBatchExecution.scala:50)
    at org.apache.spark.sql.streaming.StreamingQueryManager.createquery(StreamingQueryManager.scala:317)
    at org.apache.spark.sql.streaming.StreamingQueryManager.startQuery(StreamingQueryManager.scala:359)
    at org.apache.spark.sql.streaming.DataStreamWriter.startQuery(DataStreamWriter.scala:466)
    at org.apache.spark.sql.streaming.DataStreamWriter.startInternal(DataStreamWriter.scala:456)
    at org.apache.spark.sql.streaming.DataStreamWriter.start(DataStreamWriter.scala:301)
    at meetup.SparkStreamsApp$.delayedEndpoint$meetup$SparkStreamsApp$1(SparkStreamsApp.scala:25)
    at meetup.SparkStreamsApp$delayedInit$body.apply(SparkStreamsApp.scala:7)

我很确定这与访问和创建我一直在使用的存储桶中的子目录的服务帐户有关,同时使用 spark-submit 环境变量和 {{1} 在本地 GOOGLE_APPLICATION_CREDENTIALS Spark 应用程序}} 配置属性

我正在按如下方式部署 Spark 应用程序:

spark.hadoop.google.cloud.auth.service.account.enable=true

如何以适当的 Kubernetes / GKE 方式修复它?

解决方法

根据您的配置,我建议您添加以下属性 fs.gs.project.id,如所示 here。因为它显示为 Required. Google Cloud Project ID with access to configured GCS buckets

另外,我同意@blackbishop关于秘密管理的声明。

,

GKE 文档中推荐的方法是 Import credentials as a Secret :

kubectl create secret generic spark-streaming-sa --from-file=/path/spark-streaming-serviceaccount-key.json

并在您提交作业时添加以下配置:

--conf spark.kubernetes.driver.secrets.spark-streaming-sa=<mount path>
--conf spark.kubernetes.executor.secrets.spark-streaming-sa=<mount path>
--conf spark.kubernetes.driverEnv.GOOGLE_APPLICATION_CREDENTIALS=<mount path>/spark-streaming-sa.json
--conf spark.executorEnv.GOOGLE_APPLICATION_CREDENTIALS=<mount path>/spark-streaming-sa.json
--conf spark.hadoop.google.cloud.auth.service.account.json.keyfile=<mount path>/spark-streaming-sa.json

您可以参考 Github GoogleCloudPlatform/spark-on-k8s-gcp-examples 上提供的示例。

这也在 spark 文档的 Secret Management 部分进行了描述Running Spark on Kubernetes

Kubernetes Secrets 可用于为 Spark 提供凭据 访问安全服务的应用程序。挂载用户指定的 秘密进入驱动容器,用户可以使用配置 表单的属性 spark.kubernetes.driver.secrets.[SecretName]=<mount path>。相似地, 表单的配置属性 spark.kubernetes.executor.secrets.[SecretName]=<mount path> 可以是 用于将用户指定的秘密挂载到执行程序容器中。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。