从外部应用连接到 Cloud SQL

本页面介绍了如何从在 Google Cloud 外部运行的应用连接到 Cloud SQL。

数据库连接会消耗服务器和连接应用上的资源。请始终采用最佳连接管理做法,以最大限度减少应用的占用空间,并降低超出 Cloud SQL 连接限制的可能性。 如需了解详情,请参阅管理数据库连接

准备工作

授予对一个应用的访问权限不会自动允许数据库用户帐号连接到该实例。您必须首先具备可用于连接的数据库用户帐号,之后才能连接到实例。对于新实例,这就表示您必须已配置好默认用户帐号。了解详情

连接选项

下表比较了从外部应用连接到 Cloud SQL 实例的选项:

连接选项 是否有安全加密? 了解详情 备注
使用 SSL 的公共 IP 地址 需要 SSL 证书管理服务。
不使用 SSL 的公共 IP 地址 不适用于生产实例。
Cloud SQL 代理
Cloud SQL 代理 Docker 映像
JDBC 套接字库 仅限 Java 编程语言。
Go 代理库 仅限 Go 编程语言。
Cloud Shell 使用 Cloud SQL 代理从 Google Cloud Console 建立连接。最适合用于需要 mysql 命令行工具的管理任务。
Apps 脚本 Apps 脚本可以通过 JDBC 服务(标准 Java 数据库连接技术的一种封装容器)连接到外部数据库。

使用代理从外部应用建立连接

如果您是为本地测试环境(而非生产环境)设置 Cloud SQL 代理,则可以参照代理快速入门操作,而不必遵循本页面中的说明操作。

如果您使用的是 Java 或 Go 编程语言,则除了使用 Cloud SQL 代理,还有几种备选方法。了解详情

1.启用 API

启用 Cloud SQL Admin API。

启用 API

2. 在本地计算机上安装代理客户端

Linux 64 位

  1. 下载该代理:
    wget https://dl.google.com/cloudsql/cloud_sql_proxy.linux.amd64 -O cloud_sql_proxy
    
  2. 使该代理可以执行:
    chmod +x cloud_sql_proxy
    

Linux 32 位

  1. 下载该代理:
    wget https://dl.google.com/cloudsql/cloud_sql_proxy.linux.386 -O cloud_sql_proxy
    
  2. 使该代理可以执行:
    chmod +x cloud_sql_proxy
    

macOS 64 位

  1. 下载该代理:
    curl -o cloud_sql_proxy https://dl.google.com/cloudsql/cloud_sql_proxy.darwin.amd64
    
  2. 使该代理可以执行:
    chmod +x cloud_sql_proxy
    

macOS 32 位

  1. 下载该代理:
    curl -o cloud_sql_proxy https://dl.google.com/cloudsql/cloud_sql_proxy.darwin.386
    
  2. 使该代理可以执行:
    chmod +x cloud_sql_proxy
    

Windows 64 位

右键点击 https://dl.google.com/cloudsql/cloud_sql_proxy_x64.exe,然后选择链接另存为以下载该代理。将文件重命名为 cloud_sql_proxy.exe

Windows 32 位

右键点击 https://dl.google.com/cloudsql/cloud_sql_proxy_x86.exe,然后选择链接另存为以下载该代理。将文件重命名为 cloud_sql_proxy.exe
如果此处未包含您的操作系统,您还可以通过源代码编译该代理

3.确定如何对代理进行身份验证

详细了解代理身份验证选项

4. 如果您的身份验证方法有相应需要,请创建一个服务帐号

如果使用服务帐号为该代理提供凭据,则您必须在创建该服务帐号时为其分配足够的权限。如果要使用更精细的 Identity Access and Management (IAM) 角色来管理 Cloud SQL 权限,您必须向服务帐号分配一个具有 cloudsql.instances.connect 权限的角色。以下预定义 Cloud SQL 角色拥有这项权限:

  • Cloud SQL Client
  • Cloud SQL Editor
  • Cloud SQL Admin

