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 数据推送到 Kinesis Stream
AWS Lambda 可以与外部 Internet 服务对话吗?