同VPC不同私有子网中Lambda调用Elastic Beanstalk Flask API问题
无法在Lambda中调用Elastic Beanstalk自动生成的API链接(连接超时)
环境与配置
基础架构
- Python Flask API通过Elastic Beanstalk部署在2个私有子网,关联带NAT Gateway的路由表,出入站权限已配置
- Lambda函数部署在同一VPC的另外2个私有子网,关联同一NAT Gateway
安全组规则
- Python API安全组:
- 出站:允许所有
0.0.0.0/0流量 - 入站:允许来自Lambda安全组的80、443端口流量
- 出站:允许所有
- Lambda安全组:
- 出站:允许所有
0.0.0.0/0流量 - 入站:允许来自Python API安全组的80、443端口(测试添加),以及Secrets Manager VPC端点安全组的流量
- 出站:允许所有
问题与报错
核心问题:无负载均衡的情况下,能否在Lambda中用requests模块直接调用Elastic Beanstalk自动生成的HTTP API链接?
出现的超时错误:
HTTPConnectionPool(host='MY-URL.elasticbeanstalk.com', port=80): Max retries exceeded with url: /APIModuleNameData (Caused by ConnectTimeoutError(<urllib3.connection.HTTPConnection object at 0x7f6c2e09eba0>))
已完成的排查:
- 确认Lambda出站连接正常
- 尝试过开放Python API安全组全部出入站权限
- 登录EC2验证了NAT Gateway的访问性
原因与解决方案
核心原因
Elastic Beanstalk自动生成的公共域名(MY-URL.elasticbeanstalk.com)默认指向公共负载均衡,但你没有配置负载均衡,且API实例部署在私有子网——这个公共域名无法解析到私有子网内的EC2实例,自然无法建立连接,导致超时。
可行的解决方法
直接使用EC2实例的私有IP/内网DNS调用
因为Lambda和API实例在同一VPC,直接用实例的私有IP或内网DNS名称发起请求即可,示例代码:import requests # 替换为你的API实例私有IP或内网DNS response = requests.get("http://10.0.1.100/APIModuleNameData")你的安全组规则已经允许Lambda安全组访问API的80/443端口,无需额外调整。
配置VPC私有DNS(可选)
如果需要用域名访问,可在Route 53创建私有托管区域,将自定义域名解析到API实例的私有IP,这样Lambda就能通过私有域名访问API,无需依赖公共域名。不要依赖EB的公共域名(重要)
EB的公共域名是为带公共负载均衡的部署场景设计的,当实例在私有子网且无负载均衡时,这个域名完全无法指向你的私有实例,必须放弃使用它。
额外排查点
- 确认Lambda所在子网的路由表没有限制私有子网间的通信(同一VPC内默认允许私有IP段的流量,除非有自定义路由规则拦截)
- 检查API安全组的入站规则,确保Lambda安全组的ID配置正确,没有写错或选错安全组
内容的提问来源于stack exchange,提问作者Jatin Garg
相关产品推荐
相关产品推荐