如果您要使用传统的项目角色(Viewer、Editor、Owner),则该服务帐号必须至少具有 Editor 角色。

  1. 转到 Google Cloud Console 中的服务帐号页面。

    转到“服务帐号”页面

  2. 选择包含您的 Cloud SQL 实例的项目。
  3. 点击创建服务帐号
  4. 创建服务帐号对话框中,为服务帐号提供一个描述性名称。
  5. 角色部分,选择以下角色之一:
    • Cloud SQL > Cloud SQL Client
    • Cloud SQL > Cloud SQL Editor
    • Cloud SQL > Cloud SQL Admin

    或者,您可以通过选择项目 > Editor 使用基本的 Editor 角色,但 Editor 角色拥有整个 Google Cloud 的权限。

    如果您看不到这些角色,则表明您的 Google Cloud 用户可能没有 resourcemanager.projects.setIamPolicy 权限。您可以转到 Google Cloud Console 中的 IAM 页面,然后搜索您的用户 ID 来检查您的权限。

  6. 服务帐号 ID 更改为一个不重复且易于识别的值。
  7. 点击提供新的私钥,并确认密钥类型为 JSON
  8. 点击创建

    私钥文件将下载到您的机器上。您可以将此文件移至其他位置,但要确保密钥文件的安全。

5. 确定如何为代理指定实例

详细了解代理实例指定选项

6. 启动代理

您传递给代理的选项取决于您先前选择的身份验证和实例指定选项。

根据您的语言和环境,您可以使用 TCP 套接字或 Unix 套接字启动代理。

TCP 套接字

  1. 实例详情页面复制您的实例连接名称。

    例如:myproject:myregion:myinstance

  2. 如果您要使用服务帐号对代理进行身份验证,请记下随服务帐号一起创建的私钥文件在客户端机器上的位置。
  3. 启动代理。

    下面列出了一些可能的代理调用字符串:

    • 使用 Cloud SDK 身份验证:
      ./cloud_sql_proxy -instances=<INSTANCE_CONNECTION_NAME>=tcp:3306
      
      指定的端口必须尚未被本地数据库服务器等所占用。
    • 使用服务帐号并明确包含实例连接的名称(建议用于生产环境):
      ./cloud_sql_proxy -instances=<INSTANCE_CONNECTION_NAME>=tcp:3306 \
                        -credential_file=<PATH_TO_KEY_FILE> &
      

    如需详细了解代理选项,请参阅用于验证代理身份的选项用于指定实例的选项

Unix 套接字

  1. 如果使用显式实例指定,请从实例详情页面复制您的实例连接名称。
  2. 创建要用来存放代理套接字的目录:
    sudo mkdir /cloudsql; sudo chmod 777 /cloudsql
  3. 如果您要使用服务帐号对代理进行身份验证,请记下随服务帐号一起创建的私钥文件在客户端机器上的位置。
  4. 打开一个新终端窗口并启动代理。

    下面列出了一些可能的代理调用字符串:

    • 使用服务帐号并明确包含实例连接的名称(建议用于生产环境):
      ./cloud_sql_proxy -dir=/cloudsql -instances=<INSTANCE_CONNECTION_NAME> \
                        -credential_file=<PATH_TO_KEY_FILE> &
    • 使用 Cloud SDK 身份验证和自动实例发现:
      ./cloud_sql_proxy -dir=/cloudsql &

    建议最好在单独的终端中启动代理,这样便于您监控其输出,避免与其他程序的输出相混淆。

    如需详细了解代理选项,请参阅用于验证代理身份的选项用于指定实例的选项

  5. 使用 Cloud SQL 代理和 unix 套接字连接到 Cloud SQL 时,请确保套接字文件名的长度不超过系统限制。一般来说,套接字文件名包含 91 到 108 个字符,具体取决于您所用的系统。在 Linux 上,该文件名通常包含 108 个字符;您可以使用以下命令进行检查:
    cat /usr/include/linux/un.h | grep "define UNIX_PATH_MAX"

7. 更新应用以使用代理连接到 Cloud SQL

