首页 文章

无法从Kubernetes引擎连接到CloudSQL(可以't connect to MySQL server on ' localhost')

提问于
浏览
0

我试着按照以下步骤操作:https://cloud.google.com/sql/docs/mysql/connect-kubernetes-engine .

我有应用程序容器和在同一个pod中运行的cloudsql代理容器 .

创建群集后,代理容器的日志似乎正确:

$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错误:

$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机密设置的凭据) .

我确定我在这里做了些傻事,所以我希望有人在GCP上有更多的经验可以看看,并提供有关解决这个问题的指示 .


更新:我刚刚访问了GCP kubernetes引擎页面,并在应用程序容器上打开了一个shell,并尝试连接到 Cloud sql实例 . 这似乎有效 .

$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连接时)失败:

>>> 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)

3 回答

  • 1

    通过代理连接到CloudSQL可以通过unix套接字或TCP连接完成,但是你不应该同时尝试使用它们 .

    我没有看到您如何配置代理的任何规范,但如果您希望使用unix套接字,那么您的代理实例标志应如下所示: -instances=<INSTANCE_CONNECTION_NAME> . 这将导致代理在/ cloudsql目录中创建一个unix套接字,该套接字将流量转发到您的Cloud SQL实例 . 在这种情况下,您将在您的网址中设置 unix_socket=/cloudsql/<INSTANCE_CONNECTION_NAME> .

    如果您尝试通过TCP套接字连接,请使用如下的实例标志: -instances=<INSTANCE_CONNECTION_NAME>=tcp:3306 . 这将告诉代理侦听端口3306并将流量转发到您的Cloud SQL实例 . 在这种情况下,您'll use host=' 127.0.0.1'和port = 3306 .

    如果您正在寻找在GKE上使用CloudSQL的介绍,我建议您查看此项目中提到的codelab:https://github.com/GoogleCloudPlatform/gmemegen

  • 0

    我最近通过cloudsql-proxy设置了cloudSQL postgres . 我有几个问题要问你 .

    • 您用于cloudsql-proxy的凭据是否具有Cloud SQL客户端角色 .

    • 你的cloudsql-proxy容器命令是这样的,

    / cloud_sql_proxy“,” - dir = / cloudsql“,” - instances == tcp:3306“,” - credential_file = / secrets / cloudsql / credentials.json“

    如果您可以共享包含应用程序和代理容器的kubernetes deployment.yml,这可能会有所帮助 .

  • 1

    好的..发表答案,但我并不完全满意,所以我会等待更多 .

    通过将SQLALCHEMY_DATABASE_URI更改为 'mysql+pymysql://user:password@/db' (意味着我摆脱了unix套接字连接字符串),我能够连接到 Cloud SQL实例

    所以:

    >>> engine = create_engine('mysql+pymysql://user:password@/db')
    >>> engine.connect()
    <sqlalchemy.engine.base.Connection object at 0x7f2236bdc438>
    

    为我工作 . 我不知道为什么我必须摆脱unix socket连接字符串,因为我为我的项目启用了Cloud SQL API .

相关问题