AWS ECS:VPC 终端节点和 NAT 网关

Posted

技术标签:

【中文标题】AWS ECS:VPC 终端节点和 NAT 网关【英文标题】:AWS ECS: VPC Endpoints and NAT Gateways 【发布时间】:2019-09-17 11:52:36 【问题描述】:

根据NAT Gateways 上的 AWS 文档,它们无法通过 VPC endpoints 发送流量,除非以下列方式设置:

NAT 网关无法通过 VPC 端点发送流量 [...]。如果私有子网中的实例必须通过 VPC 端点访问资源 [...],请使用私有子网的路由表将流量直接路由到这些设备。

按照文档中的this 示例,我为我的 ECS 应用创建了以下配置:

    具有 CIDR 172.31.0.0/16 的 VPC (vpc-app)。 具有以下路由表的应用子网 (subnet-app):
    Destination     |  Target
    ----------------|-----------
    172.31.0.0/16   |   local  
    0.0.0.0/0       |  nat-main
    子网default-1vpc-app 中的NAT 网关(nat-main) 具有以下路由表:
    Destination     |    Target
    ----------------|--------------
    172.31.0.0/16   |     local  
    0.0.0.0/0       |  igw-xxxxxxxx
    安全组 (sg-app) 为 subnet-app 打开端口 443。 具有vpc-appsubnet-appsg-app 的 VPC 终端节点(接口类型)用于以下服务:
    com.amazonaws.eu-west-1.ecr.api  
    com.amazonaws.eu-west-1.ecr.dkr  
    com.amazonaws.eu-west-1.ecs  
    com.amazonaws.eu-west-1.ecs-agent  
    com.amazonaws.eu-west-1.ecs-telemetry  
    com.amazonaws.eu-west-1.s3 (Gateway)

还有一点很重要,我为vpc-app 启用了DNS 解析DNS 主机名,以及启用私有DNS 名称 ecr-dkrecr-api VPC 端点的 em> 选项。

我也尝试过只使用 Fargate 容器,因为它们没有 ECS 代理 的额外复杂性,并且因为根据文档:

使用 Fargate 启动类型的任务只需要 com.amazonaws.region.ecr.dkr Amazon ECR VPC 终端节点和 Amazon S3 网关终端节点即可利用此功能。

这也不起作用,每次我的 Fargate 任务运行时,我都会在 nat-mainMonitoringBytes out to source 的峰值/em>。

无论我尝试什么,subnet-app 中的 EC2 实例(和 Fargate 任务)仍在使用 nat-main 拉取映像,而不是转到 ECR 服务的本地地址。

我已重新启动 ECS 代理,并确保选中 ECS Interface VPC Endpoints 指南和 ECR Interface Endpoints 指南中的所有框。

我在这里错过了什么?

任何帮助将不胜感激。

【问题讨论】:

安全组需要修改吗? 是的,您需要为子网启用端口 443 的访问权限,我已经这样做了。 【参考方案1】:

接口 VPC 端点使用 DNS 解析,而不是路由。

为了使您的配置正常工作,您需要确保在创建端点时选中了启用私有 DNS 名称。这使您能够使用其默认 DNS 主机名向服务发出请求,而不是使用特定于端点的 DNS 主机名。

来自documentation:

当您创建接口端点时,我们会生成特定于端点的 DNS 主机名,您可以使用这些主机名与服务进行通信。对于 AWS 服务和 AWS Marketplace 合作伙伴服务,您可以选择为终端节点启用私有 DNS。此选项将私有托管区域与您的 VPC 相关联。托管区域包含服务的默认 DNS 名称(例如,ec2.us-east-1.amazonaws.com)的记录集,该名称解析为您的 VPC 中终端节点网络接口的私有 IP 地址。这使您可以使用其默认 DNS 主机名而不是特定于端点的 DNS 主机名向服务发出请求。例如,如果您现有的应用程序向 AWS 服务发出请求,它们可以继续通过接口端点发出请求,而无需更改任何配置。

另一种方法是更新您的应用程序以使用特定于端点的 DNS 主机名。

请注意,要使用私有 DNS 名称,必须为您的 VPC 启用 DNS 解析DNS 主机名

另请注意,要在没有 NAT 网关的情况下使用 ECR/ECS,您需要配置 S3 端点(网关,需要更新路由表)以允许实例从托管的底层私有 Amazon S3 存储桶下载图像层他们。更多信息Setting up AWS PrivateLink for Amazon ECS, and Amazon ECR

【讨论】:

感谢您的回复,我确实为 VPC 启用了 DNS 解析和 DNS 主机名,以及为 ECR + ECR-API VPCE 启用了私有 DNS 名称选项。我已经更新了我的问题,将这些启用的选项作为配置的一部分。您到底是什么意思:接口 VPC 端点使用 DNS 解析,而不是路由。 您可以在您的 VPC 中运行 dig +short ecr.eu-west-1.amazonaws.com 吗?我的意思是您的应用仍会尝试访问ecr.eu-west-1.amazonaws.com,但它应该解析为端点的 ENI 之一的 IP 地址。它不像 S3 必须在路由表中配置。 刚刚运行了您的建议,我得到的是公共 IP 而不是内部 IP,我可以尝试找出为什么会发生这种情况? PacketsOutToDestination 的值大于零表示有流量从 NAT 网关后面的客户端(=上传)互联网。 您可以通过暂时关闭您的 NAT 网关并尝试拉/启动任务来确认您的 ECR 的 VPC 终端节点正在工作。【参考方案2】:

经过数小时的反复试验,在@jogold 的大力帮助下,在this 博客文章中找到了缺失的部分:

下一步是为 S3 创建网关 VPC 终端节点。这是必要的,因为 ECR 使用 S3 来存储 Docker 镜像层。当您的实例从 ECR 下载 Docker 映像时,它们必须访问 ECR 以获取映像清单和 S3 以下载实际的映像层。

创建 S3 网关 VPCE 后,我忘记将其地址添加到 subnet-app 的路由表中,所以虽然对我的 ECR URI 的初始请求是使用内部地址发出的,但从 S3 下载图像仍然使用了 NAT 网关。

添加条目后,NAT网关的网络使用量急剧下降。

有关如何设置网关 VPCE 的更多信息,请访问here。

【讨论】:

很高兴您找到了解决方案,将在我的回答中添加关于 S3 端点的注释。 由于您的第一个回复范围更广,并且包含关于 S3 端点的注释,因此我决定接受您的答案作为正确答案,感谢您的帮助!

以上是关于AWS ECS:VPC 终端节点和 NAT 网关的主要内容,如果未能解决你的问题,请参考以下文章

AWS VPC:将 NAT 和 Internet 网关与负载均衡器和私有子网一起使用时的奇怪行为

阿里云VPC实验五则

阿里云NAT网关配置

用于微服务的私有子网 ecs 连接上负载均衡器的 AWS API 网关

AWS Lambda:如何为具有 VPC 访问权限的 lambda 函数设置 NAT 网关

AWS Lambda + NAT 网关的替代方案