为什么 mysql-client 不能通过 docker-转发的 tcp 端口连接到 GCP cloud_sql_proxy?
Why won't mysql-client connect to the GCP cloud_sql_proxy via a docker-forwarded tcp port?
要点
我有一个应用程序想要通过 tcp 端口连接到 mysql 数据库。我正在构建一个 docker 容器,该容器暂存云 sql 实例以供其连接(数据库包含从其他地方导入的测试用例)。我希望能够从 docker 容器内部转发 mysql 端口并从容器外部进行连接,但出现错误。
我试过的
容器中的数据库,这有效
当我在本地容器中有一个数据库时,我可以这样连接:
# run in background, listening on port 13306
❯ docker run -p 13306:3306 -e MYSQL_ROOT_PASSWORD=test -d percona:5.7.26-centos
9c25...
❯ mysql -h127.0.0.1 -P13306 -uroot -ptest
mysql> --connection successful
容器中的代理(从外部连接),这不起作用
但是当我在本地容器中有 cloud_sql_proxy 时,我得到这个错误:
# run in background, listening on port 13306
❯ docker run -p 13306:3306 \
-v "${PWD}/gcloud:/root/.config/gcloud" \
-d portforwardexample \
cloud_sql_proxy "-instances=myproject:us-west2:myinstance=tcp:3306"
d56c...
❯ mysql -h127.0.0.1 -P13306
ERROR 2013 (HY000): Lost connection to MySQL server at 'reading initial communication packet', system error: 0
如果我停止容器,我会收到不同的消息:
❯ mysql -h127.0.0.1 -P13306
ERROR 2003 (HY000): Can't connect to MySQL server on '127.0.0.1' (111)
...所以我知道 一些 通信正在发生。
容器中的代理(从内部连接),这有效
我知道问题出在我这边,因为当我使用交互式会话并从容器内连接时,一切都按预期工作。
❯ docker run -it --rm -p 13306:3306 \
-v "${PWD}/gcloud:/root/.config/gcloud" \
portforwardexample
root@bcf:/# cloud_sql_proxy "-instances=myproject:us-west2:myinstance=tcp:3306" &
2019/12/14 22:44:04 Listening on 127.0.0.1:3306 for myproject:us-west2:myinstance
2019/12/14 22:44:04 Ready for new connections
root@bcf:/# mysql -h127.0.0.1 -P3306
mysql> --connection successful
为什么我不能从容器外部连接?我需要做些什么来告诉容器可以通过 docker 转发端口吗?
我省略了我认为与我的问题无关的细节,但这里有一个包含一些额外细节的 repo(比如我正在使用的 Dockerfile):https://github.com/MatrixManAtYrService/cloudsqlproxyproblem
如果容器内的程序显示 Listening on 127.0.0.1
它可能无法从容器外部访问,您需要以某种方式对其进行配置,以便它绑定或侦听 0.0.0.0(所有接口)。
the Cloud SQL Proxy documentation中的例子有这个选项:
/cloud_sql_proxy -instances=...=tcp:0.0.0.0:3306 ...
而 0.0.0.0 是重要的。
要点
我有一个应用程序想要通过 tcp 端口连接到 mysql 数据库。我正在构建一个 docker 容器,该容器暂存云 sql 实例以供其连接(数据库包含从其他地方导入的测试用例)。我希望能够从 docker 容器内部转发 mysql 端口并从容器外部进行连接,但出现错误。
我试过的
容器中的数据库,这有效
当我在本地容器中有一个数据库时,我可以这样连接:
# run in background, listening on port 13306
❯ docker run -p 13306:3306 -e MYSQL_ROOT_PASSWORD=test -d percona:5.7.26-centos
9c25...
❯ mysql -h127.0.0.1 -P13306 -uroot -ptest
mysql> --connection successful
容器中的代理(从外部连接),这不起作用
但是当我在本地容器中有 cloud_sql_proxy 时,我得到这个错误:
# run in background, listening on port 13306
❯ docker run -p 13306:3306 \
-v "${PWD}/gcloud:/root/.config/gcloud" \
-d portforwardexample \
cloud_sql_proxy "-instances=myproject:us-west2:myinstance=tcp:3306"
d56c...
❯ mysql -h127.0.0.1 -P13306
ERROR 2013 (HY000): Lost connection to MySQL server at 'reading initial communication packet', system error: 0
如果我停止容器,我会收到不同的消息:
❯ mysql -h127.0.0.1 -P13306
ERROR 2003 (HY000): Can't connect to MySQL server on '127.0.0.1' (111)
...所以我知道 一些 通信正在发生。
容器中的代理(从内部连接),这有效
我知道问题出在我这边,因为当我使用交互式会话并从容器内连接时,一切都按预期工作。
❯ docker run -it --rm -p 13306:3306 \
-v "${PWD}/gcloud:/root/.config/gcloud" \
portforwardexample
root@bcf:/# cloud_sql_proxy "-instances=myproject:us-west2:myinstance=tcp:3306" &
2019/12/14 22:44:04 Listening on 127.0.0.1:3306 for myproject:us-west2:myinstance
2019/12/14 22:44:04 Ready for new connections
root@bcf:/# mysql -h127.0.0.1 -P3306
mysql> --connection successful
为什么我不能从容器外部连接?我需要做些什么来告诉容器可以通过 docker 转发端口吗?
我省略了我认为与我的问题无关的细节,但这里有一个包含一些额外细节的 repo(比如我正在使用的 Dockerfile):https://github.com/MatrixManAtYrService/cloudsqlproxyproblem
如果容器内的程序显示 Listening on 127.0.0.1
它可能无法从容器外部访问,您需要以某种方式对其进行配置,以便它绑定或侦听 0.0.0.0(所有接口)。
the Cloud SQL Proxy documentation中的例子有这个选项:
/cloud_sql_proxy -instances=...=tcp:0.0.0.0:3306 ...
而 0.0.0.0 是重要的。