为什么我的 Amazon EMR 应用程序失败,并显示 HTTP 403 “Access Denied”(访问被拒绝)AmazonS3Exception 错误?
上次更新日期:2022 年 5 月 3 日
当我提交应用程序到 Amazon EMR 集群时,应用程序遇到 HTTP 403“Access Denied”(访问被拒绝)AmazonS3Exception 错误:
java.io.IOException: com.amazon.ws.emr.hadoop.fs.shaded.com.amazonaws.services.s3.model.AmazonS3Exception: Access Denied (Service: Amazon S3; Status Code: 403; Error Code: AccessDenied; Request ID: 8B28722038047BAA; S3 Extended Request ID: puwS77OKgMrvjd30/EY4CWlC/AuhOOSNsxfI8xQJXMd20c7sCq4ljjVKsX4AwS7iuo92C9m+GWY=), S3 Extended Request ID: puwS77OKgMrvjd30/EY4CWlC/AuhOOSNsxfI8xQJXMd20c7sCq4ljjVKsX4AwS7iuo92C9m+GWY=
解决方法
如果权限配置不正确,则您可能会在 Amazon EMR 或 Amazon Simple Storage Service (Amazon S3) 上收到“Access Denied”(访问被拒绝)错误。
首先,请检查您的应用程序代码中指定的凭证或角色
在 EMR 集群的主节点上运行以下命令。使用您的 Amazon S3 路径替换 s3://doc-example-bucket/abc/。
aws s3 ls s3://doc-example-bucket/abc/
如果此命令成功,则说明应用程序代码中指定的凭证或角色导致“Access Denied”(访问被拒绝)错误。确认您的应用程序使用的是预期凭证或者代入的是预期角色,并且它有权访问 Amazon S3 路径。通过使用 AWS CLI 代入 AWS Identity and Access Management (IAM) 角色来验证该角色拥有访问 Amazon S3 路径的权限。然后,对 S3 路径执行示例请求。
如果此命令失败,请确认您使用的是最新版本的 AWS Command Line Interface (AWS CLI)。然后,请检查以下各项以解决“访问被拒绝”错误:
检查 Amazon EC2 实例配置文件角色的策略
如果 Amazon Elastic Compute Cloud (Amazon EC2) 实例配置文件在 S3 存储桶上没有所需的读取和写入权限,则可能会收到“Access Denied”(访问被拒绝)错误。
注意:默认情况下,应用程序将会从 Amazon EC2 实例配置文件的 IAM 角色继承 Amazon S3 访问权限。请确保附加于此角色的 IAM 策略允许对源和目标存储桶执行所需的 S3 操作。
要排查此问题,请运行以下命令以检查您是否具有所需的读取权限:
$ aws s3 ls s3://doc-example-bucket/myfolder/
输出可能类似于以下内容:
An error occurred (AccessDenied) when calling the ListObjectsV2 operation: Access Denied
– 或者 –
运行以下命令:
$ hdfs dfs -ls s3://doc-example-bucket/myfolder
输出可能类似于以下内容:
ls: com.amazon.ws.emr.hadoop.fs.shaded.com.amazonaws.services.s3.model.AmazonS3Exception: Access Denied (Service: Amazon S3; Status Code: 403; Error Code: AccessDenied; Request ID: RBT41F8SVAZ9F90B; S3 Extended Request ID: ih/UlagUkUxe/ty7iq508hYVfRVqo+pB6/xEVr5WHuvcIlfQnFf33zGTAaoP2i7cAb1ZPIWQ6Cc=; Proxy: null), S3 Extended Request ID: ih/UlagUkUxe/ty7iq508hYVfRVqo+pB6/xEVr5WHuvcIlfQnFf33zGTAaoP2i7cAb1ZPIWQ6Cc=
请确保实例配置文件角色对 S3 存储桶具有所需的读写权限。例如,以下 IAM 策略中的 S3 操作提供了对 S3 存储桶 doc-example-bucket 所需的读写访问权限:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "ListObjectsInBucket",
"Effect": "Allow",
"Action": [
"s3:ListBucket"
],
"Resource": [
"arn:aws:s3:::doc-example-bucket"
]
},
{
"Sid": "AllObjectActions",
"Effect": "Allow",
"Action": "s3:*Object*",
"Resource": [
"arn:aws:s3:::doc-example-bucket/*"
]
}
]
}
检查用于 EMRFS 角色映射的 IAM 角色
当您使用安全配置为 EMRFS 指定 IAM 角色时,则您正在使用角色映射。您的应用程序将根据角色映射配置从 IAM 角色继承 S3 权限。
附加到这些角色的 IAM 策略必须对源和目标存储桶具有所需的 S3 权限。要为至 Amazon S3 的 EMRFS 请求指定 IAM 角色,请参阅使用 IAM 角色为 EMRFS 设置安全配置。
检查 Amazon S3 VPC 终端节点策略
如果 EMR 集群的子网路由表有指向 Amazon S3 VPC 终端节点的路由,则确认终端节点策略允许所需的 Amazon S3 操作。
要使用 CLI 检查和修改端点策略,请执行以下操作:
运行以下命令以检查终端节点策略。将 vpce-xxxxxxxx 替换为您的 VPC ID。
aws ec2 describe-vpc-endpoints --vpc-endpoint-ids "vpce-xxxxxxxx"
如有必要,运行以下命令来上传修改后的终端节点策略。替换 VPC ID 和 JSON 文件路径。
aws ec2 modify-vpc-endpoint --vpc-endpoint-id "vpce-xxxxxxxx" --policy-document file://policy.json
要使用 Amazon VPC 控制台检查和修改端点策略,请执行以下操作:
- 打开 Amazon VPC 控制台。
- 在导航窗格中,选择 Endpoints(端点)。
- 选择 Amazon S3 终端节点(EMR 集群的子网路由表中的终端节点)。然后,选择 Policy(策略)选项卡以查看终端节点策略。
- 要添加所需的 Amazon S3 操作,选择 Edit Policy(编辑策略)。
检查 S3 源和目标存储桶策略
存储桶策略指定委托人允许或拒绝的操作。源和目标存储桶策略必须允许 EC2 实例配置文件角色或映射的 IAM 角色执行所需的 Amazon S3 操作。
要使用 CLI 检查和修改存储桶策略,请执行以下操作:
运行以下命令来检查存储桶策略。使用源或目标存储桶的名称替换 doc-example-bucket。
aws s3api get-bucket-policy --bucket doc-example-bucket
如有必要,运行以下命令来上传修改后的存储桶策略。替换存储桶名称和 JSON 文件路径。
aws s3api put-bucket-policy --bucket doc-example-bucket --policy file://policy.json
要使用 Amazon S3 控制台检查和修改存储桶策略,请执行以下操作:
- 打开 Amazon S3 控制台。
- 选择存储桶。
- 选择权限选项卡。
- 选择 Bucket Policy(存储桶策略)以检查并修改存储桶策略。
访问另一个账户中的 S3 存储桶
重要提示:如果您的应用程序访问另一个 AWS 账户的 S3 存储桶,则账户拥有者必须允许您在存储桶策略上的 IAM 角色。
例如,以下存储桶策略将为 emr-account 中的所有 IAM 角色和用户提供 s3://doc-example-bucket/myfolder/ 的全部访问权限。
{
"Id": "MyCustomPolicy",
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowRootAndHomeListingOfCompanyBucket",
"Principal": {
"AWS": [
"arn:aws:iam::emr-account:root"
]
},
"Action": [
"s3:ListBucket"
],
"Effect": "Allow",
"Resource": [
"arn:aws:s3:::doc-example-bucket"
],
"Condition": {
"StringEquals": {
"s3:prefix": [
"",
"myfolder/"
],
"s3:delimiter": [
"/"
]
}
}
},
{
"Sid": "AllowListingOfUserFolder",
"Principal": {
"AWS": [
"arn:aws:iam::emr-account:root"
]
},
"Action": [
"s3:ListBucket"
],
"Effect": "Allow",
"Resource": [
"arn:aws:s3:::doc-example-bucket"
],
"Condition": {
"StringLike": {
"s3:prefix": [
"myfolder/*"
]
}
}
},
{
"Sid": "AllowAllS3ActionsInUserFolder",
"Principal": {
"AWS": [
"arn:aws:iam::emr-account:root"
]
},
"Effect": "Allow",
"Action": [
"s3:*"
],
"Resource": [
"arn:aws:s3:::doc-example-bucket/myfolder/*",
"arn:aws:s3:::doc-example-bucket/myfolder*"
]
}
]
}