无法从Kubernetes Engine连接到CloudSQL(无法连接到“本地主机"上的MySQL服务器) [英] Unable to connect to CloudSQL from Kubernetes Engine (Can't connect to MySQL server on 'localhost')
问题描述
我尝试按照以下步骤操作: https://cloud.google.com/sql/docs/mysql/connect-kubernetes-engine .
I tried to follow the steps in: https://cloud.google.com/sql/docs/mysql/connect-kubernetes-engine.
我在同一容器中运行了应用程序容器和cloudsql代理容器.
I have the application container and the cloudsql proxy container running in the same pod.
创建集群后,代理容器的日志似乎正确:
After creating the cluster, logs for the proxy container seems correct:
$kubectl logs users-app-HASH1-HASH2 cloudsql-proxy
2018/08/03 18:58:45 using credential file for authentication; email=it-test@tutorial-bookshelf-xxxxxx.iam.gserviceaccount.com
2018/08/03 18:58:45 Listening on 127.0.0.1:3306 for tutorial-bookshelf-xxxxxx:asia-south1:it-sample-01
2018/08/03 18:58:45 Ready for new connections
但是,来自应用程序容器的日志引发了无法在localhost上连接的错误:
However logs from the application container throws up an unable to connect on localhost error:
$kubectl logs users-app-HASH1-HASH2 app-container
...
19:27:38 users_app.1 | return Connection(*args, **kwargs)
19:27:38 users_app.1 | File "/usr/local/lib/python3.7/site-packages/pymysql/connections.py", line 327, in __init__
19:27:38 users_app.1 | self.connect()
19:27:38 users_app.1 | File "/usr/local/lib/python3.7/site-packages/pymysql/connections.py", line 629, in connect
19:27:38 users_app.1 | raise exc
19:27:38 users_app.1 | sqlalchemy.exc.OperationalError: (pymysql.err.OperationalError) (2003, "Can't connect to MySQL server on 'localhost' ([Errno 2] No such file or directory)") (Background on this error at: http://sqlalche.me/e/e3q8)
SQLALCHEMY_DATABASE_URI
是'mysql + pymysql://{user}:{password} @/{database}?unix_socket =/cloudsql/{cloudsql_connection_name}'
填充了正确的值(我使用kubectl机密设置的凭据).
The SQLALCHEMY_DATABASE_URI
is 'mysql+pymysql://{user}:{password}@/{database}?unix_socket=/cloudsql/{cloudsql_connection_name}'
and is populated with the correct values (credentials that I set using kubectl secrets).
我敢肯定,我在这里做的事很愚蠢,所以我希望有人对GCP有更多的经验,可以看看并提供解决此问题的指导.
I'm sure I'm doing something silly here, so I'm hoping someone more experience on GCP could take a look and provide pointers on troubleshooting this issue.
更新:我刚刚转到GCP kubernetes引擎页面,并在应用程序容器上打开了一个外壳,并尝试连接到云sql实例.这似乎奏效了.
UPDATE: I just went to the GCP kubernetes engine page and opened up a shell on the app container and tried to connect to the cloud sql instance. That seemed to have worked.
$gcloud container cluster ......... -it /bin/sh
#python
>>> import pymysql
>>> connection = pymysql.connect(host='127.0.0.1', user='user', password='password', db='db')
>>> with connection.cursor() as cursor:
... cursor.execute("show databases;")
... tables = cursor.fetchall()
...
5
但是以下(当我尝试通过sqlalchemy连接时)失败:
But the following (when I try and connect through sqlalchemy) fails:
>>> connection = pymysql.connect(host='127.0.0.1', user='u', password='p', db='d', unix_socket='/cloudsql/CONNECTION_NAME')
...
pymysql.err.OperationalError: (2003, "Can't connect to MySQL server on '127.0.0.1' ([Errno 2] No such file or directory)")
>>> from sqlalchemy import create_engine
>>> engine = create_engine('mysql://user:password@localhost/db')
>>> engine.connect()
Traceback (most recent call last):
...
sqlalchemy.exc.OperationalError: (_mysql_exceptions.OperationalError) (2002, 'Can\'t connect to local MySQL server through socket \'/run/mysqld/mysqld.sock\' (2 "No such file or directory")') (Background on this error at: http://sqlalche.me/e/e3q8)
>>> engine = create_engine('mysql+pymysql://user:password@/db?unix_socket=/cloudsql/tutorial-bookshelf-xxxx:asia-south1:test-01')
>>> engine.connect()
Traceback (most recent call last):
...
raise exc
sqlalchemy.exc.OperationalError: (pymysql.err.OperationalError) (2003, "Can't connect to MySQL server on 'localhost' ([Errno 2] No such file or directory)") (Background on this error at: http://sqlalche.me/e/e3q8)
推荐答案
可以通过unix套接字或TCP连接来完成通过代理与CloudSQL的连接,但是您不应该尝试同时使用两者时间.
Connection to the CloudSQL via the proxy can be done by either a unix socket or a TCP connection, but you shouldn't be trying to use both at the same time.
关于您如何配置代理,我没有看到任何规范,但是如果您希望使用unix套接字,则代理实例标志应如下所示: -instances =< INSTANCE_CONNECTION_NAME>
.这将导致代理在/cloudsql目录中创建一个UNIX套接字,以将流量转发到您的Cloud SQL实例.在这种情况下,您将在URL中设置 unix_socket =/cloudsql/< INSTANCE_CONNECTION_NAME>
.
I don't see any specifications on how you have configured your proxy, but if you wish to use a unix socket then your proxy instances flag should look like this: -instances=<INSTANCE_CONNECTION_NAME>
. This will cause the proxy to create a unix socket in the /cloudsql directory that forwards traffic to your Cloud SQL instance. In this case, you'll set unix_socket=/cloudsql/<INSTANCE_CONNECTION_NAME>
in your url.
如果您尝试通过TCP套接字进行连接,请使用如下实例标记: -instances =< INSTANCE_CONNECTION_NAME> = tcp:3306
.这将告诉代理侦听端口3306并将流量转发到您的Cloud SQL实例.在这种情况下,您将使用host ='127.0.0.1'和port = 3306.
If you are trying to connect via TCP socket, then use an instances flag like this: -instances=<INSTANCE_CONNECTION_NAME>=tcp:3306
. This will tell the proxy to listen on port 3306 and forward traffic to your Cloud SQL instance. In this case, you'll use host='127.0.0.1' and port=3306.
如果您希望获得有关在GKE上使用CloudSQL的入门知识,我鼓励您查看该项目中提到的代码实验室: https://github.com/GoogleCloudPlatform/gmemegen
If you are looking for a hands on introduction to using CloudSQL on GKE, I encourage you to check out the codelab mentioned in this project: https://github.com/GoogleCloudPlatform/gmemegen
这篇关于无法从Kubernetes Engine连接到CloudSQL(无法连接到“本地主机"上的MySQL服务器)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!