使用 Amazon EMR 和 S3 访问授权来扩展 Spark 对 Amazon S3 的访问 大

扩展 Amazon S3 的 Spark 访问权限与 Amazon EMR 结合使用

作者:Damon Cortesi
日期:2023年11月26日
类别:Amazon EMR, Amazon S3, 分析, 公告

关键要点

在本篇文章中,我们将探讨如何通过 Amazon EMR 集成 Amazon S3 访问权限授予来简化权限管理,增强 Apache Spark作业的安全性与可扩展性。我们会详细介绍设置流程以及如何利用 AWS CloudFormation模板创建资源,并展示不同的场景来使用这些集成。同时,我们将特别说明如何进行跨账户访问权限的配置。

Amazon EMR 现已支持集成 Amazon S3 访问授予,从而简化了 S3权限管理,并允许您在更大范围内执行细粒度访问控制。这项技术能够有效地提高数据安全性,用户可根据需要设置相关权限,尤其适合有多账户需求的企业。

接下来的内容将分为几个部分,包括基本的前提条件、创建资源的过程、示例场景等。

前提条件

在启动 AWS CloudFormation 堆栈之前,请确保您具备以下条件:

  • 一个可以访问 AWS 服务的 AWS 账户;
  • 最新版本的 AWS 命令行界面();
  • 一个具备访问密钥和机密密钥的 AWS 身份与访问管理()用户,以便配置 AWS CLI,并具有创建 IAM 角色、IAM 策略和 AWS CloudFormation 堆栈的权限;
  • 如果您希望测试跨账户功能,还需要一个第二个 AWS 账户。

操作流程

通过 AWS CloudFormation 创建资源

要使用 Amazon S3 访问权限,您需要一个版本为 6.15.0 或更高的 Amazon EMR 集群。请参考以下文档以获取更多信息,包括如何将 Amazon S3 访问权限与 、 和 结合使用。

为本次演示,我们假设您在组织中有两种不同类型的数据访问用户——具有读写权限的分析工程师和仅具有读取权限的业务分析师。我们将使用两种不同的 AWS IAM角色,但您也可以直接将自己的身份提供者连接到 IAM 身份中心。

以下是这一部分的架构图。AWS CloudFormation 堆栈将创建以下 AWS 资源:

资源描述
VPC 堆栈包含私有和公有子网,用于 EMR Studio,路由表和 NAT 网关。
Amazon S3 存储桶存储 EMR 产生的日志文件、Spark 代码和 Jupyter 笔记本。
包含样本数据的 S3 存储桶用于配合 S3 访问权限使用的样本数据。
配置的 Amazon EMR 集群使用运行时角色和 S3 访问权限的集群。
配置的 Amazon EMR Serverless 应用使用 S3 访问权限的 Serverless 应用。
EMR Studio用户可以登录并使用 EMR Serverless 应用创建工作空间笔记本。
两个用于 EMR 作业运行的 AWS IAM 角色一个具有写入权限,一个具有读取权限。
处理 S3 访问权限的 IAM 角色在注册位置时能用于访问存储桶数据的角色。