使用代理连接到 Cloud SQL 实例所需的具体代码语句取决于您所使用的语言和框架。

连接到代理的方式与连接到 TCP 或 Unix 套接字的方式相同(具体取决于调用代理的方式):

TCP 套接字

使用 TCP 套接字时,代理作为本地主机通过以下地址提供:

127.0.0.1:3306

Unix 套接字

使用 Unix 套接字时,代理通过如下路径提供:

PROXY_PATH/INSTANCE_CONNECTION_NAME;
其中的 PROXY_PATH 是您在启动代理时通过 -dir 选项所设置的目录的路径。本文档中的示例使用 /cloudsql。您可以在 Google Cloud Console 中对应的实例详情页面找到实例的连接名称,也可以使用 PROJECT-ID:REGION:INSTANCE_NAME

需要帮助?如需获得代理问题排查方面的帮助,请参阅排查 Cloud SQL 代理连接问题。也可参阅我们的 Cloud SQL 支持页面

特定语言的信息和示例

您可以使用支持连接到 Unix 或 TCP 套接字的任何语言连接到代理。下面给出了几个代理调用和连接语句示例,可帮助您了解它们在您的应用中如何协同工作。

.NET

启动代理后,修改您的 appsettings.json 文件并在 CloudSql:ConnectionString 中定义连接字符串。例如:

{
  "CloudSQL" : {
     ConnectionString": "Host=127.0.0.1;Uid=DATABASE_USER;Pwd=PASSWORD;Database=DATABASE_NAME"
  }
}

然后,在您的 Startup.cs 文件中,创建数据库连接:

var connectionString = new MySqlConnectionStringBuilder(
    Configuration["CloudSql:ConnectionString"])
{
    // Connecting to a local proxy that does not support ssl.
    SslMode = MySqlSslMode.None,
};
DbConnection connection =
    new MySqlConnection(connectionString.ConnectionString);

Go

您可以通过两种方式将 Cloud SQL 代理与 Go 编程语言配合使用:

  1. 使用 Go 代理库
  2. 将代理作为同伴进程运行

Go 代理库

该库提供了从 Go 程序连接到 Cloud SQL 的最简单方法,因为您并不需要明确地单独启动代理。

import (
    "github.com/GoogleCloudPlatform/cloudsql-proxy/proxy/dialers/mysql"
)
...
cfg := mysql.Cfg(INSTANCE_CONNECTION_NAME, DATABASE_USER, PASSWORD)
cfg.DBName = DATABASE_NAME
db, err := mysql.DialCfg(cfg)

如需了解详情,请参阅 Cloud SQL 代理 GitHub 页面

同伴进程

您还可以将代理作为同伴进程运行,并从您的应用连接到代理。

为简洁起见,下面的代理调用语句使用本地 Cloud SDK 身份验证,根据您的身份验证方式以及实例指定方式的不同,具体的调用语句可能会有所不同。请参阅 Cloud SQL 代理身份验证选项

TCP 套接字

代理调用语句:

./cloud_sql_proxy -instances=[INSTANCE_CONNECTION_NAME]=tcp:3306 &

连接语句:

import (
       "database/sql"
        _ "github.com/go-sql-driver/mysql"
)

dsn := fmt.Sprintf("%s:%s@tcp(%s)/%s",
       DATABASE_USER,
       PASSWORD,
       "127.0.0.1:3306",
       DATABASE_NAME)
db, err := sql.Open("mysql", dsn)

Unix 套接字

代理调用语句:

./cloud_sql_proxy -instances=[INSTANCE_CONNECTION_NAME] -dir=/cloudsql &

连接语句:

import (
       "database/sql"
        _ "github.com/go-sql-driver/mysql"
)

dsn := fmt.Sprintf("%s:%s@unix(/cloudsql/%s)/%s",
       DATABASE_USER,
       PASSWORD,
       INSTANCE_CONNECTION_NAME,
       DATABASE_NAME)
db, err := sql.Open("mysql", dsn)

Java

