5

我正在尝试使用 cloudsql-proxy docker 容器将应用程序(docker 容器)连接到 Google Cloud SQL 数据库。因此,我使用以下 cloudsql-proxy 容器创建了一个 docker-compose 文件:(XXX 替换为我的云 sql 实例 ID)

version: "3"

volumes:
  sqlproxy:

services:

  cloudsql-proxy:
    container_name: cloudsql-proxy
    image: gcr.io/cloudsql-docker/gce-proxy:1.11
    command: /cloud_sql_proxy --dir=/cloudsql -instances=XXX=tcp:0.0.0.0:3306 -credential_file=/config/credentials.json
    ports:
      - "3306:3306"
    volumes:
      - /usr/share/service-accounts/cloudsql-client.json:/config/credentials.json
      - sqlproxy:/cloudsql
      - /etc/ssl/certs:/etc/ssl/certs
    restart: always

每当我尝试从在同一台机器上运行的另一个容器中连接到 cloudsql mysql 数据库时,例如 docker-compose 文件中的第二个容器,我都会收到错误消息

“错误 2003 (HY000): 无法连接到 '127.0.0.1' 上的 MySQL 服务器 (111 "连接被拒绝")"

我尝试使用三种不同的方法连接到 cloudsql-proxy,但仍然出现相同的错误。所有容器(云 sql 代理和要连接的测试容器)都在一个谷歌计算引擎实例上:

a) mysql-client: mysql --host 127.0.0.1

b) jdbc url: jdbc:mysql://127.0.0.1:3306/test

c) jdbc url: jdbc:mysql://cloudsql-proxy:3306/test

在我的 gc 防火墙中,我为 0.0.0.0/0 打开端口 3306 用于测试目的,停止并启动云 sql 实例等,但错误仍然存​​在。代理容器的日志是OK的:

2018/05/02 16:02:03 using credential file for authentication; email=cloudsql-client@xxx.iam.gserviceaccount.com
2018/05/02 16:02:03 Listening on 0.0.0.0:3306 for x:x:x
2018/05/02 16:02:03 Ready for new connections

我的方法有什么根本性的问题还是我错过了什么?这可能是码头工人的问题吗?我可以从其他容器 ping 代理容器。

4

1 回答 1

1

这不是 Docker 问题,更改 Google Cloud 防火墙将允许 Internet 上的机器连接到实例上的端口 3306。

Figure 1
+--------------------------------------------+
| GCE instance                               |
|                                            |
| +-----------------+    +-----------------+ |
| |MySQL   127.0.0.1|    |Test    127.0.0.1| |
| |                 |    |                 | |
| +------3306-------+    +-----------------+ |
|         |                                  |
|         |                                  |
+--------3306--------------------------------+

第一个图显示容器Test无法到达容器 MySQL,因为它只知道自己(环回网络上的 127.0.0.1)。您提到的错误发生是因为 MySQL 未在容器的端口 3306 上运行Test

访问容器的一个选项MySQLTest添加一个覆盖网络

# I recommend using the latest version
version: "3.6"

volumes:
  sqlproxy:

networks:
  mysql_net:
    driver: overlay

services:
  cloudsql-proxy:
    ...
    # This is not required
    # ports:
    #   - "3306:3306"
    ...
    networks:
      mysql_net:
        aliases:
          database

  test-container:
    # Reach the container MySQL using the alias
    command: mysql -u <user> -p --host database
    ...
    networks:
      mysql_net:

如第二张图所示,这两个容器现在共享一个公共子网。容器Test应该能够到达容器MySQL

Figure 2
+-----------------------------------------------------------+
| GCE instance                                              |
|                                                           |
| +-------------------------------+   +-------------------+ |
|  MySQL     127.0.0.1            |   |Test     127.0.0.1 | |
| |          10.0.0.3/8 (database)|   |         10.0.0.4/8| |
| |                               |   |                   | |
| |                               |   |                   | |
| +------------3306---------------+   +-------------------+ |
|                                                           |
+-----------------------------------------------------------+

由于容器的 IP 未知,您必须使用别名(如域名)。在示例中,别名是database。第二个图假设覆盖网络mysql_net具有掩码255.0.0.0和容器的给定 IP,MySQL分别Test10.0.0.310.0.0.4

于 2018-06-29T08:34:21.680 回答