AWS Lambda通过带EIP的NAT Gateway连接SQS约12小时后断开
根据你的描述,Lambda初期能正常访问RDS、SQS并推送SNS,但12小时后出现的超时和移除NAT Gateway的现象完全一致,说明核心问题大概率出在NAT Gateway的可用性或关联的路由配置上。结合你提供的CloudFormation模板,我整理了几个关键排查点和修复方案:
1. 修正NAT路由的依赖关系
先看你模板里的NATRoute配置:
NATRoute: Type: AWS::EC2::Route DependsOn: - RouteTableLambda - InternetGateway Properties: RouteTableId: Ref: RouteTableLambda DestinationCidrBlock: '0.0.0.0/0' NatGatewayId: Ref: NATGateway
这里的DependsOn列表漏掉了NATGateway——这意味着路由可能在NAT Gateway完全就绪前就被创建。虽然AWS会处理部分隐式依赖,但显式指定依赖NAT Gateway能确保路由只有在NAT Gateway可用时才生效,避免潜在的状态不一致或延迟问题。修改后如下:
NATRoute: Type: AWS::EC2::Route DependsOn: - RouteTableLambda - NATGateway # 新增这个依赖项 Properties: RouteTableId: Ref: RouteTableLambda DestinationCidrBlock: '0.0.0.0/0' NatGatewayId: Ref: NATGateway
2. 检查NAT Gateway的状态和EIP关联
12小时后突发故障,最常见的原因是NAT Gateway状态异常或EIP被意外释放:
- 登录AWS控制台,导航到VPC -> NAT Gateways,查看目标NAT Gateway的状态:如果显示
failed,先检查关联的EIP是否还存在(去EC2 -> Elastic IPs页面核对); - 确认NAT Gateway所在的
SubnetAPublic路由表(RouteTableEC2Bastion)是否保留了0.0.0.0/0指向IGW的路由——你的模板里InternetRoute已经配置了这部分,大概率没问题,但还是要确认没有被手动修改; - 查看CloudFormation栈的事件日志,排查是否有EIP被释放的记录,排除自动化工具或脚本误操作的可能。
3. 理解为什么RDS和SQS会同时失效
你可能会疑惑:RDS和Lambda在同一个私网子网,理论上不需要NAT Gateway就能访问,为什么也会超时?
- SQS访问:Lambda在VPC内访问SQS属于公网AWS服务调用,必须经过NAT Gateway(除非配置了SQS VPC端点),所以NAT Gateway失效会直接导致SQS访问超时;
- RDS访问:虽然是VPC内私网访问,但Lambda需要通过AWS元数据服务获取IAM角色的临时凭证才能连接RDS——元数据服务的访问依赖NAT Gateway(如果Lambda没有配置VPC端点的话),所以NAT Gateway失效后,Lambda无法获取凭证,进而无法连接RDS。
4. 长期优化:配置SQS VPC端点
如果你的Lambda只需要访问SQS和RDS,不需要访问其他公网资源,可以配置SQS的VPC端点,彻底绕开NAT Gateway的依赖:
SQSVpcEndpoint: Type: AWS::EC2::VPCEndpoint Properties: ServiceName: com.amazonaws.${self:provider.region}.sqs VpcId: Ref: ServerlessVPC SubnetIds: - Ref: SubnetBPrivate - Ref: SubnetCPrivate SecurityGroupIds: - Ref: ServerlessSecurityGroup PrivateDnsEnabled: true
开启PrivateDnsEnabled后,Lambda可以直接用标准SQS域名(比如sqs.us-east-1.amazonaws.com)访问,不需要修改任何代码。
5. 快速验证方案
临时手动检查Lambda所在私网子网的路由表:确认0.0.0.0/0路由确实指向正常运行的NAT Gateway。如果路由没问题,重启NAT Gateway(删除后重新创建),观察Lambda是否恢复正常——如果恢复,说明是NAT Gateway本身的状态异常。
内容的提问来源于stack exchange,提问作者Mickel

