文章目录

  • 0. 前置条件
  • 1. 安装ekscli
  • 2. 安装kubectl
  • 3. 创建EKS集群
  • 4. 查看EKS集群状态
  • 5. 创建Namespace
  • 6. 授权访问Namespace
  • 7. 创建Job Execution Role
  • 8. 创建Role的Trust Relationship
  • 9. 在EKS上创建EMR虚拟集群
  • 10. 向EMR on EKS提交作业
  • 11. 删除与清理
  • 12. 常见错误

EMR on EKS的创建工作完全是命令行驱动的,目前尚无对应的UI界面来完成相关操作。本文将通过命令行演示如何创建并运行一个EMR on EKS集群。创建EMR on EKS的过程可以分为两个阶段:第一阶段是先创建出一个EKS集群,第二阶段是在这个EKS集群之上创建EMR的虚拟集群,以下是具体操作步骤。

注:在操作过程中,我们将会陆续得到一些值,例如EKS集群的名称,虚拟集群的ID,这些变量在后续的操作中会再次使用,为了便于提升文中脚本的可复用性,我们会单独将这些值抽取出来,赋给一个变量,同时用export导出,便于后续的引用。以下是操作过程中将会生成并被引用到的一些变量,以及本例我们将采用的值:

变量名称 本例取值 描述
REGION us-east-1 当前所处的AWS REGION
ZONES us-east-1a,us-east-1b,us-east-1c 分配给将要创建的EKS集群的可用区
EKS_CLUSTER_NAME it-infrastructure 将要创建的EKS集群的名称
DATALAKE_NAMESPACE datalake 将要在EKS上创建的面向数据系统的Kubenetes命名空间,将要创建的EMR on EKS虚拟集群会被置于该空间下
VIRTUAL_CLUSTER_NAME emr-cluster-1 将要创建的EMR on EKS虚拟集群的名字
SSH_PUBLIC_KEY <从EC2->Kye Pairs处查找> 将要创建的EKS集群需要指定公钥
EXECUTION_ROLE_ARN <从IAM的Admin Role处查找> 用于运行EMR on EKS的IAM Role
VIRTUAL_CLUSTER_ID <过程中产生> 将要创建的EMR on EKS虚拟集群的ID

以下是为上述全局变量赋值的命令(VIRTUAL_CLUSTER_ID将在后续操作中产生,暂不赋值):

export REGION="us-east-1"
export ZONES="us-east-1a,us-east-1b,us-east-1c"
export EKS_CLUSTER_NAME="it-infrastructure"
export DATALAKE_NAMESPACE="datalake"
export VIRTUAL_CLUSTER_NAME="emr-cluster-1"
export SSH_PUBLIC_KEY="<your-pub-key-name>"
export EXECUTION_ROLE_ARN="<your-admin-role-arn>"

0. 前置条件

  • 确保有你有一台Linux主机,并已安装awscli命令行
  • 确保配置给awscli的access_key属于一个Admin账号

1. 安装ekscli

ekscli是用于操作eks的命令行工具,我们需要使用到该工具,须先行安装,安装命令如下:

curl --silent --location "https://github.com/weaveworks/eksctl/releases/latest/download/eksctl_$(uname -s)_amd64.tar.gz" | tar xz -C /tmp
sudo mv /tmp/eksctl /usr/local/bin

2. 安装kubectl

kubectl是用于管理kubenetes集群的命令行工具,我们需要使用到该工具,须先行安装,安装命令如下:

curl -o kubectl https://amazon-eks.s3.us-west-2.amazonaws.com/1.20.4/2021-04-12/bin/linux/amd64/kubectl
chmod +x ./kubectl
mkdir -p $HOME/bin && cp ./kubectl $HOME/bin/kubectl && export PATH=$PATH:$HOME/bin
echo 'export PATH=$PATH:$HOME/bin' >> ~/.bashrc

3. 创建EKS集群

接下来,我们要在美东1创建名为ABC_IT_INFRASTRUCTURE的EKS集群,命令如下:

eksctl create cluster \--region $REGION \--name $EKS_CLUSTER_NAME \--zones $ZONES \--node-type m5.xlarge \--nodes 5 \--with-oidc \--ssh-access \--ssh-public-key $SSH_PUBLIC_KEY \--managed

