如何通过TCP上的MySQL代理Docker容器连接到Cloud SQL(第2代)

问题描述 投票:1回答:3

在Mac OS X上运行,我一直在尝试使用these directions通过代理连接到Cloud SQL实例。一旦安装了MySQL客户端,gce-proxy容器,并在Google Cloud Platform中创建了一个服务帐户,您就可以开始运行文档中指定的这两个命令:

docker run -d -v /cloudsql:/cloudsql \
  -v [LOCAL_CERTIFICATE_FILE_PATH]:[LOCAL_CERTIFICATE_FILE_PATH] \
  b.gcr.io/cloudsql-docker/gce-proxy /cloud_sql_proxy \
  -instances=[INSTANCE_CONNECTION_NAME]=tcp:3306 -credential_file=[CLOUD_KEY_FILE_PATH]

mysql -h127.0.0.1 -uroot -p

首先,我不明白这应该如何工作,因为容器没有暴露端口。所以不出所料,当我尝试连接时,我从MySQL客户端收到以下错误:

ERROR 2003 (HY000): Can't connect to MySQL server on '127.0.0.1' (61)

但是如果我通过将-p 3306:3306添加到docker run命令来暴露端口,我仍然无法连接。相反,我从MySQL客户端收到以下错误:

ERROR 2013 (HY000): Lost connection to MySQL server at 'reading initial communication packet', system error: 0

我已经成功连接到我的docker主机上运行cloud_sql_proxy的代理,遵循that documentation,所以我相信我的凭证文件和我的mysql客户端配置正确。容器的日志未声明已尝试任何连接。通过docker连接到普通的mysql容器没问题。我在这里错过了什么?

google-cloud-sql
3个回答
1
投票

它看起来确实在文档中有一些遗漏。

1)正如您所指出的,您需要从容器中公开端口。您需要确保仅通过指定-p 127.0.0.1:3306:3306将其公开给本地计算机。

2)然后在运行容器时,您需要通过指定-instances=[INSTANCE_CONNECTION_NAME]=tcp:0.0.0.0:3306来暴露容器外的端口


0
投票

我试过@Vadim的建议,基本上是这样的:

docker run -d -v /cloudsql:/cloudsql \
  -p 127.0.0.1:3306:3306 \ 
  -v [LOCAL_CERTIFICATE_FILE_PATH]:[LOCAL_CERTIFICATE_FILE_PATH] \
  b.gcr.io/cloudsql-docker/gce-proxy /cloud_sql_proxy \
  -instances=[INSTANCE_CONNECTION_NAME]=tcp:0.0.0.0:3306 -credential_file=[CLOUD_KEY_FILE_PATH]

我仍然无法获得连接,因为我仍然遇到此错误:

ERROR 2013 (HY000): Lost connection to MySQL server at 'reading initial communication packet', system error: 0

但是,docker容器的日志显示了一个连接,如下所示:

2016/10/16 07:52:32 New connection for "[INSTANCE_CONNECTION_NAME]"
2016/10/16 07:52:32 couldn't connect to "[INSTANCE_CONNECTION_NAME]": Post https://www.googleapis.com/sql/v1beta4/projects/[PROJECT_NAME]/instances/[CLOUD_SQL_INSTANCE_NAME]/createEphemeral?alt=json: oauth2: cannot fetch token: Post https://accounts.google.com/o/oauth2/token: x509: failed to load system roots and no roots provided

所以现在它似乎正在获得流量,但它找不到SSL容器的证书。我曾使用OpenSSL's cert.pem export of my certificates并将其安装到docker容器中的相同位置。有意义的是,[LOCAL_CERTIFICATE_FILE_PATH]:[LOCAL_CERTIFICATE_FILE_PATH]的任意映射并没有帮助代理找出证书的位置。所以我使用了this Kubernetes setup guide的线索并将装载量改为-v [LOCAL_CERTIFICATE_FILE_PATH]:/etc/ssl/certs。幸运的是,这很有效。

TL; DR - 这是使Docker Container在TCP上运行的最终语法:

docker run -d \
    -p 127.0.0.1:3306:3306 \
    -v [SERVICE_ACCOUNT_PRIVATE_KEY_DIRECTORY]:[SERVICE_ACCOUNT_PRIVATE_KEY_DIRECTORY] \
    -v [LOCAL_CERTIFICATE_DIRECTORY]:/etc/ssl/certs \
    b.gcr.io/cloudsql-docker/gce-proxy /cloud_sql_proxy \
    -instances=[INSTANCE_CONNECTION_NAME]=tcp:0.0.0.0:3306 \
    -credential_file=[SERVICE_ACCOUNT_PRIVATE_KEY_JSON_FILE]

0
投票

通过使用docker-compose,我能够弄清楚如何在我的本地docker环境中使用cloudsql-proxy。您需要下载Cloud SQL实例凭据并准备好它们。我将它们作为credentials.json保存在我的项目根目录中,并将其添加到项目中的.gitignore中。

我找到的关键部分是在GCP实例ID之后使用=tcp:0.0.0.0:5432,以便可以转发端口。然后,在您的应用程序中,使用cloudsql-proxy而不是localhost作为主机名。确保其余的db信誉在应用程序机密中有效,以便它可以通过cloudsql-proxy容器提供的本地代理进行连接。

注意:请记住我正在编写一个tomcat java应用程序,而我的docker-compose.yml反映了这一点。

码头工人,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
© www.soinside.com 2019 - 2024. All rights reserved.