【发布时间】:2021-10-21 00:03:20
【问题描述】:
我有一个 (Linux) Docker 映像,当我在本地计算机上将它作为容器运行时,它成功连接到 Google 的 Cloud SQL。当我将该映像移动到 Google 的容器注册表并将其放入 Google Cloud Run API 时,我收到以下错误:
psycopg2.OperationalError: could not connect to server: Connection timed out Is the server running on host "xxx.xxx.xxx.xxx" and accepting TCP/IP connections on port 5432?
at connect (/env/local/lib/python3.7/site-packages/psycopg2/__init__.py:130)
...
我假设这是因为我将 Cloud SQL 实例配置为具有“授权网络”列表的“公共 IP”。见文档here
问题在于,根据我部署 Cloud Run API 的方式/时间,IP 地址可能会随着时间而改变。如何授权从属于我的项目(而非其他项目)的其他 Google Cloud 服务(特别是 Google Cloud Run)访问 Cloud SQL 实例?
更新
根据 John Hanley 的评论(请参阅此 URL),我可以通过将以下内容添加到我的 gcloud beta run deploy 命令来更新我的部署命令:
--add-cloudsql-instances=[CLOUD_SQL_CONNECTION_NAME] --service-account=service-account@my-project.iam.gserviceaccount.com
SQL 连接仍然无法正常工作。我想我已经完成了这个网页上我能想到的所有事情,除了重写我的 SQL 连接 python 代码。是否需要以本页所示的 unix-socket 格式编写连接?
我已经编写了使用 SSL 客户端证书的代码。这是我用于连接的类中的 2 种方法:
def get_db_connection(self):
file_map = {os.path.abspath(f'{TEMP_PATH}/sslrootcert.pem'): self.sslrootcert,
os.path.abspath(f'{TEMP_PATH}/sslcert.pem'): self.sslcert,
os.path.abspath(f'{TEMP_PATH}/sslkey.pem'): self.sslkey}
rev_map = {v: k for k, v in file_map.items()}
db = None
try:
for path, obj in file_map.items():
with open(path, 'w') as f:
if isinstance(obj, bytes):
f.write(obj.decode('utf-8'))
else:
f.write(str(obj))
os.chmod(path, stat.S_IRWXU)
db = psycopg2.connect(database=self.database, user=self.user, password=self.password, host=self.host,
port=self.port, sslmode=self.sslmode, sslrootcert=rev_map.get(self.sslrootcert),
sslcert=rev_map.get(self.sslcert), sslkey=rev_map.get(self.sslkey))
finally:
for path in file_map.keys():
if os.path.isfile(path):
os.remove(path)
return db
@contextlib.contextmanager
def db_connect(self):
db = self.get_db_connection()
cur = db.cursor()
try:
yield (db, cur)
finally:
db.close()
更新 2
我仍在努力尝试所有建议的方法,但我意识到我的 Cloud SQL 数据库设置为“仅允许 SSL 连接”:
这可能是连接在 Cloud Run 中运行时失败但在我的本地计算机上成功(在 Docker 容器中或在 Docker 容器中)的原因吗?如果是这样,应如何更改 Cloud Run 设置以解决此问题?
最终更新
使用基于 Unix Socket 的连接(来自here)允许连接开始工作。为什么从 Google Cloud Run 到 Google Cloud SQL 的连接需要 Unix Socket 连接?有没有办法让它与我上面的 SSL 证书方法/代码一起使用?
【问题讨论】:
-
Google Cloud Run 提供 Cloud SQL Auth Proxy 支持。这在带有示例的文档中进行了介绍。 cloud.google.com/sql/docs/mysql/connect-run
-
John Hanley,感谢您将我指向此文档。我在谷歌搜索这个问题时没有找到这个。它帮助我解决了我在上述问题中更新的 2 个问题。
标签: ssl psycopg2 google-cloud-sql google-cloud-run unix-socket