上述命令行需要注意如下几点:

  • $SSH_PUBLIC_KEY为你在AWS上的公钥key的ID,这个字符串可在EC2控制台->Key Pairs处查找,name列即是;
  • --zones并不是必选项,如不指定,会随机选择AZ,但是有时随机选择的AZ在创建时并没有足够的资源支撑请求创建的EKS集群,这时就需要显式地指定zone来避开不可用的zone;
  • --node-type--nodes也不是必选项,如不指定,集群默认部署在2个m5.large节点上,对于EMR来说,这个集群的配置太低了,所以必须显式配置这两项,赋予集群更大的资源;

上述命令行需要执行较长时间(约20分钟左右),当最后出现:

EKS cluster "ABC_IT_INFRASTRUCTURE" in "us-east-1" region is ready

表明EKS集群已经建好。需要注意的是,该命令在执行过程中会通过Cloud Formation创建大量的基础设施,包括IAM Role,VPC,EC2等等,中途发生错误的可能性较大,且很多操作是不能自动回滚的,所以需要打开Cloud Formation的控制台并持续关注,如发现未清理的Stack,须手动删除Stack后再重新执行上述命令。

eksctl create cluster还有很多可配置的选项,可以通过如下命令查看详细说明:

eksctl create cluster -h

4. 查看EKS集群状态

EKS集群创建完成后,为确保集群是否健康,可通过命令行查看一下集群状况(该步骤非必须,可跳过)。

  • 查看集群各物理节点状况
kubectl get nodes -o wide
  • 查看集群POD的状况
kubectl get pods --all-namespaces -o wide

5. 创建Namespace

为便于对资源进行管理,我们可以在Kubenetes集群上为数据相关的系统创建单独的namespace,取名ABC_DATALAKE,后续创建的EMR虚拟集群将被置于该namespace下:

kubectl create namespace $DATALAKE_NAMESPACE

6. 授权访问Namespace

默认情况下,EMR on EKS是无权直接访问和使用EKS上的namespace的,需要我们创建一个Kubernetes role,然后将该Role绑定到一个Kubernetes user上,同时将一个服务角色AWSServiceRoleForAmazonEMRContainers映射到这个user上,这样才能桥接Kubenetes端和EMR on EKS服务端之间的权限认证,幸运的是我们不需要手动逐一完成这些操作,通过一条eksctl命令可以直接实现:

eksctl create iamidentitymapping \--region $REGION \--cluster $EKS_CLUSTER_NAME \--namespace $DATALAKE_NAMESPACE \--service-name "emr-containers"

控制台的输出也会印证上面的论述:

2021-06-02 12:39:49 [ℹ]  created "datalake:Role.rbac.authorization.k8s.io/emr-containers"
2021-06-02 12:39:49 [ℹ]  created "datalake:RoleBinding.rbac.authorization.k8s.io/emr-containers"
2021-06-02 12:39:49 [ℹ]  adding identity "arn:aws:iam::1234567898765:role/AWSServiceRoleForAmazonEMRContainers" to auth ConfigMap

7. 创建Job Execution Role

运行EMR on EKS需要一个IAM Role,在这个Role中要配置授权EMR on EKS可以使用的资源有哪些,例如s3上某些桶,cloudwatch等服务,这些被称之为Role Policies,官方文档给出过一份Role Policies的参考配置,可参见:https://docs.aws.amazon.com/emr/latest/EMR-on-EKS-DevelopmentGuide/creating-job-execution-role.html。

为方便起见,本文将直接使用Admin角色作为job execution role

8. 创建Role的Trust Relationship

如果通过第7步创建了一个role,还需要对这个role进行编辑,添加这个role和EMR服务账号(EMR managed service account)之间的互信。这里所谓的EMR服务账号(EMR managed service account)是在job提交时自动创建的,所以在配置中在EMR服务账号部分会使用统配符。

不过幸运的是,我们不需要手动编辑Role的Trust Relationships部分,我们可以如下命令行自动添加这个Trust Relationship:

aws emr-containers update-role-trust-policy \--cluster-name $EKS_CLUSTER_NAME \--namespace $DATALAKE_NAMESPACE \--role-name <Admin or the-job-excution-role-name-you-created>

