为什么 VPC 中 public 子网内的 AWS lambda 函数无法连接到 Internet?

Why can't an AWS lambda function inside a public subnet in a VPC connect to the internet?

我已经按照教程 here 创建了一个带有 public 和私有子网的 VPC。

然后我在 public 子网中设置了一个 AWS lambda 函数来测试它是否可以连接到外部互联网。

这是我用 python3

编写的 lambda 函数
import requests

def lambda_handler(event, context):
    r = requests.get('http://www.google.com')
    print(r)

当我将 http://www.google.com 的内容设置在 VPC 中的 public 子网内时,上述函数未能获取 http://www.google.com 的内容。

错误信息如下:

"errorMessage": "HTTPConnectionPool(host='www.google.com', port=80): Max retries exceeded with url: / (Caused by NewConnectionError(': Failed to establish a new connection: [Errno 110] Connection timed out',))", "errorType": "ConnectionError",

我不明白为什么。

public 子网的路由 table 如下所示:

http://www.google.comGET 请求应该匹配 igw-XXXXXXXXX 目标。为什么 internet-gateway(igw) 不能将请求传送到 http://www.google.com 并取回网站内容?

这个 article 说我必须在私有子网中设置 lambda 函数才能访问互联网。

If your Lambda function needs to access private VPC resources (for example, an Amazon RDS DB instance or Amazon EC2 instance), you must associate the function with a VPC. If your function also requires internet access (for example, to reach a public AWS service endpoint), your function must use a NAT gateway or instance.

但这并不能解释为什么我不能在 public 子网中设置 lambda 函数。

连接到 VPC public 子网的 Lambda 函数通常无法访问互联网。

要从 public 子网访问互联网,您需要一个 public IP,或者您需要通过本身具有 public IP 的 NAT 进行路由。您还需要一个 Internet Gateway (IGW)。然而:

  1. Lambda 函数没有,也不可能有 public 个 IP 地址,并且
  2. VPC public 子网中的默认路由目标是 IGW,而不是 NAT

因此,由于 Lambda 函数只有一个私有 IP,并且其流量路由到 IGW 而不是 NAT,因此从 Lambda 函数到互联网的所有数据包都将在 IGW 处被丢弃。

我应该为 VPC 访问配置我的 Lambda 函数吗?

如果您的 Lambda 函数 不需要 访问您的 VPC 内的私有资源(例如 RDS 数据库或 Elasticsearch 集群),那么不要配置 Lambda 函数来连接到 VPC .

如果您的 Lambda 函数确实需要到达您的 VPC 内的私有资源,则配置 Lambda 函数以连接到私有子网(并且仅连接到私有子网)。

是否使用 NAT?

如果 Lambda 函数只需要访问 VPC 中的资源(例如私有子网中的 RDS 数据库),那么您不需要通过 NAT 进行路由。

如果 Lambda 函数只需要访问 VPC 中的资源和访问通过私有 VPC Endpoint 提供的 AWS 服务,那么您不需要通过 NAT 进行路由。使用 VPC 端点。

如果您的 Lambda 函数需要到达互联网上的端点,则确保从 Lambda 函数的私有子网到 public 子网中的 NAT 实例或 NAT 网关的默认路由。并在需要时配置 IGW,否则无法访问互联网。

注意 NAT gateway charges per hour and per GB processed so it's worth understanding how to reduce data transfer costs for NAT gateway.

最佳实践

为 VPC 访问配置 Lambda 函数时,HA 最佳实践是跨不同可用区 (AZ) 配置多个(私有)子网。

间歇性连接

确保您为 Lambda 函数配置的所有子网都是私有子网。例如,配置 1 个私有子网和 1 个 public 子网是一个常见的错误。这将导致您的 Lambda 函数有时可以正常工作,有时会在没有任何明显原因的情况下失败。

例如,Lambda 函数可能连续成功 5 次,然后超时失败(无法访问某些互联网资源或 AWS 服务)。发生这种情况是因为第一次启动是在私有子网中,启动 2-5 在同一私有子网中重用相同的 Lambda 函数执行环境(所谓的“热启动”),然后启动 6 是“冷启动”,其中AWS Lambda 服务在 public 子网中部署了 Lambda 函数,其中 Lambda 函数没有到互联网的路由。