Unable to connect to CloudSQL from Kubernetes Engine (Can't connect to MySQL server on 'localhost')

南笙酒味 提交于 2021-02-10 06:30:52

问题


I tried to follow the steps in: https://cloud.google.com/sql/docs/mysql/connect-kubernetes-engine.

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

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)

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

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.


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

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)

回答1:


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.

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.

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.

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




回答2:


I have recently setup cloudSQL postgres via cloudsql-proxy. I have few questions for you.

  1. The credentials you are using for cloudsql-proxy, do they have Cloud SQL Client Role.
  2. Does your cloudsql-proxy container command look like this,

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

It might be helpful if you could share your kubernetes deployment.yml which has both the app and proxy containers.




回答3:


Ok .. Posting an answer, but I'm not fully satisfied so I'll wait for more.

I was able to connect to the cloud SQL instance by changing the SQLALCHEMY_DATABASE_URI to 'mysql+pymysql://user:password@/db' (meaning I got rid of the unix socket connection string)

so :

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

worked for me. I'm not sure why I had to get rid of the unix socket connection string as I did enable the Cloud SQL API for my project.



来源:https://stackoverflow.com/questions/51679208/unable-to-connect-to-cloudsql-from-kubernetes-engine-cant-connect-to-mysql-ser

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!