有没有一种方法可以通过代理在 Docker 容器内访问 Google Cloud SQL?

27

我在Google Compute Engine上运行多个Docker机器(dev,staging),托管Django服务器(这需要访问Google Cloud SQL)。我有多个Google Cloud SQL实例在运行,每个实例都由我的Google Compute Engine实例上各自的Docker机器使用。

目前,我通过将我的Compute Engine IP列入白名单来访问Cloud SQL。但出于显而易见的原因,我不想使用IP,即我不为我的开发机器使用静态IP。

但现在我想使用google_cloud_proxy来获取访问权限。但我该如何做呢! GCP提供了多种访问google Cloud SQL实例的方式。但没有一种适合我的用例:

我有以下选择https://cloud.google.com/sql/docs/mysql/connect-compute-engine; 但是

  1. 它只能使计算引擎访问SQL实例;我必须从我的Docker访问。
  2. 这不支持我在同一计算引擎机器上代理多个SQL实例;如果可能的话,我希望在Docker内部进行此代理。

那么,我该如何在Docker中访问CLoud SQL? 如果Docker compose是更好的开始方式; 对于Kubernetes来说,实施起来有多容易(我在生产中使用Google Container Engine)


一个 Cloud SQL 代理可以代理多个实例。你需要拥有多个代理的原因是什么? - Vadim
我读了一些东西,意识到你说的是对的。所以我的第二个问题现在无效了... 你对Q1有什么想法吗?我如何在单独的Docker内访问这个代理连接? - rrmerugu
我不确定我完全理解这个问题。您可以将代理作为一个单独的Docker镜像运行(https://cloud.google.com/sql/docs/mysql/connect-docker),然后从您的Docker镜像连接到它。 - Vadim
根据您的回答,我可以看出您理解我的问题。在我的问题中,Connect-docker 是指使用 docker-compose。我知道 docker-compose 是一个选项,但我只是在探索它是否是最佳选择。 - rrmerugu
如果您从拥有静态IP的GCE实例连接,您可以选择将这些IP列入白名单,并通过IP直接连接。如果您不想维护IP白名单,那么使用代理docker容器是最佳选择。 - Vadim
是的。由于某些原因,我们决定不使用白名单IP的方法。显然这是我现在能用的选项..谢谢。 - rrmerugu
4个回答

33
我能够通过使用docker-compose在我的本地docker环境中找出如何使用cloudsql-proxy。您需要下载Cloud SQL实例凭据并准备好它们。我将它们保存在项目根目录下的credentials.json中,并将其添加到项目的.gitignore中。
我发现的关键部分是在GCP实例ID后面使用=tcp:0.0.0.0:5432,以便可以转发端口。然后,在您的应用程序中,将主机名从localhost更改为cloudsql-proxy。确保您的应用程序密钥中的其余数据库凭据有效,以便它可以通过由cloudsql-proxy容器提供的本地代理进行连接。
注意:请记住,我正在编写一个tomcat java应用程序,我的docker-compose.yml反映了这一点。

docker-compose.yml:

version: '3'
services:
  cloudsql-proxy:
      container_name: cloudsql-proxy
      image: gcr.io/cloudsql-docker/gce-proxy:1.11
      command: /cloud_sql_proxy --dir=/cloudsql -instances=<YOUR INSTANCE ID HERE>=tcp:0.0.0.0:5432 -credential_file=/secrets/cloudsql/credentials.json
      ports:
        - 5432:5432
      volumes:
        - ./credentials.json:/secrets/cloudsql/credentials.json
      restart: always

  tomcatapp-api:
    container_name: tomcatapp-api
    build: .
    volumes:
      - ./build/libs:/usr/local/tomcat/webapps
    ports:
      - 8080:8080
      - 8000:8000
    env_file:
      - ./secrets.env
    restart: always

2
有趣,谢谢Dan,我们采用了类似的方法 :) 感谢您发布您的答案。 - rrmerugu
1
我想通过这个docker-compose.yml在GCE上运行。但是,我的应用程序无法连接到cloudsql-proxy。它返回gaierror:[Errno -2]名称或服务未知。你知道如何解决吗? 3x - northtree
我遇到了这个错误:gcloud不在路径中,-instances和-projects为空 - Zaffer
我在云shell上运行docker compose,但是出现了以下错误。dockerpycreds.errors.StoreError:凭据存储docker-credential-gcloud退出并显示“”。 - vikrant rana
抱歉,答案错误。使用cloudsql-proxy而不是localhost是不可用的。不过,其余部分还是有帮助的。 - Nathan McKaskle
显示剩余4条评论

3

对于Mac OS用户,您可以使用以下内容作为POSTGRES_HOST:

host.docker.internal

喜欢

DATABASES = {
    "default": {
        "ENGINE": "django.db.backends.postgresql",
        "NAME": "<DB-NAME>",
        "HOST": "host.docker.internal",
        "PORT": "<YOUR-PORT>",
        "USER": "<DB-USER>",
        "PASSWORD": "<DB-USER-PASSWORD>",
    },
}

您的 localhost 将会被转发到容器中。


1
这正是我所需要的。将 127.0.0.1 替换为 host.docker.internal,使我的 Web 应用程序能够通过容器工作。 - sq89

2
使用Cloud SQL Proxy >= 2.0,接受的答案对于入门非常有帮助,但我们在从另一个容器连接到代理时仍然遇到了很多挑战。我们能够找到的最好解释来自这篇博文:https://towardsdatascience.com/how-to-connect-to-gcp-cloud-sql-with-cloud-sql-auth-proxy-in-docker-99bdf810c498 我们最终的解决方案如下(通过SQL代理连接到云SQL的Streamlit仪表板):
services:
  cloudsql-proxy:
    container_name: cloudsql-proxy
    image: gcr.io/cloud-sql-connectors/cloud-sql-proxy:2.5.0
    command: <INSTANCE_ID> --credentials-file=/secrets/cloudsql/credentials.json --address 0.0.0.0 --port 5432
    networks:
      - dashboard
    ports:
      - 127.0.0.1:5432:5432
    volumes:
      - ./dashboard/credentials.json:/secrets/cloudsql/credentials.json

  dashboard:
    build: ./dashboard/
    working_dir: /dashboard/
    environment:
      - "DASHBOARD_DB_HOST=cloudsql-proxy"
      - "DASHBOARD_DB_NAME=$DASHBOARD_DB_NAME"
      - "DASHBOARD_DB_USER=$DASHBOARD_DB_USER"
      - "DASHBOARD_DB_PASSWORD=$DASHBOARD_DB_PASSWORD"
    networks:
      - dashboard
    ports:
      - "8051:8051"
    depends_on:
      - "cloudsql-proxy"
networks:
  dashboard:
    name: dashboard
    driver: bridge

希望这对于那些在2023年及以后来到这个问题的人有所帮助。

0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接