迁移到Spark Operator和S3的4个集成步骤

2021-01-27 10:45:35 浏览数 (1)


客座文章作者:万事达卡首席软件开发工程师 Allison Richardet

在万事达,内部云团队维护我们的 Kubernetes 平台。我们的工作包括维护 Kubernetes 集群,这是我们所依赖的核心部署,并为租户提供了日志、监控等服务,并为租户提供了良好的体验。

我们的租户之一,数据仓库团队,曾经在 YARN 和 HDFS 上使用过原生 Apache Spark。他们找了我们的团队,希望将他们的大数据工作转移到 Kubernetes;他们想要实现云原生化,而我们也有机会在 Kubernetes 上与 Apache Spark 合作。

所以,我们的旅程从 Spark Operator 开始。向 Kubernetes 和 Operators 的迁移将为我们的内部客户数据仓库团队打开云原生的可能性。我们有机会帮助他们利用可伸缩性和成本改进的优势,而切换到 S3 将进一步实现这些目标。

背景

操作器(operator)是什么,为什么我们,或者你,对此感兴趣?首先,操作器使用自定义资源扩展了 Kubernetes API。操作器还定义了一个自定义控制器来监视其资源类型。将自定义资源与自定义控制器结合在一起会产生一个声明性 API,在这个 API 中,操作器会协调集群声明状态与实际状态之间的差异。换句话说,操作器处理与其资源相关的自动化。

有了这些好处,我们的团队很高兴能够利用 Kubernetes 的 Spark 操作器来支持我们的租户。通常,原生 Apache Spark 使用 HDFS。然而,迁移到云端并在 Kuberentes 上运行 Spark 操作器,S3 是 HDFS 的一个很好的替代方案,因为它具有成本优势,并且能够根据需要进行扩展。有趣的是,S3 在默认情况下不能与 Spark 操作器一起使用。我们参考了 Spark 操作器以及 Hadoop-AWS 集成文档。此外,我们将分享以下 4 个步骤的详细信息:镜像更新、SparkApplication 配置、S3 凭据和 S3 样式。遵循我们的步骤,将 S3 与你的 Spark 作业和 Kubernetes 的 Spark 操作器进行集成。

工作流程

与我们部署到 Kubernetes 集群的大多数应用程序一样,我们使用 Helm chart。Kubernetes 的 Apache Spark 操作器的 Helm chart 可以在这里[1]找到。

Values & Helm 模板

我们更新 values.yaml,然后运行 helm template 生成我们将部署到 Kubernetes 集群的清单。我们发现,对将要创建的内容具有可见性和对部署的控制是值得额外步骤的;模板存储在 git 中,我们的 CD 工具负责部署。

默认的 chart values 将允许你快速启动和运行。根据你的需要,以下是你可能需要做的一些修改:

  • 启用 webhook:默认情况下,不启用 Mutating Admission Webhook。启用允许自定义 SparkApplication 驱动程序和执行程序 pod,包括挂载卷、ConfigMaps、亲和性/非亲和性等等。
  • 定义 ingressUrlFormat:Spark UI 可选的 ingress。

请参阅快速入门指南[2]和默认values.yaml[3]获取更多详细信息和选项。

需求

要运行使用 S3 的 SparkApplication,需要 SparkApplication 的附加配置,包括一个自定义 docker 镜像。Hadoop S3AConnector 是一种可以对 S3 进行读写的工具。

1. 镜像更新

SparkApplication 使用的 docker 镜像需要添加两个 jar(hadoop-aws 和 aws-java-sdk 或 aws-java-sdk-bundle),版本根据 Spark 版本和 Hadoop 配置文件。

在这一步中有几件事情要记住。

  • 用户和权限
  • 额外的 Jar

如果使用 spark 镜像作为起点,在添加 jar 时引用它们各自的 dockerfile 以正确对齐用户和位置。

让我们来看看 python Dockerfile[4]。在执行任何安装任务之前,用户被设置为 root,然后重置为${spark_uid}。

通过检查基本镜像[5],可以看到 jar 位于/opt/spark/jars 或$SPARK_HOME/jars 中。最后,更新 jar 的权限,以便能够使用它们。

上传到 S3[6]的文档提供了使用 jar 文件的信息;然而,我们需要一个包含 fs.s3a.path.style.access 配置的新 Hadoop 版本——我们将在后面一节中讨论这个问题。在编写本文时,我们使用 spark 操作器版本 v1beta2-1.2.0-3.0.0,其中包含基本 spark 版本 3.0.0。使用 gcr.io/spark-operator/spark-py:v3.0.0-hadoop3 镜像作为起点,我们添加了以下 jar:hadoop-aws-3.1.0.jar 和 aws-java-sdk-bundle-1.11.271.jar。它需要一些实验来确定最终能工作的正确镜像组合。

2. SparkApplication 配置

SparkApplication 需要额外的配置才能与 S3 通信。spec.sparkConf 中要求的最小配置如下:

