【问题标题】:AWS Lambda in VPC sometimes doesn't have internet accessVPC 中的 AWS Lambda 有时无法访问 Internet
【发布时间】:2018-12-25 01:48:20
【问题描述】:

我有部署到 VPC 的 Lambda。

这个部署有下一个配置:

  • VPC (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 无法访问互联网。第三方服务正常。

更奇怪的是,Lambda 获得的 IP 是 127.0.0.1、169.254.76.13、169.254.79.1,而不是来自子网(192.168.48.0/20 和 192.168.64.0/20)的 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

任何想法我做错了什么?

P.S.:我发现了类似的问题AWS VPC Lambda Function keeps losing internet accessWhy AWS lambda functions In a VPC sometimes timeout and sometimes work fine?

UPD

添加了路线,现在可以使用了

  RouteTableBPrivateInternetRoute:
    Type: AWS::EC2::Route
      Properties:
        RouteTableId: !Ref RouteTableBPrivate
        DestinationCidrBlock: '0.0.0.0/0'
        NatGatewayId: !Ref NatGateway

【问题讨论】:

    标签: amazon-web-services aws-lambda amazon-cloudformation


    【解决方案1】:

    要让在 VPC 内部运行的 AWS Lambda 函数能够访问 VPC 外部的资源(例如 Internet),它必须位于具有 NAT 网关的私有子网中。在您的实例中,私有子网 A 是唯一具有适当配置以允许 Lambda 函数访问 Internet 的子网。因此,您需要编辑 Lambda 函数的配置,使其仅在该子网中运行。

    【讨论】:

    • 据我所知,Lambda 要求每个可用区至少有一个子网docs.aws.amazon.com/lambda/latest/dg/…
    • 我还有来自私有子网 A (0.0.0.0/0 -> NAT) 的路由,还不够吗?
    • 从私有子网 A 到 NAT 的路由足以让 Lambda 函数在私有子网 A 中工作。您必须在希望 Lambda 函数访问 Internet 的每个子网中拥有相同的路由。
    • 如果您阅读了您链接的文档页面,它清楚地表明只有具有 NAT 网关路由的私有 VPC 子网才能为 Lambda 函数提供 Internet 访问权限。它还明确表示建议“每个可用区中有一个子网”。不知道你是如何从“推荐”中得到“要求”的
    【解决方案2】:

    您是否已选择公有子网作为 lambda 将在其中运行的子网之一?

    只有在私有子网中运行的 lambda 才能访问互联网,因此请转到 AWS 控制台上的 lambda 页面,取消选择公共子网并保存,这样问题就不会再次发生了。

    【讨论】:

      猜你喜欢
      • 2019-10-28
      • 1970-01-01
      • 2019-09-18
      • 2018-10-20
      • 2019-12-06
      • 2016-05-27
      • 2017-02-18
      • 2017-02-08
      相关资源
      最近更新 更多