AWS Lambda - NAT 网关互联网访问导致超时
AWS Lambda - NAT Gateway internet access results in timeout
我有一个 AWS Lambda 函数:
- 检查 Redis Elasticache 实例,
- 如果在缓存中找不到该项目,请转到 Google Places API 服务。
Redis 实例在 私有子网 中;因此,为了获取它,我添加了实例所在的 VPC 和子网。我还指定了允许所有出站流量的安全组。网络 ACL 是默认的,它应该用于所有入站和出站流量。
像这样通过控制台将VPC添加到Lambda函数时,提示:
When you enable VPC, your Lambda function will lose default internet access. If you require external internet access for your function, ensure that your security group allows outbound connections and that your VPC has a NAT gateway.
所以,在私有子网的Route Table
中,我也添加了一个NAT gateway
。但是,在从 Lambda 函数调用 Google Places API 服务时,它总是注定会导致超时。
简而言之,我怀疑 NAT 网关是否正确允许 Lambda 函数的互联网访问。我如何检查它出了什么问题?
NAT 网关是否以某种方式在 CloudWatch 等中记录通过它尝试的呼叫或呼叫尝试?
我的案例的问题原来是我在私有子网中创建了 NAT 网关。
确保将 NAT 网关置于 public 子网。
顺便说一句,CloudWatch 中有指标但没有直接日志记录可用的 NAT 网关。
需要以下步骤
- 具有分配给您的 lambda 函数的完整 VPC 权限的 IAM 角色。
- 具有 public 和私有子网
的 VPC
- 正在创建 NAT 网关
a) 子网必须是 public 子网
b)弹性IP新建或分配
- 创建路由 table 并添加另一个目标路由作为我们在上面创建的 NAT 网关。
你的 lambda 现在应该很开心了
我想详细说明@vahdet 的回答。我正在失去理智试图调和 NAT 网关应该如何同时位于 public 和私有子网中。似乎 AWS 官方文档 here 是错误的,但当然不是。我和其他人都忽略了一个非常微妙的细节。
NAT 网关必须同时“hot-wired”跨越两个不同的子网,以便将私有地址桥接到 public 面向互联网的地址。
首先,我尝试将 NAT 网关放在与 IGW 相同的路由 table 中,但这当然行不通,因为你不能有两条相同的路由 (0.0.0.0/0 ) 具有不同的目标。
指南说要将 NAT 网关放在专用网络的路由 table 中,我照做了,但似乎没有用。
我遗漏的关键细节是 NAT 网关必须 在 public 子网中创建。文档实际上是这样说的,但它似乎令人困惑,因为我们后来被告知将 NAT 网关的 route 放在 private table 中.
这两件事都是真的。在public子网中创建NAT网关,然后只在中添加一个路由table条目 ]私人路线table.
文档告诉您在 VPC 中创建以下网络资源:
- 两个新子网
- 两条新路线tables
- 一个新的 NAT 网关
我已经有了一条路由 table 和一些子网,所以我尝试只添加一个新子网和一条新路由 table,这就是我遇到麻烦的地方。确实最好按照记录创建两个。
我的子网是这样的:
subnet-public 10.8.9.0/24 us-east-1a
subnet-private 10.8.8.0/24 us-east-1a
然后在subnet-public中创建 NAT网关。
它将等待几分钟,这很重要,因为它必须先进入可用状态,然后才能在路由 table 条目中引用。
这是路线 tables:
route-table-public
10.8.0.0/16 local
0.0.0.0/0 igw-xyz
subnet-association: subnet-public
route-table-private
10.8.0.0/16 local
0.0.0.0/0 nat-abc
subnet-association: subnet-private
你看到那里发生了什么吗?这真的很微妙。 NAT 网关是 cross-wired。它“存在于”创建它的 public 子网中,但私有子网中的所有流量都会路由到它。
如果您像我最初那样在私有子网中创建 NAT 网关,那么 NAT 网关就像私有子网中的其他所有内容一样孤立,无法将流量路由到 Internet。它必须在 public 子网中 创建 才能访问互联网,因为它必须 在 public 子网[=62] 中有一个 IP 地址=].我的 NAT 网关获得了 10.8.9.127 的内部 IP 和 54.X.X.X 范围内的外部 IP。
通过使 NAT 网关成为私有路由中的 0.0.0.0/0 路由 table,我们告诉所有非 10.8.0.0/16 流量直接进入 NAT 网关,即使它实际上不在私有子网内。
VPC 本身知道如何跨自己的子网桥接流量,并且能够将 10.8.8.X 流量发送到 NAT 网关的 10.8.9.X IP。然后它充当桥梁,并将所有通过其内部 IP 的流量转换为其外部 IP。因为它位于 public 子网中,该子网位于具有 Internet 网关的路由 table 中,所以外部 IP 具有通往 Internet 的清晰路径。
现在我在 subnet-private 中的私有 VPC lambda 已经通过 NAT 网关验证了互联网访问。
我有一个 AWS Lambda 函数:
- 检查 Redis Elasticache 实例,
- 如果在缓存中找不到该项目,请转到 Google Places API 服务。
Redis 实例在 私有子网 中;因此,为了获取它,我添加了实例所在的 VPC 和子网。我还指定了允许所有出站流量的安全组。网络 ACL 是默认的,它应该用于所有入站和出站流量。
像这样通过控制台将VPC添加到Lambda函数时,提示:
When you enable VPC, your Lambda function will lose default internet access. If you require external internet access for your function, ensure that your security group allows outbound connections and that your VPC has a NAT gateway.
所以,在私有子网的Route Table
中,我也添加了一个NAT gateway
。但是,在从 Lambda 函数调用 Google Places API 服务时,它总是注定会导致超时。
简而言之,我怀疑 NAT 网关是否正确允许 Lambda 函数的互联网访问。我如何检查它出了什么问题?
NAT 网关是否以某种方式在 CloudWatch 等中记录通过它尝试的呼叫或呼叫尝试?
我的案例的问题原来是我在私有子网中创建了 NAT 网关。
确保将 NAT 网关置于 public 子网。
顺便说一句,CloudWatch 中有指标但没有直接日志记录可用的 NAT 网关。
需要以下步骤
- 具有分配给您的 lambda 函数的完整 VPC 权限的 IAM 角色。
- 具有 public 和私有子网 的 VPC
- 正在创建 NAT 网关 a) 子网必须是 public 子网 b)弹性IP新建或分配
- 创建路由 table 并添加另一个目标路由作为我们在上面创建的 NAT 网关。 你的 lambda 现在应该很开心了
我想详细说明@vahdet 的回答。我正在失去理智试图调和 NAT 网关应该如何同时位于 public 和私有子网中。似乎 AWS 官方文档 here 是错误的,但当然不是。我和其他人都忽略了一个非常微妙的细节。
NAT 网关必须同时“hot-wired”跨越两个不同的子网,以便将私有地址桥接到 public 面向互联网的地址。
首先,我尝试将 NAT 网关放在与 IGW 相同的路由 table 中,但这当然行不通,因为你不能有两条相同的路由 (0.0.0.0/0 ) 具有不同的目标。
指南说要将 NAT 网关放在专用网络的路由 table 中,我照做了,但似乎没有用。
我遗漏的关键细节是 NAT 网关必须 在 public 子网中创建。文档实际上是这样说的,但它似乎令人困惑,因为我们后来被告知将 NAT 网关的 route 放在 private table 中.
这两件事都是真的。在public子网中创建NAT网关,然后只在中添加一个路由table条目 ]私人路线table.
文档告诉您在 VPC 中创建以下网络资源:
- 两个新子网
- 两条新路线tables
- 一个新的 NAT 网关
我已经有了一条路由 table 和一些子网,所以我尝试只添加一个新子网和一条新路由 table,这就是我遇到麻烦的地方。确实最好按照记录创建两个。
我的子网是这样的:
subnet-public 10.8.9.0/24 us-east-1a
subnet-private 10.8.8.0/24 us-east-1a
然后在subnet-public中创建 NAT网关。 它将等待几分钟,这很重要,因为它必须先进入可用状态,然后才能在路由 table 条目中引用。
这是路线 tables:
route-table-public
10.8.0.0/16 local
0.0.0.0/0 igw-xyz
subnet-association: subnet-public
route-table-private
10.8.0.0/16 local
0.0.0.0/0 nat-abc
subnet-association: subnet-private
你看到那里发生了什么吗?这真的很微妙。 NAT 网关是 cross-wired。它“存在于”创建它的 public 子网中,但私有子网中的所有流量都会路由到它。
如果您像我最初那样在私有子网中创建 NAT 网关,那么 NAT 网关就像私有子网中的其他所有内容一样孤立,无法将流量路由到 Internet。它必须在 public 子网中 创建 才能访问互联网,因为它必须 在 public 子网[=62] 中有一个 IP 地址=].我的 NAT 网关获得了 10.8.9.127 的内部 IP 和 54.X.X.X 范围内的外部 IP。
通过使 NAT 网关成为私有路由中的 0.0.0.0/0 路由 table,我们告诉所有非 10.8.0.0/16 流量直接进入 NAT 网关,即使它实际上不在私有子网内。
VPC 本身知道如何跨自己的子网桥接流量,并且能够将 10.8.8.X 流量发送到 NAT 网关的 10.8.9.X IP。然后它充当桥梁,并将所有通过其内部 IP 的流量转换为其外部 IP。因为它位于 public 子网中,该子网位于具有 Internet 网关的路由 table 中,所以外部 IP 具有通往 Internet 的清晰路径。
现在我在 subnet-private 中的私有 VPC lambda 已经通过 NAT 网关验证了互联网访问。