AWS Lambda 连接互联网

Posted

技术标签:

【中文标题】AWS Lambda 连接互联网【英文标题】:AWS Lambda connecting to Internet 【发布时间】:2016-09-05 06:23:25 【问题描述】:

TL;TR

我正在尝试从 AWS Lambda 连接到互联网,我有一个带有 NAT 网关的私有子网,但该功能仍然无法连接到互联网...

完整问题

所以我正在尝试使用我的 AWS Lambda 函数访问互联网。我试过 Java 和 NodeJS 4 都没有运气。

我有一个带有子网的私有 VPC:10.0.10.0/24

如您所见,我已向我的 NAT 网关添加了一条规则:

我这样配置我的 AWS Lambda:

选择该子网 (10.0.10.0) 并使用对所有内容(入站和出站)开放的安全组

但是,当我尝试从 Internet 下载内容时,lambda 超时:

'use strict';
console.log('Loading function');

var http = require("http");

exports.handler = (event, context, callback) => 
    //console.log('Received event:', JSON.stringify(event, null, 2));
    console.log('value1 =', event.key1);
    console.log('value2 =', event.key2);
    console.log('value3 =', event.key3);

    var options = 
      host: 'www.virgilio.it',
      port: 80,
      path: '/'
    ;

    http.get(options, function(res) 
      console.log("Got response: " + res.statusCode);
    ).on('error', function(e) 
      console.log("Got error: " + e.message);
    );

    callback(null, event.key1);  // Echo back the first key value
    // callback('Something went wrong');
;

“errorMessage”:“2016-05-10T10:11:46.936Z 79968883-1697-11e6-9e17-1f46a366f324 任务在 55.00 后超时 秒”

这是一个错误吗?

注意:如果我不选择我的 VPC,同样的功能会起作用

【问题讨论】:

【参考方案1】:

我发现了错误,应该将 NAT 网关添加到公共子网(而不是私有子网)。 公共子网是 Internet 网关路由与 0.0.0.0/0 关联的子网

【讨论】:

该默认路由更恰当地表示为0.0.0.0/0【参考方案2】:

由于我遇到了同样的问题,为上述答案增加了一点清晰度 -

    将 NAT 网关或 NAT 实例添加到公共子网(具有 0.0.0.0/0 对应(公共)子网路由表中的 Internet 网关条目) 编辑私有子网(运行 lambda 的地方)的路由表,以在公共子网中的 NAT 网关上添加一个 0.0.0.0/0 条目。 确保分配给 lambda 的安全组允许出站连接。

【讨论】:

当我这样做时,它的状态为“黑洞”。 我认为这意味着 NAT 网关已被删除【参考方案3】:

默认情况下,lambda 函数不绑定到 VPC,这使其能够访问 Internet,但会阻止它访问 VPC 中的资源,例如 RDS 实例。

如果您将 lambda 附加到 VPC,您将失去互联网访问权限,这会阻止您访问 S3 和 Dynamo 等资源以及发出 HTTP 请求。

如果您两者都需要,那么我将不得不设置 VPC 以访问 Internet,这很麻烦(嘿 AWS 伙计们,如果您有一个明确定义的流程,请简化:把它变成复选框或按钮;)

创建新的 VPC

我发现最好不要理会默认 VPC,这样您就不会冒险破坏该 VPC 中已经在工作的东西(如果您那里已经有资源),而且还因为您可以使用默认 VPC作为以后的配置参考。

使用向导创建 VPC。

创建路由表

    命名第一个public-subnet(如果还没有的话); 将第二个命名为private-lambda。 AWS 支持建议为 lambda 设置一个单独的子网,并将此路由表附加到它。

创建子网

默认情况下,当您创建 VPC 时,它会为您创建一个公共子网。如果您使用默认值,则其名称应为Public subnet。就这样吧。

现在您要创建私有子网。如果您希望 Lambda 具有高可用性,建议为您的 Lambda 设置多个私有子网。