代码语言:javascript复制
sparkConf:
    spark.hadoop.fs.s3a。端点:<端点>
    spark.hadoop.fs.s3a。impl: org.apache.hadoop.fs.s3a.S3AFileSystem

还必须提供访问 S3 的凭据。有类似于上面的配置选项;但是,这是非常丧气的,因为它们是字符串值,因此与安全最佳实践相违背。

3. S3 凭证

我们不在 SparkApplication 的 sparkConf 中提供 s3 凭据,而是创建一个 Kubernetes 秘密,并为驱动程序和执行程序定义环境变量。Spark 操作器文档提供了几种使用 secret 的选项,以及用于挂载秘密[7]指定环境变量[8]的完整示例。

接下来,因为我们使用环境变量来验证 S3,我们在 sparkConf 中设置以下选项:

代码语言:javascript复制
sparkConf:
     spark.hadoop.fs.s3a.aws.credentials.provider: com.amazonaws.auth.EnvironmentVariableCredentialsProvider

这是不需要的,如果没有提供,将尝试按照以下顺序来尝试凭据提供程序类:

  1. org.apache.hadoop.fs.s3a.SimpleAWSCredentialsProvider
  2. com.amazonaws.auth.EnvironmentVariableCredentialsProvider
  3. com.amazonaws.auth.InstanceProfileCredentialsProvider

4. S3 样式

在 SparkApplication 的 sparkConf 中有一些其他的选项需要记住,这些选项是基于你特定的 S3 的:

代码语言:javascript复制
sparkConf:
    extraJavaOptions: -Dcom.amazonaws.services.s3.enableV4=true
    spark.hadoop.fs.s3a.path.style.access: “true”
    spark.hadoop.fs.s3a.connection.ssl.enabled: “true”

路径样式访问——通过启用路径样式访问,将禁用虚拟主机(默认启用)。启用路径样式访问可以消除为默认虚拟主机设置 DNS 的需求。

启用 SSL——如果你正在使用 TLS/SSL,请确保在 SparkApplication 的 sparkConf 中启用这个选项。

额外的 Java 选项——根据你的需要而变化。

使用 S3

现在你已经完成了使用 S3 的所有设置,现在有两种选择:利用 S3 处理依赖项或上传到 S3。

S3 处理依赖项

mainApplicationFile 和 spark 作业使用的附加依赖项(包括文件或 jar)也可以从 S3 中存储和获取。它们可以在 spec.deps 字段中的 SparkApplication 中与其他依赖项一起定义。spark-submit 会分别使用 spec.deps.jar 和 spec.deps.files 中指定的 jar 或文件。s3 中访问依赖的格式为 s3a://bucket/path/to/file。

上传到 S3

上传到 S3 时,文件位置的格式为 s3a://bucket/path/to/destination。bucket 必须存在,否则上传失败。如果 destination 文件已经存在,上载将失败。

总结

我们介绍了启动并运行 Spark 操作器和 S3 所需的 4 个步骤:镜像更新、SparkApplication 的 sparkConf 中所需的选项、S3 凭据以及基于特定 S3 的其他选项。最后,我们给出了一些关于如何利用 S3 来实现依赖关系和上传到 S3 的建议。

最后,我们帮助我们的内部客户,数据仓库团队,将他们的大数据工作负载从原生 Apache Spark 转移到 Kubernetes。Kubernetes 上的 Spark 操作器在云计算方面有很大的优势,我们想与更大的社区分享我们的经验。我们希望这个关于 Spark 操作器和 S3 集成的演练将帮助你和/或你的团队启动并运行 Spark 操作器和 S3。

参考资料

[1]

这里: https://github.com/GoogleCloudPlatform/spark-on-k8s-operator/tree/master/charts/spark-operator-chart

[2]

快速入门指南: https://github.com/GoogleCloudPlatform/spark-on-k8s-operator/blob/master/docs/quick-start-guide.md

[3]

values.yaml: https://github.com/GoogleCloudPlatform/spark-on-k8s-operator/blob/master/charts/spark-operator-chart/values.yaml

[4]

Dockerfile: https://github.com/apache/spark/blob/master/resource-managers/kubernetes/docker/src/main/dockerfiles/spark/bindings/python/Dockerfile

[5]

基本镜像: https://github.com/apache/spark/blob/master/resource-managers/kubernetes/docker/src/main/dockerfiles/spark/Dockerfile

[6]

上传到 S3: https://github.com/GoogleCloudPlatform/spark-on-k8s-operator/blob/master/sparkctl/README.md#uploading-to-s3

[7]

挂载秘密: https://github.com/GoogleCloudPlatform/spark-on-k8s-operator/blob/master/docs/user-guide.md#mounting-secrets

[8]

指定环境变量: https://github.com/GoogleCloudPlatform/spark-on-k8s-operator/blob/master/docs/user-guide.md#specifying-environment-variables

0 人点赞