Java 编程语言不提供对 Unix 套接字的内置支持。您可以使用 TCP 套接字或使用通过 Cloud SQL 代理提供 Unix 套接字支持的库,但是在不添加授权网络地址的情况下连接到 Cloud SQL 实例的最简单方法是使用 JDBC 套接字工厂。

JDBC 套接字工厂提供了客户端代理软件的替代方案,并要求您启用 Cloud SQL Admin API,就像 Cloud SQL 代理所做的一样。套接字工厂提供与代理相同级别的加密,并使用 Cloud SDK 凭据执行身份验证。使用套接字工厂之前,您必须安装 Cloud SDK 并对其进行身份验证。

如需查看代码示例,请参阅 JDBC 驱动程序的 Cloud SQL 套接字工厂。请查看 README 文件,了解相关说明。

PHP

PDO 和 TCP

调用代理:

./cloud_sql_proxy -instances=INSTANCE_CONNECTION_NAME=tcp:3306 &

以下示例使用 PHP 数据对象 (PDO) 连接到 Cloud SQL:

// Use a Data source name (DSN) to connect to Cloud SQL through the proxy
$dsn = 'mysql:host=127.0.0.1;port=3306;dbname=DATABASE_NAME';
// Instantiate your DB using the DSN, username, and password
$dbUser = 'DATABASE_USER';
$dbPass = 'PASSWORD';
$db = new PDO($dsn, $dbUser, $dbPass);

PDO 和 Unix 套接字

调用代理:

./cloud_sql_proxy -instances=INSTANCE_CONNECTION_NAME -dir=/cloudsql &

以下示例使用 PDO 连接到 Cloud SQL:

