【问题标题】:S3 Requests Timing out From .Net Core App running in ECS在 ECS 中运行的 .Net Core 应用程序的 S3 请求超时
【发布时间】:2019-10-01 22:52:10
【问题描述】:

下面是我从 s3 获取对象的代码。此代码在我设置了 aws 配置文件和配置文件的机器上本地运行。我的印象是,如果我给我的 ecs 任务一个可以访问 s3 的角色,那么这仍然可以工作,而无需我将访问密钥和密钥传递给我的代码中的 s3Client。

S3 获取代码

  public async Task GetFilesFromS3Async(IEnumerable<FileDownloadViewModel> attachments)
        {
            foreach (var attachment in attachments)
            {
                var request = new GetObjectRequest()
                {
                    BucketName = "bucketname",
                    Key = $"{attachment.SubBucket}/{attachment.ObjectId}/{attachment.FileName}"
                };

                using(var s3response = await _client.GetObjectAsync(request))
                {
                    using (var memoryStream = new MemoryStream())
                    {
                        await s3response.ResponseStream.CopyToAsync(memoryStream);
                        memoryStream.Position = 0;
                        attachment.FileBytes = memoryStream.ToArray();
                    }
                }                
            }
        }

s3 客户端初始化

 private readonly IAmazonS3 _client;

    public S3Service(IAmazonS3 client)
    {
        _client = client;
    }

startup.cs 代码

services.AddAWSService<IAmazonS3>();

我的任务和 ec2 实例上的角色都有允许对 s3 进行写入/读取操作的策略。

编辑

我的 ec2 实例和运行容器的服务的策略:(基本上所有 s3 的 get 和 put 操作)

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": [
                "s3:PutAnalyticsConfiguration",
                "s3:GetObjectVersionTagging",
                "s3:CreateBucket",
                "s3:ReplicateObject",
                "s3:GetObjectAcl",
                "s3:GetBucketObjectLockConfiguration",
                "s3:DeleteBucketWebsite",
                "s3:PutLifecycleConfiguration",
                "s3:GetObjectVersionAcl",
                "s3:DeleteObject",
                "s3:GetBucketPolicyStatus",
                "s3:GetObjectRetention",
                "s3:GetBucketWebsite",
                "s3:PutReplicationConfiguration",
                "s3:PutObjectLegalHold",
                "s3:GetObjectLegalHold",
                "s3:GetBucketNotification",
                "s3:PutBucketCORS",
                "s3:GetReplicationConfiguration",
                "s3:ListMultipartUploadParts",
                "s3:PutObject",
                "s3:GetObject",
                "s3:PutBucketNotification",
                "s3:PutBucketLogging",
                "s3:PutBucketObjectLockConfiguration",
                "s3:GetObjectVersionForReplication",
                "s3:GetLifecycleConfiguration",
                "s3:ListBucketByTags",
                "s3:GetInventoryConfiguration",
                "s3:GetBucketTagging",
                "s3:PutAccelerateConfiguration",
                "s3:DeleteObjectVersion",
                "s3:GetBucketLogging",
                "s3:ListBucketVersions",
                "s3:RestoreObject",
                "s3:GetBucketPolicy",
                "s3:PutEncryptionConfiguration",
                "s3:GetEncryptionConfiguration",
                "s3:GetObjectVersionTorrent",
                "s3:AbortMultipartUpload",
                "s3:GetBucketRequestPayment",
                "s3:GetObjectTagging",
                "s3:GetMetricsConfiguration",
                "s3:DeleteBucket",
                "s3:PutBucketVersioning",
                "s3:GetBucketPublicAccessBlock",
                "s3:ListBucketMultipartUploads",
                "s3:PutMetricsConfiguration",
                "s3:GetBucketVersioning",
                "s3:GetBucketAcl",
                "s3:PutInventoryConfiguration",
                "s3:GetObjectTorrent",
                "s3:PutBucketWebsite",
                "s3:PutBucketRequestPayment",
                "s3:PutObjectRetention",
                "s3:GetBucketCORS",
                "s3:GetBucketLocation",
                "s3:ReplicateDelete",
                "s3:GetObjectVersion"
            ],
            "Resource": [
                "arn:aws:s3:::bucket/*",
                "arn:aws:s3:::bucket"
            ]
        }
    ]
}

在我的前端应用程序的控制台中,我也收到了一个 cors 错误,但在我的应用程序的其他任何地方都没有出现 cors 问题。

【问题讨论】:

    标签: amazon-web-services asp.net-core amazon-s3


    【解决方案1】:

    超时听起来好像您没有在网络级别设置任何东西。如果这是一个政策问题,我会期待一个带有权限错误的异常。我需要知道您的 ECS 任务角色和附加策略是什么样的,以及您用于 ECS 任务的启动和网络类型以提供故障排除建议。

    1. 检查角色和策略

    使用policy simulator 使用您认为在 ECS 任务中假设的策略来模拟适用于您的 S3 存储桶的 GetObject 操作。这将验证它不是政策或为您提供更多详细信息。

    验证正在使用的 ECS 任务角色以及正在使用的角色是否附加了此策略。如果您仍然认为这是一个政策问题,请在此处分享您的角色和附加政策。

    1. 验证网络

    S3 通常通过公共互联网访问。因此,如果您不允许 ECS 公共 Internet 访问,它通常不会工作,我希望像您在 OP 中看到的那样超时。您需要检查您的任务所在的 VPC 是否可以通过 NAT 网关访问公共 Internet,或者该 VPC 是否具有指向您在私有 VPC 中设置的 S3 存储桶的私有终端节点。您还需要确保 ECS 任务中使用的安全组允许出站 HTTP/HTTPS(TCP 端口 80/443)流量到公共互联网。

    这更像是一个网络问题,您需要从 serverfault.com 获得帮助,但这里有一些地方可以开始追踪网络问题。

    https://serverfault.com/questions/578571/accessing-amazon-s3-from-a-private-vpc-subnet

    https://aws.amazon.com/premiumsupport/knowledge-center/s3-private-connection-no-authentication/

    【讨论】:

    • 我使用自定义 s3 策略运行了策略模拟器,一切似乎都很好。所以我认为这不是问题。我也在使用带有 awsvpc 网络类型的 ECS/Docker。那是你要求的吗?我会将我的政策信息添加到实际问题中
    • 在你得到这个工作之后@ColbyBoren,我建议你削减那个政策。您不应该仅仅为了读取 S3 存储桶而需要所有这些操作,这是一个安全漏洞。否则,该政策看起来还不错。但是,我们需要了解您是如何允许客户使用此政策的。您为 ECS 任务分配了哪些角色以及这些角色附加了哪些策略?转到 AWS 控制台中的 ECS -> 您的集群 -> 任务 -> 单击有问题的任务 GUID -> 查看任务角色。此角色是否附加了上述政策?
    • 如果角色看起来不错(来自我之前的评论),那么接下来要看的是网络。您通常通过 Internet 访问 S3。需要确保您已将 ECS 任务配置为访问公共 Internet,或者您正在私下访问 S3。我会稍微更新我的答案以指导您。
    • 任务角色确实附加了策略。
    • 你是对的!谢啦。第二个链接解决了这个问题。
    猜你喜欢
    • 2021-06-07
    • 2021-12-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-14
    • 2016-04-18
    • 1970-01-01
    相关资源
    最近更新 更多