开始操作,请完成以下步骤:

  1. 选择 启动堆栈
    删除)](https://console.aws.amazon.com/cloudformation/home?region=us- east-1#/stacks/new?stackName=EMRBlog&templateURL=https://s3.amazonaws.com/aws- blogs-artifacts-public/artifacts/BDB-3849/blog_post_template.cfn.yaml)
  2. 接受默认设置,选择 我确认此模板可能创建 IAM 资源

AWS CloudFormation 堆栈的创建大约需要 10-15 分钟。完成后,转到输出标签,您会发现以下步骤所需的信息。

创建 Amazon S3 访问权限资源

首先,我们将创建 Amazon S3 访问权限资源。创建一个 S3 访问权限实例,创建一个 S3 访问权限位置,引用由 AWS CloudFormation堆栈创建的数据存储桶,该存储桶仅对我们创建的 AWS IAM 角色可访问,并为读写角色授予不同级别的访问权限。

bash aws s3control create-access-grants-instance \ --account-id <YOUR_ACCOUNT_ID>

接下来,创建一个新的 S3 访问权限位置。Amazon S3 访问权限通过提供 AWS IAM 凭证来工作,这些凭证可用于特定 S3 前缀的访问。S3访问权限位置将与一个 AWS IAM 角色相关联。

我们将有选择性地将 AWS IAM 角色的作用域限制为堆栈创建的存储桶。前往输出标签以查找替换以下代码片段中的值:

bash aws s3control create-access-grants-location \ --account-id <YOUR_ACCOUNT_ID> \ --location-scope "s3://<DATA_BUCKET>/" \ --iam-role-arn <DATA_BUCKET_ROLE>

记下响应中的 AccessGrantsLocationId 值。我们将在接下来的步骤中创建必要的 S3 访问权限,以限制对存储桶的读写访问。

  • 对于读写用户,使用 s3control create-access-grant 允许对 "output/*" 前缀的 READWRITE 访问:

bash aws s3control create-access-grant \ --account-id <YOUR_ACCOUNT_ID> \ --access-grants-location-id <LOCATION_ID_FROM_PREVIOUS_COMMAND> \ --access- grants-location-configuration S3SubPrefix="output/*" \ --permission READWRITE \ --grantee GranteeType=IAM,GranteeIdentifier=<DATA_WRITER_ROLE>

  • 对于读取用户,再次使用 s3control create-access-grant 允许对相同前缀的仅 READ 访问:

bash aws s3control create-access-grant \ --account-id <YOUR_ACCOUNT_ID> \ --access-grants-location-id <LOCATION_ID_FROM_PREVIOUS_COMMAND> \ --access- grants-location-configuration S3SubPrefix="output/*" \ --permission READ \ --grantee GranteeType=IAM,GranteeIdentifier=<DATA_READER_ROLE>

演示场景 1:在 EC2 上运行 Spark 作业生成 Parquet 数据

现在我们已经设置好 Amazon EMR 环境并通过 S3 访问权限授予角色的访问权限,值得注意的是,我们的 EMR 集群和 EMR Serverless应用的两个 AWS IAM 角色具有只允许访问我们的 EMR 工件存储桶的 IAM 策略。它们没有访问 S3 数据存储桶的 IAM 权限,而是使用 S3访问权限获取针对存储桶和前缀的短期凭证。

此外,角色被授予 s3:GetDataAccess 和 s3:GetDataAccessGrantsInstanceForPrefix 权限以请求通过特定区域创建的 S3 访问权限实例的访问权限。这种设置使您能够以更加细粒度的方式管理 S3 访问,从而增强安全性。

接下来,我们将以分析工程师的身份在 EMR 上运行 Spark 作业,将一些示例数据转换为 Parquet 格式。请使用以下在 中提供的示例代码。下载该文件并将其拷贝到由 AWS CloudFormation 堆栈创建的 EMR_ARTIFACTS_BUCKET。我们将使用具有 ReadWrite AWS IAM角色提交作业。请注意,针对 EMR 集群,我们已配置 S3 访问权限在访问未通过 S3 访问权限提供时回退到 IAM 角色。

`bash aws s3 cp converter.py s3://<EMR_ARTIFACTS_BUCKET>/code/ aws emr add- steps --cluster-id <EMR_CLUSTER_ID> \ --execution-role-arn <DATA_WRITER_ROLE> \ --steps '的 步骤 标签中查看作业的状态。

演示场景 2:使用 EMR Studio 的交互式 EMR Serverless 应用分析数据

接下来,让我们登录 EMR Studio 并使用只读运行时角色的 EMR Serverless 应用分析场景1中的数据。首先,我们需要在 Serverless 应用上启用交互式端点。

  • 在 AWS CloudFormation 堆栈的 输出标签 中选择 EMRStudioURL
  • 在左侧的 服务器端 部分下选择 应用程序

删除)

  • 选择 EMRBlog 应用,然后选择 操作 下拉菜单中的 配置
  • 展开 交互式端点 部分,确保选中 启用交互式端点

删除)

  • 向下滚动并单击 配置应用 以保存更改。
  • 返回到“应用程序”页面,选择 EMRBlog 应用,然后单击 启动应用 按钮。

接下来,在 Studio 中创建一个新的工作空间。

  • 在左侧选择 工作空间 ,然后单击 创建工作空间 按钮。
  • 输入工作空间名称,保留其余默认设置,然后选择 创建工作空间
  • 创建工作空间后,应该会在几秒钟内在新标签中启动。

现在将工作空间连接到您的 EMR Serverless 应用。

  • 选择左侧的 EMR 计算 按钮。
  • 选择 EMR Serverless 作为计算类型。
  • 选择 EMRBlog 应用和以 EMRBlog 开头的运行角色。
  • 选择 附加 。窗口将刷新,然后您可以打开新的 PySpark 笔记本,按照下面的步骤继续操作。为了亲自执行代码,请下载 ,使用文件浏览器中的 上传文件 按钮将其上传到您的工作空间。

删除)

让我们快速读取数据。

python df = spark.read.parquet(f"s3://{DATA_BUCKET}/output/weather-data/") df.createOrReplaceTempView("weather") df.show()

删除)

我们将执行一个简单的 COUNT(*)

python spark.sql("SELECT year, COUNT(*) FROM weather GROUP BY 1").show()

删除)
您还可以看到,如果尝试将数据写入输出位置,则会出现 Amazon S3 错误。

pythondf.write.format("csv").mode("overwrite").save("s3://<DATA_BUCKET>/output/weather- data-2/")

删除)

尽管您也可以通过 AWS IAM 策略授予类似的访问权限,但 Amazon S3 访问权限在那些已经无法通过 IAM 管理访问的组织中非常有用,或希望将 S3 访问权限映射到 IAM 身份中心的主体或角色,或此前使用过 EMR 文件系统 (EMRFS) 角色映射的情况。S3访问权限凭证也是临时的,提供了更安全的数据访问。此外,如下所示,跨账户访问也能从 S3 访问权限的简化中受益。

演示场景 3:跨账户访问

另一个常见的访问模式是跨账户访问数据。在数据网格逐渐兴起的情况下,数据生产者和消费者在不同的 AWS 账户中去中心化,这种模式变得越来越普遍。

此前,跨账户访问需要在配置 Spark 作业时设置复杂的跨账户假设角色操作和自定义凭证提供程序。借助 S3 访问权限,我们只需执行以下操作:

  • 在第二个数据消费者账户中创建一个 Amazon EMR 作业角色和集群;
  • 数据生成者账户使用新的实例资源策略授予数据消费者账户访问权限;
  • 数据生成者账户为数据消费者作业角色创建访问权限。

就这么简单!如果您手头有第二个账户,可以在数据消费者账户中部署 ,以创建新的 EMRServerless 应用和作业角色。如果没有,您可以按照下面的步骤进行操作。AWS CloudFormation堆栈的创建应在一分钟内完成。接下来,我们将为数据消费者授予对数据生成者账户中 S3 访问权限实例的访问权限。

  • <DATA_PRODUCER_ACCOUNT_ID><DATA_CONSUMER_ACCOUNT_ID> 替换为相关的 12 位 AWS 账户 ID。
  • 您可能还需要在命令和策略中更改区域:

bash aws s3control put-access-grants-instance-resource-policy \ --account-id <DATA_PRODUCER_ACCOUNT_ID> \ --region us-east-2 \ --policy '{ "Version": "2012-10-17", "Id": "S3AccessGrantsPolicy", "Statement": [ { "Sid": "AllowAccessToS3AccessGrants", "Principal": { "AWS": "<DATA_CONSUMER_ACCOUNT_ID>" }, "Effect": "Allow", "Action": [ "s3:ListAccessGrants", "s3:ListAccessGrantsLocations", "s3:GetDataAccess", "s3:GetAccessGrantsInstanceForPrefix" ], "Resource": "arn:aws:s3:us- east-2:<DATA_PRODUCER_ACCOUNT_ID>:access-grants/default" } ] }'

  • 然后,授予数据消费者账户的 EMR Serverless 作业角色对输出文件夹的 READ 访问权限:

bash aws s3control create-access-grant \ --account-id <DATA_PRODUCER_ACCOUNT_ID> \ --access-grants-location-id <LOCATION_ID_FROM_PREVIOUS_COMMAND> \ --access-grants-location-configurationS3SubPrefix="output/*" \ --permission READ \ --granteeGranteeType=IAM,GranteeIdentifier=DATA_CONSUMER_JOB_ROLE \ --region us-east-2

完成这些操作后,我们将能够从数据生成者账户的存储桶中在数据消费者账户中读取数据。我们只需再次运行简单的 COUNT(*) 查询。将 <APPLICATION_ID><DATA_CONSUMER_JOB_ROLE><DATA_CONSUMER_LOG_BUCKET> 替换为第二个账户的 AWS CloudFormation 堆栈输出标签中的值,并将 <DATA_PRODUCER_BUCKET> 替换为第一个

Leave a Reply

Required fields are marked *