// Use a Data source name (DSN) to connect to Cloud SQL through the proxy
$dsn = sprintf('mysql:unix_socket=/cloudsql/INSTANCE_CONNECTION_NAME;dbname=DATABASE_NAME';
// Instantiate your DB using the DSN, username, and password
$dbUser = 'DATABASE_USER';
$dbPass = 'PASSWORD';
$db = new PDO($dsn, $dbUser, $dbPass);

mysqli 和 TCP

调用代理:

./cloud_sql_proxy -instances=INSTANCE_CONNECTION_NAME=tcp:3306 &

以下示例使用 mysqli 连接到 Cloud SQL:

// Instantiate your DB using the database host, port, name, username, and password
$dbName = 'DATABASE_NAME';
$dbUser = 'DATABASE_USER';
$dbPass = 'PASSWORD';
$mysqli = new mysqli('127.0.0.1', $dbUser, $dbPass, $dbName, 3306);

mysqli 和 Unix 套接字

调用代理:

./cloud_sql_proxy -instances=INSTANCE_CONNECTION_NAME -dir=/cloudsql &

以下示例使用 mysqli 连接到 Cloud SQL:

// Instantiate your DB using the database name, socket, username, and password
$dbName = 'DATABASE_NAME';
$dbUser = 'DATABASE_USER';
$dbPass = 'PASSWORD';
$dbSocket = '/cloudsql/INSTANCE_CONNECTION_NAME';
$mysqli = new mysqli(null, $dbUser, $dbPass, $dbName, null, $dbSocket);

Python

为简洁起见,下面的代理调用语句使用本地 Cloud SDK 身份验证,根据您的身份验证方式以及实例指定方式的不同,具体的调用语句可能会有所不同。了解详情

PyMySQL 和 TCP

调用代理:

./cloud_sql_proxy -instances=INSTANCE_CONNECTION_NAME=tcp:3306 &

连接语句:

import pymysql
connection = pymysql.connect(host='127.0.0.1',
                             user='DATABASE_USER',
                             password='PASSWORD',
                             db='DATABASE_NAME')

PyMySQL 和 Unix

调用代理:

./cloud_sql_proxy -instances=INSTANCE_CONNECTION_NAME -dir=/cloudsql &

连接语句:

import pymysql
connection = pymysql.connect(unix_socket='/cloudsql/' + INSTANCE_CONNECTION_NAME,
                             user='DATABASE_USER',
                             password='PASSWORD',
                             db='DATABASE_NAME')

SQLAlchemy 和 TCP

调用代理:

./cloud_sql_proxy -instances=INSTANCE_CONNECTION_NAME=tcp:3306 &

连接语句:

from sqlalchemy import create_engine
  engine = create_engine('mysql+pymysql://DATABASE_USER:PASSWORD@127.0.0.1/DATABASE_NAME')

SQLAlchemy 和 Unix

调用代理:

./cloud_sql_proxy -instances=INSTANCE_CONNECTION_NAME -dir=/cloudsql &

连接语句:

from sqlalchemy import create_engine
engine = create_engine('mysql+pymysql://DATABASE_USER:PASSWORD@/DATABASE_NAME?unix_socket=/cloudsql/INSTANCE_CONNECTION_NAME')

Ruby

mysql2 和 TCP

调用代理:

./cloud_sql_proxy -instances=INSTANCE_CONNECTION_NAME=tcp:3306 &

以下示例使用 mysql2 RubyGem 连接到 Cloud SQL:

require "mysql2"
client = Mysql2::Client.new host: "127.0.0.1", port: 3306,
    database: "DATABASE_NAME", username: "DATABASE_USER",
    password: "PASSWORD"

>mysql2 和 Unix 套接字

调用代理:

./cloud_sql_proxy -instances=INSTANCE_CONNECTION_NAME -dir=/cloudsql &

以下示例使用 mysql2 RubyGem 连接到 Cloud SQL:

require "mysql2"
client = Mysql2::Client.new socket: "/cloudsql/CONNECTION_NAME",
    database: "DATABASE_NAME", username: "DATABASE_USER",
    password: "PASSWORD"

Rails 和 TCP

调用代理:

./cloud_sql_proxy -instances=INSTANCE_CONNECTION_NAME=tcp:3306 &

config/databases.yml 中,请使用以下配置:

mysql_settings: &mysql_settings
  adapter: mysql2
  encoding: utf8
  pool: 5
  username: DATABASE_USER
  password: PASSWORD
  database: DATABASE_NAME
  host: 127.0.0.1:3306

Rails 和 Unix 套接字

调用代理:

./cloud_sql_proxy -instances=INSTANCE_CONNECTION_NAME -dir=/cloudsql &

config/databases.yml 中,请使用以下配置:

mysql_settings: &mysql_settings
  adapter: mysql2
  encoding: utf8
  pool: 5
  username: DATABASE_USER
  password: PASSWORD
  database: DATABASE_NAME
  socket: /cloudsql/INSTANCE_CONNECTION_NAME

为公共 IP 连接配置访问权限

您可以通过授权公共 IP 地址(应用用于建立连接的公共 IP 地址),授予任何应用对 Cloud SQL 实例的访问权限。

您不能将专用网络(例如 10.x.x.x)指定为已获授权的网络。

MySQL 实例的公共 IP 地址

  • IPv6:实例不支持 IPv6。
  • IPv4:实例具有自动分配的静态 IPv4 地址。关闭(停用)实例时,IP 地址将产生少量费用。

如需通过公共 IP 连接配置访问权限,请按照如下所述操作:

控制台

  1. 确定应用的 IP 地址。了解详情
  2. 授权应用的 IP 地址连接到您的实例。

    如需了解详情,请参阅添加已获授权的地址

  3. 您可以在实例详情页面中找到已分配给您的实例的 IP 地址。这是您的应用连接字符串所需的值。

gcloud

  1. 确定客户端机器的 IP 地址。了解详情
  2. 授权应用的 IP 地址连接到您的实例。

    如需了解详情,请参阅添加已获授权的地址

  3. 检索实例的 IP 地址:
    gcloud sql instances describe [INSTANCE_NAME]
    

    在输出中找到 ipAddress 字段。这是您的应用连接字符串所需的值。

REST v1beta4

  1. 确定应用的 IP 地址。了解详情
  2. 授权应用的 IP 地址连接到您的实例。

    如需了解详情,请参阅添加已获授权的地址

  3. 检索实例的 IP 地址:

    在使用下面的请求数据之前,请先进行以下替换:

    • project-id:项目 ID
    • instance-id:实例 ID

    HTTP 方法和网址:

    GET https://www.googleapis.com/sql/v1beta4/projects/project-id/instances/instance-id

    如需发送您的请求,请展开以下选项之一:

    您应该收到类似以下内容的 JSON 响应:

    {
      "kind": "sql#instance",
      "state": "RUNNABLE",
      "databaseVersion": "MYSQL_5_7",
      "settings": {
        "authorizedGaeApplications": [],
        "tier": "db-f1-micro",
        "kind": "sql#settings",
        "pricingPlan": "PER_USE",
        "replicationType": "SYNCHRONOUS",
        "activationPolicy": "ALWAYS",
        "ipConfiguration": {
          "authorizedNetworks": [],
          "ipv4Enabled": true
        },
        "locationPreference": {
          "zone": "asia-east1-a",
          "kind": "sql#locationPreference"
        },
        "dataDiskType": "PD_SSD",
        "backupConfiguration": {
          "startTime": "08:00",
          "kind": "sql#backupConfiguration",
          "enabled": true,
          "binaryLogEnabled": true
        },
        "settingsVersion": "13",
        "storageAutoResizeLimit": "0",
        "storageAutoResize": true,
        "dataDiskSizeGb": "10"
      },
      "etag": "etag-id",
      "ipAddresses": [
        {
          "type": "PRIMARY",
          "ipAddress": "10.0.0.1"
        }
      ],
      "serverCaCert": {
        "kind": "sql#sslCert",
        "certSerialNumber": "0",
        "cert": "certificate-id",
        "commonName": "C=US,O=Google\\, Inc,CN=Google Cloud SQL Server CA,dnQualifier=dn-qualifier-id",
        "sha1Fingerprint": "sha-id",
        "instance": "instance-id",
        "createTime": "2019-06-28T22:46:35.052Z",
        "expirationTime": "2029-06-25T22:47:35.052Z"
      },
      "instanceType": "CLOUD_SQL_INSTANCE",
      "project": "project-id",
      "serviceAccountEmailAddress": "service-acct-id@gcp-sa-cloud-sql.iam.gserviceaccount.com",
      "backendType": "SECOND_GEN",
      "selfLink": "https://www.googleapis.com/sql/v1beta4/projects/project-id/instances/instance-id",
      "connectionName": "project-id:region:instance-id",
      "name": "instance-id",
      "region": "asia-east1",
      "gceZone": "asia-east1-a"
    }
    

    请记下 ipAddresses.ipAddress 的值(适用于 IPv4)。这是您的应用连接字符串所需的值。

需要帮助?如需获得代理问题排查方面的帮助,请参阅排查 Cloud SQL 代理连接问题。也可参阅我们的 Cloud SQL 支持页面

为使用动态分配的 IP 地址的应用配置访问权限

部分应用需要使用动态分配或暂时的 IP 地址连接到您的 Cloud SQL 实例。平台即服务 (Paas) 应用就是其中的一个例子。

这些应用的最佳解决方案是使用 Cloud SQL 代理进行连接。这样,您就能最有效地控制对实例的访问。

测试连接

您可以使用 mysql 客户端测试从本地环境建立连接的能力。如需了解详情,请参阅使用 IP 地址连接 mysql 客户端使用 Cloud SQL 代理连接 mysql 客户端

需要帮助?如需获得代理问题排查方面的帮助,请参阅排查 Cloud SQL 代理连接问题。也可参阅我们的 Cloud SQL 支持页面

确定应用的 IP 地址

为确定运行应用的计算机的 IP 地址,以便授权该地址访问 Cloud SQL 实例,您可以使用以下可选方法之一:

  • 如果计算机不在代理后面,请登录计算机并使用此链接确定其 IP 地址。
  • 如果计算机在代理后面,请登录计算机,并使用 whatismyipaddress.com 等工具或服务来确定其真实的 IP 地址。

后续步骤