其中,你需要将<Admin or the-job-excution-role-name-you-created>替换为Admin或者是在第7步中创建的role的名称。当创建成功之后,可以在Role的Trust Relationships页面看到生成的类似下面的相关配置:

{"Effect": "Allow","Principal": {"Federated": "arn:aws:iam::1234567898765:oidc-provider/oidc.eks.us-east-1.amazonaws.com/id/1C2DF227CD8E011A693BCF03D7EBD581"},"Action": "sts:AssumeRoleWithWebIdentity","Condition": {"StringLike": {"oidc.eks.us-east-1.amazonaws.com/id/1C2DF227CD8E011A693BCF03D7EBD581:sub": "system:serviceaccount:kube-system:emr-containers-sa-*-*-1234567898765-3l0vgne6"}}
}

即使我们在第7步选择使用Admin角色作为job execution role,该步操作依然需要执行,–role-name取值Admin, 否则在作业执行过程中无权完成创建Log Group以及在s3上存储日志等操作

9. 在EKS上创建EMR虚拟集群

接下来我们就将创建EMR集群了,其实更准确的叫法应该是“注册”,因为这一步执行完成后并不会在EKS上生成一个EMR集群,这里创建的是一个虚拟的集群,集群要在第一次提交作业时才会创建。创建集群的命令如下:

# create virtual cluster description file
tee $VIRTUAL_CLUSTER_NAME.json <<EOF
{"name": "$VIRTUAL_CLUSTER_NAME","containerProvider": {"type": "EKS","id": "$EKS_CLUSTER_NAME","info": {"eksInfo": {"namespace": "$DATALAKE_NAMESPACE"}}}
}
EOF# create virtual cluster
aws emr-containers create-virtual-cluster --cli-input-json file://./$VIRTUAL_CLUSTER_NAME.json

上述命令先创建一个集群描述文件$VIRTUAL_CLUSTER_NAME.json, 这个文件描述了EMR集群的名称以及要建在哪个EKS集群的哪个Namespace上,然后通过aws emr-containers create-virtual-cluster创建出这个文件描述的虚拟集群。

上述命令如果执行成功,会在控制台输出一份描述集群的json数据,其中的id字段较为重要,后续提交作业时都会使用到这个id,如果没有保存下来,也可以通过如下命令随时查询:

aws emr-containers list-virtual-clusters

将获得的id付给全局变量VIRTUAL_CLUSTER_ID,后续操作将会多次引用到该ID:

export VIRTUAL_CLUSTER_ID='<cluster-id>'

10. 向EMR on EKS提交作业

虚拟集群建好之后,就可以提交大数据作业了,EMR on EKS是基于容器的,不同于EMR通过shell登录进行操作(可以但不方便),常规的使用方式是将其视为一个计算资源的黑盒,向其提交作业即可。以下是一条向EMR on EKS提交作业的示例命令,它执行的是spark自带的example程序pi.py

aws emr-containers start-job-run \
--virtual-cluster-id $VIRTUAL_CLUSTER_ID \
--name sample-job-name \
--execution-role-arn $EXECUTION_ROLE_ARN \
--release-label emr-6.2.0-latest \
--job-driver '{"sparkSubmitJobDriver": {"entryPoint": "local:///usr/lib/spark/examples/src/main/python/pi.py","sparkSubmitParameters": "--conf spark.executor.instances=2 --conf spark.executor.memory=2G --conf spark.executor.cores=2 --conf spark.driver.cores=1"}}' \
--configuration-overrides '{"monitoringConfiguration": {"cloudWatchMonitoringConfiguration": {"logGroupName": "/emr-on-eks/$VIRTUAL_CLUSTER_NAME", "logStreamNamePrefix": "pi"}}}'

start-job-run这条命令最需要关注的是--job-driver这个参数,所有关于作业本身的相关信息都在这个参数里了。基于文档可知,目前的EMR on EKS仅支持sparkSubmitJobDriver一种形式的作业提交,即只能是以spark-submit可接受的形式提交作业,也就是通过jar包+class或pyspark脚本的形式提交作业。jar包及其依赖jar文件可部署在s3上。

一种更加优雅的作业提交方式是提供一份job run的json描述文件,把所有集群、作业和作业配置相关的信息集中配置在这份json文件中,然后通过命令执行,如下所示:

