在EKS上使用AWS Spot Instances的Apache Spark工作负载的有效成本节约
Apache Spark是一个数据处理框架,可以在巨大的数据集上执行快速处理任务,并且可以在多个节点上分配数据处理任务。随着应用程序的快速容器化,企业也开始在Kubernetes等容器化平台上运行Spark,并且也在生产中使用。理想情况下,在Kubernetes上运行spark有两种方式。
a) Spark提交。这是一个用于提交spark程序并启动Kubernetes集群应用的单一脚本。
例子。
b) Spark操作员。Spark操作符允许以声明的方式定义Spark应用,并支持用SparkApplication进行一次性的Spark应用和用ScheduledSparkApplication进行cron-scheduled应用。
例子。
一旦你相信了上述任何一种模式,你就决定在EKS上运行你的Spark工作负载。但是,你是否以正确的方式运行它呢?让我在这里给你举个例子。让我们假设你的应用程序Kubernetes pods需要的实例类型是t2.micro,但你的spark工作负载可能需要工作节点的类型是t2.large。你可以创建不同的自动缩放组,并使用nodeSeclector / nodeAffinity使这些pod调度在正确类型的节点上。这种分割节点的方式有50%的效果。我们如何实现其余的50%呢?这可以通过使用AWS现货实例来实现。是的,由于火花的工作负载不是24小时不间断运行的,我们可以用现货实例配置一个自动扩展组,并将最小计数设为0。现货实例比按需实例便宜90%以上。在本文的范围内,我们将了解如何建立一个带有现货实例节点组的EKS集群来运行Spark工作负载。
图片来源。谷歌图片
整个故事的内容是什么?(TLDR)
- 设置一个有两个不同节点组的EKS集群(On-Demand和Spot Instance节点组)。
- 在Spot Instances上执行spark工作负载(使用spark-submit和Spark Operator)。
本文未涉及的内容
- 如何编写spark-submit文件/Spark Operator文件。
- 如何建立一个基于生产的EKS集群。
先决条件
- AWS账户。
- 安装了Helm, eksctl, spark-submit二进制文件。
故事资源
- GitHub链接:https://github.com/pavan-kumar-99/medium-manifests
- GitHub分支:aws-spot-spark
使用eksctl创建一个AWS EKS集群
那么,市场上有很多关于如何创建EKS集群的方法。其中,最常用的是Terraform和eksctl。在本文的范围内,我们将使用eksctl。 eksctl是一个简单的CLI工具,用于创建和管理EKS上的集群--亚马逊为EC2管理的Kubernetes服务。它是用Go编写的,使用CloudFormation,由Weaveworks创建。集群配置可以在文件中定制(YAML格式)。eksctl可以解析输入文件并从中创建集群。下面是我们用来创建EKS集群的eksctl配置文件。
现在让我们来了解一下这个配置文件
a) metadata.name:要创建的EKS集群的名称。
b) managedNodeGroups.name:被管理的Kubernetes工作节点组的名称。
c) managedNodeGroups.instanceType。节点组中要使用的实例类型。
d) managedNodeGroups.min/max/desired。自动伸缩节点组的最小、最大、期望的数量。
e)managedNodeGroups.spot:布尔值,指定节点组是否应该有现货实例。
因此,上面的配置创建了一个有2个管理节点组的EKS集群。
- eks-medium-on-demand-node-group。这个节点组至少有1个t2.micro实例,可自动扩展到8个。这里所有的实例都是按需分配的实例。
- eks-medium-spot-节点组。 这个节点组被创建时有0个实例。是的,你已经看到了这一点。这个节点组将有0个现货实例,最多可扩展到5个实例。
现在让我们来创建EKS集群。
$
$
$
创建了有2个托管节点组的EKS集群
创建有2个管理节点组的EKS集群
需要注意的一点是,eksctl不会用配置文件中指定的标签来标记ASG。 ASG应该被手动标记,以便集群自动缩放器能够扩大有0个节点的ASG。( 为了让nodeAffinity / nodeSelector工作) 。
现在让我们来安装Kubernetes集群自动缩放器。Kubernetes Cluster Autoscaler 根据你的工作负载的需求,自动调整特定集群中工作节点的数量。你不需要手动添加或删除节点或过度配置你的集群。相反,你可以为你的集群指定一个最小和最大的规模,而缩放是自动的,由集群自动缩放器自己完成。我已经写了一篇关于Kubernetes集群自动调节器的详细文章。一旦我发表,我将在这里分享链接。现在,让我们来安装集群自动oscaler的舵手图。
$ git clone
$ cd medium-manifests/
$ helm repo add autoscaler
$ helm upgrade -i medium-ca-aws autoscaler/cluster-autoscaler -f ca-values.yaml
集群自动oscaler日志
你现在应该看到,集群自动oscaler pods检测到了正确的自动缩放组。好了,现在让我们检查一下节点。
创建的单节点
用Spark Submit部署Spark App
我们现在创建了一个单一的节点,它是一个按需分配的节点。从节点的标签中也可以看出这一点。现在让我们使用spark-submit命令来提交一个spark作业。那么,这次的不同之处在于在spark-submit命令中加入了这个新的节点选择器参数。
$ --conf spark.kubernetes.
根据spark的文档, spark.kubernetes.node.selector.[labelKey],添加到驱动pod和执行器pod的节点选择器中,键为labelKey,值为配置的值。因此,最终的spark-submit作业将看起来像这样
在我们提交作业之前,应该为驱动pod创建Kubernetes服务账户,以创建执行者pod并访问其服务。
$ git clone
$ cd medium-manifests/
$ kubectl apply -f spark-rbac.yaml
$ ./spark-submit.sh
当我提交我的spark作业时,我应该看到现货实例ASG中的节点开始从0到2扩展。
节点扩展(现货实例
我所有的钱都因为现货实例而被节省了 :)
现货实例正在扩大规模
让我们也用Spark Operator尝试一下,看看这是否有效。
用Spark Operator部署Spark应用程序
Spark运营商允许以声明的方式定义Spark应用程序,并支持SparkApplication的一次性Spark应用程序和ScheduledSparkApplication的cron-scheduled应用程序。让我们首先部署spark操作符。
$ helm repo add spark-operator\ https://googlecloudplatform.github.io/spark-on-k8s-operator
$ helm install spark-operator spark-operator/spark-operator\
$ k get po -n spark-operator
NAME READY STATUS RESTARTS AGE
spark-operator-5fb7bcf764-qm8np 1/1 Running 0 21m
现在让我们来部署spark应用程序。火花应用程序看起来像这样。
在整个yaml文件中,需要强调的部分是nodeAffinity部分。这个亲和性确保了spark应用程序(驱动和执行都可以部署在现场实例上)。与spark-submit不同的是,驱动和执行者都有相同的nodeSelector(Spark submit目前不支持节点亲和性),在spark operator(SparkApplication)中,我们可以灵活地给驱动和执行者指定不同的亲和性。在某些情况下,我们可能希望在 "按需 "节点上运行驱动舱,在 "定点 "节点上运行执行舱。在这种情况下,spark operator允许我们为驱动程序和执行器分别创建亲和力。
$ git clone
$ cd medium-manifests/
$ kubectl apply -f spark-app.yaml
$ k get SparkApplication
NAME STATUS ATTEMPTS START FINISH AGE
pyspark-pi COMPLETED 1 2021-08-07T12:19:30Z 2021-08-07T12:21:49Z 16m
被触发的Spot Instances
有效处理Spot Instances的终止
**AWS节点终止处理程序。**这个项目确保Kubernetes控制平面对可能导致你的EC2实例不可用的事件做出适当的响应,例如EC2维护事件、EC2 Spot中断、ASG Scale-In、ASG AZ Rebalance,以及通过API或控制台的EC2实例终止。如果不处理,你的应用程序代码可能不会优雅地停止,需要更长的时间来恢复完全的可用性,或者意外地将工作安排到正在下降的节点。
项目链接:https://github.com/aws/aws-node-termination-handler
清理工作
$ eksctl delete cluster -f
我希望这篇文章涵盖了如何使用AWS Spot Instances以最小的成本在Kubernetes集群上有效地部署火花应用程序。请随时在评论区评论下你的想法和你对AWS现货实例的最佳经验。
再次感谢您阅读我的文章。希望你喜欢它。以下是我的一些其他文章,你可能感兴趣。
直到下一次...........
在EKS上使用AWS Spot Instances运行Apache Spark最初发表于Nerd For Techon Medium,在那里人们通过强调和回应这个故事继续对话。