amazon-web-services - VPC 中的 AWS Lambda 有时无法访问 Internet
问题描述
我有部署到 VPC 的 Lambda。
这个 deploymens 有下一个配置:
- 专有网络 (192.168.0.0/16)
- 公共子网 A (192.168.32.0/20) 具有 NAT 网关和路由 0.0.0.0/0 到 Internet 网关
- 私有子网 A (192.168.48.0/20) 有路由 0.0.0.0/0 到 NAT 网关
- 私有子网 B (192.168.64.0/20)
Lambda 拥有自己的 Securiy Group 并引用“私有子网 A”和“私有子网 B”
我有一个奇怪的问题:有时 Lambda 没有 Internet Access。3rd 方服务工作正常。
另一件奇怪的事情是 Lambda 从子网(192.168.48.0/20 和 192.168.64.0/20)获得 IP,例如 127.0.0.1、169.254.76.13、169.254.79.1,而不是 IP。
错误:
Error: connect ETIMEDOUT x.x.x.x:443
at Object._errnoException (util.js:1022:11)
at _exceptionWithHostPort (util.js:1044:20)
at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1198:14)
这里完整的 CloudFormation 模板:
---
AWSTemplateFormatVersion: '2010-09-09'
Description: 'Base Infrastructure'
Metadata:
'AWS::CloudFormation::Interface':
ParameterGroups:
- Label:
default: 'VPC Parameters'
Parameters:
- VpcId
- InternetGatewayId
Parameters:
VpcId:
Type: String
InternetGatewayId:
Type: String
Resources:
SubnetAPublic:
Type: 'AWS::EC2::Subnet'
Properties:
AvailabilityZone: !Select [0, !GetAZs '']
CidrBlock: !Sub '192.168.32.0/20'
MapPublicIpOnLaunch: true
VpcId: !Sub '${VpcId}'
SubnetAPrivate:
Type: 'AWS::EC2::Subnet'
Properties:
AvailabilityZone: !Select [0, !GetAZs '']
CidrBlock: !Sub '192.168.48.0/20'
VpcId: !Sub '${VpcId}'
SubnetBPrivate:
Type: 'AWS::EC2::Subnet'
Properties:
AvailabilityZone: !Select [1, !GetAZs '']
CidrBlock: !Sub '192.168.64.0/20'
VpcId: !Sub '${VpcId}'
RouteTablePublic:
Type: 'AWS::EC2::RouteTable'
Properties:
VpcId: !Sub '${VpcId}'
RouteTablePrivate:
Type: 'AWS::EC2::RouteTable'
Properties:
VpcId: !Sub '${VpcId}'
RouteTableBPrivate:
Type: 'AWS::EC2::RouteTable'
Properties:
VpcId: !Sub '${VpcId}'
RouteTableAssociationAPublic:
Type: 'AWS::EC2::SubnetRouteTableAssociation'
Properties:
SubnetId: !Ref SubnetAPublic
RouteTableId: !Ref RouteTablePublic
RouteTableAssociationAPrivate:
Type: 'AWS::EC2::SubnetRouteTableAssociation'
Properties:
SubnetId: !Ref SubnetAPrivate
RouteTableId: !Ref RouteTablePrivate
RouteTableAssociationBPrivate:
Type: 'AWS::EC2::SubnetRouteTableAssociation'
Properties:
SubnetId: !Ref SubnetBPrivate
RouteTableId: !Ref RouteTableBPrivate
EIP:
Type: 'AWS::EC2::EIP'
Properties:
Domain: vpc
NatGateway:
Type: 'AWS::EC2::NatGateway'
Properties:
AllocationId: !GetAtt 'EIP.AllocationId'
SubnetId: !Ref SubnetAPublic
RouteTablePublicInternetRoute:
Type: AWS::EC2::Route
Properties:
RouteTableId: !Ref RouteTablePrivate
DestinationCidrBlock: '0.0.0.0/0'
NatGatewayId: !Ref NatGateway
RouteTablePublicInternetRoute2:
Type: AWS::EC2::Route
Properties:
RouteTableId: !Ref RouteTablePublic
DestinationCidrBlock: '0.0.0.0/0'
GatewayId: !Sub '${InternetGatewayId}'
ServerlessSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: SecurityGroup for Serverless Functions
VpcId: !Sub '${VpcId}'
ServerlessSecurityGroupIngress:
Type: AWS::EC2::SecurityGroupIngress
Properties:
GroupId: !Ref ServerlessSecurityGroup
IpProtocol: -1
SourceSecurityGroupId: !Ref ServerlessSecurityGroup
任何想法我做错了什么?
PS:我发现了类似的问题AWS VPC Lambda 函数不断失去互联网访问以及为什么 AWS lambda 函数在 VPC 中有时会超时,有时工作正常?
UPD
添加了路线,现在可以使用
RouteTableBPrivateInternetRoute:
Type: AWS::EC2::Route
Properties:
RouteTableId: !Ref RouteTableBPrivate
DestinationCidrBlock: '0.0.0.0/0'
NatGatewayId: !Ref NatGateway
解决方案
要让在 VPC 内部运行的 AWS Lambda 函数能够访问 VPC 外部的资源(例如 Internet),它必须位于具有 NAT 网关的私有子网中。在您的实例中,私有子网 A 是唯一具有适当配置以允许 Lambda 函数访问 Internet 的子网。因此,您需要编辑 Lambda 函数的配置,使其仅在该子网中运行。
推荐阅读
- spring - Spring Boot - 如何检查连接池中的活动连接数
- c# - 在 Windows 窗体中实现 MediaPlayer 和 MediaTimeline
- python - 字符串列表:获取“类型错误”浮动对象不可下标
- r - 如何通过 bookdown::render_book 构建乳胶 kable?
- subset - 子集缺失值
- maven - 如何将 maven 插件转换为 gradle 插件(maven-surefire-puglin)?
- angular - Angular Ivy strictTemplates true 类型 'boolean | null' 不可分配给类型 'boolean'
- ios - 应用关闭时删除远程推送通知
- javascript - Model.updateOne() 在 Document.save() 之前执行 - mongoose.js
- azure-resource-manager - ARM 模板 - 复杂计算