# create job description file
tee start-job-run-request.json <<EOF
{"name": "sample-job-name", "virtualClusterId": "$VIRTUAL_CLUSTER_ID",  "executionRoleArn": "$EXECUTION_ROLE_ARN", "releaseLabel": "emr-6.2.0-latest", "jobDriver": {"sparkSubmitJobDriver": {"entryPoint": "local:///usr/lib/spark/examples/src/main/python/pi.py","sparkSubmitParameters": "--conf spark.executor.instances=2 --conf spark.executor.memory=2G --conf spark.executor.cores=2 --conf spark.driver.cores=1"}}, "configurationOverrides": {"applicationConfiguration": [{"classification": "spark-defaults", "properties": {"spark.driver.memory":"2G"}}], "monitoringConfiguration": {"persistentAppUI": "ENABLED", "cloudWatchMonitoringConfiguration": {"logGroupName": "/emr-on-eks/$VIRTUAL_CLUSTER_NAME", "logStreamNamePrefix": "pi"}, "s3MonitoringConfiguration": {"logUri": "s3://glc-emr-on-eks-logs/"}}}
}
EOF
# start job
aws emr-containers start-job-run --cli-input-json file://./start-job-run-request.json

关于json文件的编写,可以参考:https://docs.aws.amazon.com/emr/latest/EMR-on-EKS-DevelopmentGuide/emr-eks-jobs-CLI.html#emr-eks-jobs-submit

最后是关于EMR集群的配置,与纯EMR集群类似,集群配置也是通过json文件提交的,写到applicationConfiguration里面,例如上述配置中的"classification": "spark-defaults"部分。由于EMR on EKS目前仅支持Spark,所以也只有如下几类classification可配置

Classifications Descriptions
core-site Change values in Hadoop’s core-site.xml file.
emrfs-site Change EMRFS settings.
spark-metrics Change values in Spark’s metrics.properties file.
spark-defaults Change values in Spark’s spark-defaults.conf file.
spark-env Change values in the Spark environment.
spark-hive-site Change values in Spark’s hive-site.xml file.
spark-log4j Change values in Spark’s log4j.properties file.

11. 删除与清理

删除与清理集群的顺序应与创建过程相反,先删除ERM虚拟集群,然后再删除EKS集群:

# 1. list all jobs
aws emr-containers list-job-runs --virtual-cluster-id $VIRTUAL_CLUSTER_ID# 2. cancel running jobs
aws emr-containers cancel-job-run --id <job-run-id> --virtual-cluster-id $VIRTUAL_CLUSTER_ID# 3. delete virtual cluster
aws emr-containers delete-virtual-cluster --id $VIRTUAL_CLUSTER_ID# 4. delete eks cluster
eksctl delete cluster --region $REGION --name $EKS_CLUSTER_NAME

注意:第4步在删除EKS集群时,须找到对应Cloud Formation模板里的一项资源NodeInstanceRole,手动dettach 该Role上的所有policies,命令才能执行成功。

12. 常见错误

  • 通过eksctl create cluster创建的eks集群默认是两个m5.large节点,这个配置很难支撑一个EMR集群,所以务必要指定一下节点数量和节点类型:

  • 如果在第3步创建EKS集群遇到类似如下的错误:

AWS::EKS::Cluster/ControlPlane: CREATE_FAILED – "Cannot create cluster 'my-bigdata-infra-cluster' because us-east-1e, the targeted availability zone, does not currently have sufficient capacity to support the cluster. Retry and choose from these availability zones: us-east-1a, us-east-1b, us-east-1c, us-east-1d, us-east-1f (Service: AmazonEKS; Status Code: 400; Error Code: UnsupportedAvailabilityZoneException; Request ID: 61028748-0cc1-4100-9152-aab79a475fe6; Proxy: null)"

说明自动分配或指定的某一个AZ目前不可用,可在--zones参数列表中取其他AZ替换。

关于作者:架构师,15年IT系统开发和架构经验,对大数据、企业级应用架构、SaaS、分布式存储和领域驱动设计有丰富的实践经验,热衷函数式编程。对Hadoop/Spark 生态系统有深入和广泛的了解,参与过Hadoop商业发行版的开发,曾带领团队建设过数个完备的企业数据平台,个人技术博客:https://laurence.blog.csdn.net/ 作者著有《大数据平台架构与原型实现:数据中台建设实战》一书,该书已在京东和当当上线。

