Google Cloud Run连接Cloud SQL报psycopg2超时错误如何解决
问题核心原因&原理说明
- 初始公网连接超时的根因:Cloud Run的出口IP属于Google的动态共享IP池,没有固定值,无法全部加入Cloud SQL的公网IP白名单,所以直接走公网TCP连接必然会被拦截,触发超时错误。
- Cloud Run对接Cloud SQL的Unix Socket机制原理:你在部署命令中添加
--add-cloudsql-instances参数后,Cloud Run会自动在容器环境的/cloudsql/目录下挂载对应Cloud SQL实例的Unix套接字文件,该通道走Google内部私有网络,不需要走公网,也不需要配置IP白名单,是同项目内云服务访问Cloud SQL的官方推荐方案,本身传输已经加密,安全性有保障。
疑问解答
1. 「仅允许SSL连接」是不是连接失败的原因?
不是。本地能正常连接是因为你本地的公网IP已经加入了Cloud SQL的授权列表,同时你携带了合法的SSL证书,符合访问规则;Cloud Run环境之前失败是因为走公网连接时IP不在白名单内,和SSL规则本身无关。
2. 能不能沿用原有SSL证书连接代码?
可以,有两种实现方案:
- 方案1:完全不改动代码,额外配置网络
将Cloud Run服务部署到VPC网络中,搭配Cloud NAT绑定静态公网IP,之后把该静态IP加入Cloud SQL的公网授权网络列表即可。该方案不需要修改任何业务代码,但需要额外配置VPC、Cloud NAT资源,会产生额外成本,架构复杂度更高。 - 方案2:仅修改连接地址,保留SSL逻辑
Unix Socket连接也支持SSL认证,你只需要把连接参数中的host替换为Unix套接字路径(格式为/cloudsql/[项目ID]:[区域]:[实例名]),删除port参数即可,其他SSL相关配置完全可以保留,原有代码不需要做大的调整。修改后的连接代码示例:
该方案改造成本极低,同时保留了你原有SSL证书校验的逻辑,也不需要额外配置网络资源,更推荐使用。db = psycopg2.connect( database=self.database, user=self.user, password=self.password, host="/cloudsql/你的Cloud SQL连接名", sslmode=self.sslmode, sslrootcert=rev_map.get(self.sslrootcert), sslcert=rev_map.get(self.sslcert), sslkey=rev_map.get(self.sslkey) )
3. 是不是必须用Unix Socket连接?
不是必须,只是Unix Socket是成本最低、配置最简单、安全性最高的方案。如果你不想用Unix Socket,就可以选择上面提到的VPC+Cloud NAT+静态IP的方案走公网TCP连接。
内容的提问来源于stack exchange,提问作者Jed
相关产品推荐
相关产品推荐

