问卷链接(https://www.wjx.cn/jq/9714648...)
客座文章作者:万事达卡首席软件开发工程师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可以在这里找到。
Values & Helm 模板
我们更新values.yaml,然后运行helm template生成我们将部署到Kubernetes集群的清单。我们发现,对将要创建的内容具有可见性和对部署的控制是值得额外步骤的;模板存储在git中,我们的CD工具负责部署。
默认的chart values将允许你快速启动和运行。根据你的需要,以下是你可能需要做的一些修改:
- 启用webhook:默认情况下,不启用Mutating Admission Webhook。启用允许自定义SparkApplication驱动程序和执行程序pod,包括挂载卷、ConfigMaps、亲和性/非亲和性等等。
- 定义ingressUrlFormat:Spark UI可选的ingress。
请参阅快速入门指南和默认values.yaml获取更多详细信息和选项。
需求
要运行使用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。在执行任何安装任务之前,用户被设置为root,然后重置为${spark_uid}。
通过检查基本镜像,可以看到jar位于/opt/spark/jars或$SPARK_HOME/jars中。最后,更新jar的权限,以便能够使用它们。
上传到S3的文档提供了使用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中要求的最小配置如下:
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的选项,以及用于挂载秘密或指定环境变量的完整示例。
接下来,因为我们使用环境变量来验证S3,我们在sparkConf中设置以下选项:
sparkConf:
spark.hadoop.fs.s3a.aws.credentials.provider: com.amazonaws.auth.EnvironmentVariableCredentialsProvider
这是不需要的,如果没有提供,将尝试按照以下顺序来尝试凭据提供程序类:
- org.apache.hadoop.fs.s3a.SimpleAWSCredentialsProvider
- com.amazonaws.auth.EnvironmentVariableCredentialsProvider
- com.amazonaws.auth.InstanceProfileCredentialsProvider
4. S3样式
在SparkApplication的sparkConf中有一些其他的选项需要记住,这些选项是基于你特定的S3的:
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。
CNCF (Cloud Native Computing Foundation)成立于2015年12月,隶属于Linux Foundation,是非营利性组织。
CNCF(云原生计算基金会)致力于培育和维护一个厂商中立的开源生态系统,来推广云原生技术。我们通过将最前沿的模式民主化,让这些创新为大众所用。扫描二维码关注CNCF微信公众号。