配置VPC静态IP及all-traffic出口后,App Engine无法连接跨项目Cloud SQL
针对你的App Engine标准环境Java11服务既要用指定静态IP调用第三方API,又要连接跨项目Cloud SQL的场景,提供以下三种方案:
方案一:修复VPC对等连接,通过私有IP访问Cloud SQL
当设置egress_setting: all-traffic时,所有流量都会通过VPC访问连接器路由,此时需确保跨项目VPC的路由和防火墙配置正确,才能通过私有IP连接Cloud SQL:
确认VPC对等连接状态
- 项目A的Cloud SQL所在VPC与项目B的VPC必须建立双向对等连接,双方都已完成对等连接的接受操作
- 在项目B的VPC连接器所在子网的路由表中,添加指向项目A Cloud SQL私有IP的路由(目标为
<cloudSql-PrivateIp>/32,下一跳为VPC对等连接) - 在项目A的Cloud SQL所在子网的路由表中,添加指向项目B VPC连接器CIDR段的路由(目标为连接器的IP范围,下一跳为VPC对等连接)
配置Cloud SQL防火墙规则
在项目A的Cloud SQL实例中,添加允许来自项目B VPC连接器CIDR段的流量访问3306端口的防火墙规则确认Spring数据源配置
确保私有IP连接串的ipTypes=PRIVATE参数正确生效,Spring配置示例:spring: datasource: url: jdbc:mysql://<cloudSql-PrivateIp>:3306/_operations?user=<user>&password=<pass>&ipTypes=PRIVATE driver-class-name: com.mysql.cj.jdbc.Driver
方案二:适配SocketFactory以支持VPC连接器流量
如果习惯使用Cloud SQL SocketFactory方式连接,需调整连接参数并配置权限:
修正SocketFactory连接串
补充useJdbcSocketFactory=true和超时参数,同时确保cloudSqlInstance的格式正确(项目ID、地域、实例名用:分隔):spring: datasource: url: jdbc:mysql://_operations?cloudSqlInstance=<projectA-id>:northamerica-northeast1:<sql-instanceName>&socketFactory=com.google.cloud.sql.mysql.SocketFactory&useJdbcSocketFactory=true&socketFactoryConnectTimeout=30000&user=<user>&password=<pass>配置跨项目IAM权限
在项目A的IAM控制台中,给项目B的App Engine服务账号授予roles/cloudsql.client角色,确保其拥有访问Cloud SQL的权限启用私有服务访问
确认项目B的VPC已启用私有服务访问,并且Cloud SQL的私有服务地址范围已被纳入VPC对等连接的路由规则中
方案三:拆分流量路由,实现双需求
如果以上方案仍无法解决问题,可通过中转服务拆分流量:
调整App Engine的VPC配置
将egress_setting改为private-ranges-only,此时只有私有IP范围的流量走VPC连接器,公网流量默认走App Engine的出站通道(确保Cloud SQL连接正常)部署Cloud Run中转服务
- 在项目B中创建一个Cloud Run服务,配置VPC访问连接器和绑定静态IP的Cloud NAT
- 该Cloud Run服务负责转发所有第三方API的请求,App Engine服务通过私有IP调用此Cloud Run服务
- 这样第三方API会收到Cloud NAT的指定静态IP,而Cloud SQL连接则不受影响
内容的提问来源于stack exchange,提问作者StatCap

