You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过服务账号结合pymysql/mysql.connector跨VPC连接CloudSQL

跨VPC通过Nginx代理使用服务账号访问CloudSQL MySQL的解决方案

前置准备

  1. 授权服务账号

    • 在Google Cloud IAM中,给目标服务账号添加Cloud SQL Client角色(或更精细的Cloud SQL Instance User权限)。
    • 在CloudSQL实例的IAM权限页面,将该服务账号添加为成员,分配Cloud SQL Client角色。
    • 在MySQL实例内部创建对应服务账号用户:
      CREATE USER 'your-service-account@your-project.iam.gserviceaccount.com' IDENTIFIED WITH mysql_clear_password;
      GRANT ALL PRIVILEGES ON your_database.* TO 'your-service-account@your-project.iam.gserviceaccount.com';
      FLUSH PRIVILEGES;
      

    注意用户必须是完整的服务账号邮箱格式。

  2. 确保Nginx代理配置正确

    • 代理需正确转发3306端口的TCP流量,且不篡改数据包内容(令牌需明文传递)。示例Nginx TCP代理配置:
      stream {
          server {
              listen 3306;
              proxy_pass cloudsql-instance-ip:3306;
          }
      }
      

修复mysql.connector的认证插件错误

错误Authentication plugin 'mysql_clear_password' cannot be loaded是因为未指定认证插件,且未请求正确的CloudSQL权限范围。修改代码如下:

import google.auth
import google.auth.transport.requests
import mysql.connector
from mysql.connector import Error

# 指定CloudSQL所需的权限范围
SCOPES = ['https://www.googleapis.com/auth/sqlservice.admin']
creds, project = google.auth.default(scopes=SCOPES)
auth_req = google.auth.transport.requests.Request()
creds.refresh(auth_req)

try:
    connection = mysql.connector.connect(
        host=YOUR_NGINX_PROXY_HOST,
        database=YOUR_DB_NAME,
        user=YOUR_SERVICE_ACCOUNT_EMAIL,  # 完整服务账号邮箱
        password=creds.token,
        auth_plugin='mysql_clear_password',  # 启用明文密码认证插件
        ssl_ca='path/to/server-ca.pem'  # 若CloudSQL强制SSL,需添加此证书(从控制台下载)
    )
    if connection.is_connected():
        print(f"Connected to MySQL Server version {connection.get_server_info()}")
        cur = connection.cursor()
        cur.execute("SELECT now()")
        print(f"Query result: {cur.fetchall()}")
except Error as e:
    print(f"Connection error: {e}")
finally:
    if 'connection' in locals() and connection.is_connected():
        cur.close()
        connection.close()
        print("Connection closed")

修复pymysql的权限错误

错误Access denied通常是因为未指定认证插件、权限范围不正确或SSL配置缺失。修改代码如下:

import pymysql
import google.auth
import google.auth.transport.requests
from pymysql.constants import CLIENT

SCOPES = ['https://www.googleapis.com/auth/sqlservice.admin']
creds, project = google.auth.default(scopes=SCOPES)
auth_req = google.auth.transport.requests.Request()
creds.refresh(auth_req)

try:
    conn = pymysql.connect(
        host=YOUR_NGINX_PROXY_HOST,
        user=YOUR_SERVICE_ACCOUNT_EMAIL,
        passwd=creds.token,
        port=3306,
        database=YOUR_DB_NAME,
        auth_plugin='mysql_clear_password',
        ssl={'ca': 'path/to/server-ca.pem'},  # SSL证书配置
        client_flag=CLIENT.SSL  # 启用SSL连接
    )
    cur = conn.cursor()
    cur.execute("SELECT now()")
    print(f"Query result: {cur.fetchall()}")
except Exception as e:
    print(f"Connection failed: {e}")
finally:
    if 'conn' in locals() and conn.open:
        cur.close()
        conn.close()
        print("Connection closed")

关键注意事项

  • 令牌范围:必须请求sqlservice.admin或cloud-platform范围,否则令牌无法用于CloudSQL认证。
  • SSL要求:CloudSQL默认强制SSL连接,需从控制台下载server-ca.pem并在连接中配置。
  • 服务账号环境:本地运行时需设置GOOGLE_APPLICATION_CREDENTIALS环境变量指向服务账号密钥文件;GCP托管环境(如GKE、GCE)可直接使用默认服务账号。

内容的提问来源于stack exchange,提问作者Max

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 20:55:30