无NAT网关的私有隔离子网中Lambda连接RDS超时及可行性咨询
问题:Lambda在纯私有隔离子网中连接同子网RDS超时排查
请问是否可以在同一VPC的纯私有隔离子网中,让Lambda与处于相同子网的RDS实现连接?为节省NAT网关每小时0.045美分的成本,我想使用RDS免费层进行开发,此前配置带NAT网关的公网子网+有出口的私有子网是可行的,但想确认纯隔离子网无NAT网关的方案是否可行。
目前我的配置情况:
- 所有子网关联的路由表包含VPC CIDR目标,指向local
- NACL已设置允许所有出入流量(也曾尝试指定子网CIDR)
- Lambda已正确关联VPC和子网
- RDS未设置为公开访问
- RDS与Lambda处于同一VPC和安全组(虽知不适用于生产环境,已尝试安全组自引用、允许所有流量、通过控制台让RDS关联Lambda安全组等)
- Lambda层无问题,超时设置也足够
以下是VPC和安全组的CDK代码,Lambda函数已按此关联配置,目前连接一直超时,恳请帮助排查。
# Create VPC non NAT Gateways & only private isolated subnets vpc = ec2.Vpc( self, "VPCNoNat", cidr="10.0.0.0/24", nat_gateways=0, # No NAT gateways subnet_configuration=[ ec2.SubnetConfiguration( name="PrivateSubnetNoNat", subnet_type=ec2.SubnetType.PRIVATE_ISOLATED, cidr_mask=26, ), ], ) # Create a Security Group for the RDS Cluster and Lambda security_group = ec2.SecurityGroup( self, "cdk-securitygroupNoNat", vpc=vpc, security_group_name="cdk-security-group-no-nat", ) # Allow traffic on port 5432 from within the VPC for RDS security_group.add_ingress_rule(ec2.Peer.ipv4(vpc.vpc_cidr_block), ec2.Port.tcp(5432)) # Create a subnet group subnet_group = rds.SubnetGroup( self, "cdkSubnetGroupNoNat", description="Subnet group for cdk no nat", vpc=vpc, vpc_subnets=ec2.SubnetSelection(subnet_type=ec2.SubnetType.PRIVATE_ISOLATED), ) db_instance = rds.DatabaseInstance( self, "PostgresInstance1NoNat", engine=rds.DatabaseInstanceEngine.POSTGRES, instance_type=ec2.InstanceType.of( ec2.InstanceClass.BURSTABLE3, ec2.InstanceSize.MICRO ), credentials=rds.Credentials.from_generated_secret("postgres"), vpc=vpc, security_groups=[security_group], subnet_group=subnet_group, publicly_accessible=False, ) # Create a Lambda function def create_lambda_function( stack, lambda_id, handler, layers, vpc, security_group, role, runtime=_lambda.Runtime.PYTHON_3_9, timeout=Duration.seconds(15), extra_env_vars=None, ): # Default environment variables default_env_vars = { "SECRET_ARN": db_instance.secret.secret_arn, "DB_HOST": db_instance.db_instance_endpoint_address, } # Merge extra environment variables with the default ones environment_vars = {**default_env_vars, **(extra_env_vars or {})} return _lambda.Function( stack, lambda_id, handler=handler, runtime=runtime, environment=environment_vars, code=_lambda.Code.from_asset(handler), role=role, layers=layers, vpc=vpc, security_groups=[security_group], vpc_subnets=ec2.SubnetSelection(subnet_type=ec2.SubnetType.PRIVATE_ISOLATED), timeout=timeout, )
排查方案与结论
纯私有隔离子网(无NAT网关)下,同VPC同子网的Lambda和RDS完全可以正常连接,你的超时问题属于配置细节遗漏,以下是具体排查修复点:
1. 补充Lambda角色的VPC访问权限
Lambda关联VPC时,必须具备管理弹性网络接口(ENI)的权限,否则无法在子网内创建通信所需的ENI:
- 检查Lambda角色是否附加
AWSLambdaVPCAccessExecutionRole托管策略,该策略包含ec2:CreateNetworkInterface、ec2:DescribeNetworkInterfaces、ec2:DeleteNetworkInterface等必要权限。
2. 确认VPC DNS配置
Lambda在私有子网中无法访问公网DNS,若VPC DNS功能未开启,会导致RDS端点解析失败:
- 显式指定VPC的DNS配置(CDK默认开启,但可手动确认):
vpc = ec2.Vpc( self, "VPCNoNat", cidr="10.0.0.0/24", nat_gateways=0, enable_dns_support=True, # 开启VPC DNS解析 enable_dns_hostnames=True, # 允许实例获取私有DNS名称 subnet_configuration=[ ec2.SubnetConfiguration( name="PrivateSubnetNoNat", subnet_type=ec2.SubnetType.PRIVATE_ISOLATED, cidr_mask=26, ), ], )
3. 完善安全组出方向规则
虽然安全组默认允许所有出方向流量,但如果有过自定义修改,可能限制了Lambda到RDS的出流量:
- 添加显式的出方向规则,允许访问RDS端口:
# 允许安全组内实例访问VPC内的5432端口 security_group.add_egress_rule(ec2.Peer.ipv4(vpc.vpc_cidr_block), ec2.Port.tcp(5432))
4. 检查Lambda代码连接细节
- 确认
DB_HOST环境变量正确获取了RDS端点地址,无拼写错误; - 验证从Secrets Manager获取的数据库用户名/密码是否正确;
- 临时延长Lambda超时时间至30秒,首次连接可能需要更长初始化时间。
5. 统一子网部署范围
确保RDS子网组和Lambda关联的子网完全一致,避免跨子网部署导致的通信延迟或限制。
内容的提问来源于stack exchange,提问作者makisupa488
相关产品推荐
相关产品推荐