这些私有子网中的每一个都将链接到您刚刚创建的 VPC。现在,假设您将 VPC IP 保留为 10.0.0.0/16,并且您在弗吉尼亚州 (us-east-1) 运行您的资源,下面是用于创建六个私有子网的模板,每个子网位于不同的可用区(用于高可用性):

    private-lambda-us-east-1a,可用区us-east-1a,IP 块10.0.16.0/24 private-lambda-us-east-1b,可用区us-east-1b,IP 块10.0.32.0/24 private-lambda-us-east-1c,可用区 us-east-1c,IP 块 10.0.48.0/24 private-lambda-us-east-1d,可用区us-east-1d,IP 块10.0.64.0/24 private-lambda-us-east-1e,可用区us-east-1e,IP 块10.0.80.0/24 private-lambda-us-east-1f,可用区us-east-1f,IP 块10.0.92.0/24

但是你可以看到模式: - IP块的第3个位置有16个增量; - 名称表示您所在地区的选定可用区。

确保路由表与子网关联

转到“路由表”面板; 选择公共子网表,查看其关联并确保它与公共子网相关联; 选择 private-lambda 表,查看其关联并确保它与您刚刚创建的所有 private-lambda-* 子网相关联。

创建互联网网关

只需创建一个并将其附加到 VPC。

为公共子网配置路由

在我的例子中,它是经过配置的,但只需确保您的公共子网的路由表有一个从 0.0.0.0/0 到您刚刚创建的 Internet 网关的条目。

创建 NAT(网络地址转换器)

创建一个新的 NAT 并选择您的公共子网。分配一个新的 EIP。

为私有子网配置路由

确保您的私有子网的路由表有一个从 0.0.0.0/0 到您的新 NAT 的条目。

通过这些步骤,您现在应该拥有一个支持 Internet 的 VPC。


用例:为 Internet 和 RDS 访问配置 Lambda

为 lambda 创建安全组

新建一个 SG 并配置 Outbound -> All Trafic -> 到 0.0.0.0/0::/0

修改您的 RDS 实例的安全组以允许

入站 -> 所有流量 -> 来自 lambda SG

配置 lambda

创建一个新的 lambda 或选择一个现有的; 选择您的新 VPC; 选择所有私有子网 (private-lambda-*) 以获得高可用性; 选择您的 lambda 安全组。

就是这样。您现在应该有一个可以访问 VPC 和 Internet 资源的 lambda 函数:)

【讨论】:

我从这个页面设计了这个方法:aws.amazon.com/premiumsupport/knowledge-center/… 我使用了相同的方法但无法连接 尝试了完全相同的步骤!像魅力一样工作 这让我在一年前苦苦挣扎,如果当时只有本指南存在的话。完美运行 如果我需要连接到默认 VPC 中的某个东西,比如 EC2 数据库服务器,该怎么办?和互联网课程【参考方案4】:

如果您要使用 Terraform 执行此操作,以下是您需要配置的资源(除了 Lambda 资源):

aws_vpc aws_subnet(公共和私有;多个以实现高可用性) aws_internet_gateway 用于互联网的出站连接 aws_route_table(公共子网和私有子网 x2) aws_route_table_association aws_eip(NAT 网关的弹性 IP) aws_nat_gateway aws_default_network_acl 使用 Terraform 管理默认 NACL aws_default_security_group 使用 Terraform 管理默认安全组 aws_iam_role_policy_attachment 附加AWSLambdaVPCAccessExecutionRole 政策

Deploy AWS Lambda to VPC with Terraform.

【讨论】:

【参考方案5】:

为便于您开始使用 VPC 主页上的 VPC 启动模板来部署 VPC。这将创建公共子网、私有子网、NAT GW、IGW 以及从私有子网访问 Internet 所需的所有路由。

【讨论】:

以上是关于AWS Lambda 连接互联网的主要内容,如果未能解决你的问题,请参考以下文章

如何从账户 A 中的 Lambda(VPC 中的 Lambda)调用账户 B 中的 AWS Lambda 函数(VPC 中的这个 Lambda)

AWS Lambda + NAT 网关的替代方案

将 AWS Lambda 数据推送到 Kinesis Stream

AWS Lambda 可以与外部 Internet 服务对话吗?

无法从 AWS lambda 连接 AWS redshift

如何使用 NodeJS 在 AWS Lambda 上运行 PhantomJS