创建并运行 EMR on EKS 集群相关推荐

  1. key store是否创建_EKS-实践一 创建EKS集群

    EKS简介 Amazon Elastic Kubernetes Service (Amazon EKS) 是一项托管服务,可让您在 AWS 上轻松运行 Kubernetes,而无需支持或维护您自己的 ...

  2. 使用AWS 管理控制台和 AWS CLI创建EKS集群

    Amazon Elastic Kubernetes Service (Amazon EKS) 是一种托管服务,用户可以使用它在 AWS 上运行 Kubernetes,而无需安装.操作和维护Kubern ...

  3. aws上创建eks集群

    在aws上创建eks集群前,需要先创建vpc和subnet以及role,因为在创建集群时会用到. 1.创建VPC 对于创建vpc,进入create vpc界面创建即可,这里用的都是默认值. 2.创建s ...

  4. 部署一个 Containerd 容器运行时的 Kubernetes 集群

    前面我们介绍了 containerd 的基本使用,也了解了如何将现有 docker 容器运行时的 Kubernetes 集群切换成 containerd,接下来我们使用 kubeadm 从头搭建一个使 ...

  5. MySQL 集群 3副本,Kubernetes经典实践——运行MySQL多副本集群

    JFrog 在线课堂 Kubernetes经典实践--运行MySQL多副本集群 课程背景 Kubernetes以其先进的理念.活跃的社区,已成为当前容器集群化编排.部署和运行的事实标准.越来越多的企业 ...

  6. aws的EMR搭建Hadoop集群

    还是先极简介绍一下EMR是什么,Amazon EMR 基于 Hadoop 的开源框架将您的数据分布在可重新调整大小的 Amazon EC2 实例集群中并进行处理.Amazon EMR 可用于各种应用程 ...

  7. linux集群流程运行,linux 怎么配置集群

    linux 怎么配置集群?设置虚拟集群是一个比较复杂.耗时的过程,首先需要有两个Red Hat Enterprise Linux或CentOS 7节点,并配置正确的转发及反向 域名系统,由于Red H ...

  8. (三)在Azure上创建您的第一个Kubernetes集群

    目录 Azure Kubernetes服务 Azure资源管理器 先决条件和清理 AKS群集模板 Azure DevOps管道 下一步 在本系列的前面部分,我们使用Azure Functions创建了 ...

  9. 在一台物理机上创建3个虚拟机搭建k8s集群(一)

    2019年10月7日,参考链接: https://blog.csdn.net/qq_38252499/article/details/99214276 https://blog.csdn.net/cn ...

最新文章

  1. poj1486(二分图必须边)
  2. 【转】Asp.net页面的生命周期
  3. I/O端口地址分配表(转)
  4. Oracle一个中文汉字占用几个字节
  5. mongodb 部署
  6. 单列集合Set的实现类HashSet
  7. java连接oracle数据库 -- jdbc连接
  8. docker 安装 mysql 并映射数据库存放路径及配置文件
  9. jmeter接口测试----8用户定义的变量
  10. 47 Majority Element II
  11. 超级素数幂--全国模拟(一)
  12. vbs中使用select case条件语句,case中匹配项多于一个时,提示:type mismathc/ 800A000D...
  13. 将本地无损音乐上传到Apple Music中使用。
  14. Python 3的反驳
  15. 看完东野小说 乱写写(含微量剧透)
  16. 小米连续点击Android,屏幕自动点击
  17. 第1章 机器学习基础
  18. bit,B,KB,MB,GB,TB,PB分别是什么单位,换算是什么
  19. torch-sparse安装教程
  20. 【已解决】致命错误:Python.h:没有那个文件或目录

热门文章

  1. 啊哈算法dfs-bfs
  2. 如何翻滚截屏_电脑上如何实现滚动截图?用这款工具即可轻松实现!
  3. Vue详解及综合案例
  4. 三链列 Swordfish 和 四链列 Jellyfish
  5. Linux系统(四)之docker
  6. 解决问题过程记录: QuickTime初始化失败
  7. N70/N72常见问题汇总
  8. 如何让电脑显示SVG图片的缩略图
  9. 关于jsp网页弹出窗口
  10. c#的Socket实现多人聊天室(附源码)