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-1
中vpc-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-app
、subnet-app
和sg-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-dkr
和 ecr-api
VPC 端点的 em> 选项。
我也尝试过只使用 Fargate 容器,因为它们没有 ECS 代理 的额外复杂性,并且因为根据文档:
使用 Fargate 启动类型的任务只需要 com.amazonaws.region.ecr.dkr Amazon ECR VPC 终端节点和 Amazon S3 网关终端节点即可利用此功能。
这也不起作用,每次我的 Fargate 任务运行时,我都会在 nat-main
的 MonitoringBytes 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 网关与负载均衡器和私有子网一起使用时的奇怪行为
用于微服务的私有子网 ecs 连接上负载均衡器的 AWS API 网关