如何排查 Amazon S3 分批操作问题?
上次更新日期:2021 年 12 月 16 日
我正在尝试为存储在我的存储桶中的对象创建一个 Amazon Simple Storage Service (Amazon S3) 分批操作任务。但是,Amazon S3 不断返回错误,或者我的批处理任务不断失败。如何排查此问题?
简短描述
如果 Amazon S3 分批操作任务遇到阻止其成功运行的问题,则该任务将失败。例如,如果 S3 无法读取指定的清单,或者清单中的对象不存在于指定的存储桶中,则任务将失败。失败的任务会生成一个或多个故障代码和原因。S3 分批操作会将故障代码和原因存储在任务中,以便您可以通过请求任务的详细信息进行查看。您还可以在任务完成报告中查看故障代码和原因。
为防止任务运行大量不成功的操作,Amazon S3 还对每个分批操作任务设置了任务故障阈值。Amazon S3 会在至少运行 1,000 个任务后监控任务故障率。如果任务的故障率超过 50%,则任务将失败。要解决此故障,请查看故障原因并在重新提交任务之前进行纠正。
以下是 Amazon S3 分批操作失败或返回错误的一些常见原因:
- 清单文件格式(CSV 或 JSON)
- 清单文件指定多个存储桶名称或包含多个标题行
- 读取清单文件的权限
- 批处理任务区域
- S3 库存报告的目标存储桶
- AWS Identity 访问管理 (IAM) 角色的信任策略
- 用于创建批处理任务的 IAM 角色权限
- 访问源存储桶、S3 库存报告和目标存储桶的 IAM 角色
- AWS Organizations 服务控制策略 (SCP)
解决方法
清单文件格式(CSV 或 JSON)
Amazon S3 分批操作支持 CSV 和 JSON(S3 库存报告)清单文件。在 Amazon S3 中创建新的批处理任务时,请为清单文件选择或指定正确的清单格式:
- 对于 Amazon S3 库存报告,请确保使用 CSV 格式的报告,并指定与库存报告关联的 manifest.json 文件。
- 对于 CSV 文件,清单文件中的每一行必须包含清单对象键、ETag 和可选的版本 ID。对象键必须为 URL 编码。清单必须要么包含所有对象的版本 ID,要么省略所有对象的版本 ID。注意:如果清单中的对象位于受版本控制的存储桶中,则必须为对象指定版本 ID。否则,批处理任务可能会失败。或者,批处理任务可能应用于对象的最新版本(而不是创建任务时存在的对象)。
有关清单文件和格式的更多信息,请参阅指定清单。
清单文件指定多个存储桶名称或包含多个标题行
借助 S3 分批操作,您可以复制对象、修改对象的对象锁定保留日期或修改对象锁定法律保留状态。这三个批处理任务操作要求清单文件中列出的所有对象也存在于同一个存储桶中。否则,您将会遇到以下错误:
Reasons for failure:
Cannot have more than 1 bucket per Job. <Job ID>
如果要执行这三个批处理任务操作之一,请确保清单文件仅指定一个存储桶名称。此外,清单文件不得包含任何标题行。例如,如果清单文件如下所示(包含多个标题行),则 Amazon S3 将返回错误:
bucket,key
my-batch-bucket,object001.txt
my-batch-bucket,object002.txt
my-batch-bucket,object003.txt
my-batch-bucket,object004.txt
读取清单文件的权限
验证用于创建 S3 分批操作任务的 IAM 角色是否具有 GetObject 权限,以允许其读取清单文件。可以检查对象的元数据进行验证。查找 S3 对象所有权访问权限或用于加密清单文件的任何不受支持的 AWS KMS 密钥之间是否存在任何不匹配。
如果您没有读取清单文件的权限,则在尝试创建 S3 分批操作任务时会出现以下错误。
AWS CLI:
Reason for failure
Reading the manifest is forbidden: AccessDenied
Amazon S3 控制台:
Warning: Unable to get the manifest object's ETag. Specify a different object to continue
批处理任务区域
创建 S3 分批操作复制任务的 AWS 区域必须与要复制对象的目标存储桶相同。因此,在创建批处理任务时,请确保选择与目标存储桶相同的区域。例如,如果目标存储桶位于 us-west-2 区域,则选择 us-west-2 作为批处理任务的区域。
S3 库存报告的目标存储桶
确认存在 S3 库存报告的目标存储桶。另外,确认 S3 存储桶策略不会拒绝 s3:PutObject 操作。如果报告已传递给另一个 AWS 账户,则确认目标存储桶是否允许 IAM 角色执行 s3:PutObject 操作。
IAM 角色的信任策略
注意:确保指定的是 IAM 角色,而不是 IAM 用户。
与 IAM 用户不同,IAM 角色具有的信任策略定义了其他主体必须满足哪些条件才能承担该角色。要允许 S3 分批操作服务主体承担 IAM 角色,请将信任策略附上该角色。
以下信任策略示例委托了对 Amazon S3 的访问权限,同时降低了与权限提升相关的任何风险:
{
"Version":"2012-10-17",
"Statement":[
{
"Effect":"Allow",
"Principal":{
"Service":"batchoperations.s3.amazonaws.com"
},
"Action":"sts:AssumeRole"
}
]
}
用于创建批处理任务的 IAM 权限
在创建和运行 S3 分批操作任务之前,请授予所需的权限。如果您的 IAM 角色缺少执行 S3 分批操作任务所需的权限,则批处理任务将失败。
要创建 S3 分批操作任务,需要 s3:CreateJob 权限。创建任务的同一实体还必须具有 iam:PassRole 权限,才能传递为批处理作业指定的 IAM 角色。有关指定 IAM 资源的更多信息,请参阅 IAM JSON 策略,资源元素。
访问源存储桶、S3 库存报告和目标存储桶的 IAM 角色
检查以确保用于 S3 分批操作的 IAM 角色具有执行批处理任务所需的权限。例如,复制操作的 IAM 策略如下所示:
{
"Version": "2012-10-17",
"Statement": [
{
"Action": [
"s3:PutObject",
"s3:PutObjectAcl",
"s3:PutObjectTagging"
],
"Effect": "Allow",
"Resource": "arn:aws:s3:::{{DestinationBucket}}/*"
},
{
"Action": [
"s3:GetObject",
"s3:GetObjectAcl",
"s3:GetObjectTagging",
"s3:ListBucket"
],
"Effect": "Allow",
"Resource": [
"arn:aws:s3:::{{SourceBucket}}",
"arn:aws:s3:::{{SourceBucket}}/*"
]
},
{
"Effect": "Allow",
"Action": [
"s3:GetObject",
"s3:GetObjectVersion"
],
"Resource": [
"arn:aws:s3:::{{ManifestBucket}}/*"
]
},
{
"Effect": "Allow",
"Action": [
"s3:PutObject"
],
"Resource": [
"arn:aws:s3:::{{ReportBucket}}/*"
]
}
]
}
有关更多信息,请参阅授予 Amazon S3 分批操作的权限。
AWS Organizations 服务控制策略 (SCP)
如果您使用的是 AWS Organizations,请确认没有任何可能拒绝访问 Amazon S3 的拒绝声明。例如,如果您的服务控制策略显式拒绝所有 S3 操作,则在创建批处理任务时可能会出现拒绝访问错误。
下面是一个显式拒绝所有 S3 操作的策略示例:
{
"Version": "2012-10-17",
"Statement": [
{
"Principal":"*",
"Effect": "Deny",
"Action": "s3:*",
"Resource": "*"
}
]
}
如果要应用限制性策略,可以将 S3 分批操作用于执行操作的 IAM 角色列入允许名单。例如:
{
"Version": "2012-10-17",
"Statement": [
{
"Principal":"*",
"Effect": "Deny",
"Action": "s3:*",
"Resource": "*",
"Condition": {
"StringNotLike": {
"aws:userId": [
"AROAEXAMPLEID:*",
"AIDAEXAMPLEID",
"111111111111"
]
}
}
}
]
}