接続オプションについて

このページでは、Cloud SQL インスタンスに接続する方法の概要と、利用可能な認証と認可のオプションについて説明します。

概要

Cloud SQL インスタンスに接続する方法を検討する際は、次のように、考慮すべき多くの選択肢があります。

  • インターネットから Cloud SQL インスタンスにアクセスできるようにするか、Virtual Private Cloud(VPC)ネットワーク内で限定公開にするか、または、一般公開と限定公開の両方にするか。
  • 独自の接続コードを記述するか、Cloud SQL Auth Proxy や sqlcmd クライアントなど、一般公開されているツールを使用して接続するか。
  • SSL / TLS による暗号化を必須とするか、暗号化されていないトラフィックを許可するか。

以降のセクションでは、Cloud SQL がデータベースの接続、認可、認証のために提供しているオプションについて説明します。

  • 接続方法: どのネットワーク パスを使用してインスタンスに到達するのか。
    • VPC のみの内部(プライベート)IP アドレス。
    • インターネットにアクセスできる外部(パブリック)IP アドレス。
  • 認可方法: どの接続が認可され、Cloud SQL インスタンスへの接続が許可されるのか。
    • Java と Python の Cloud SQL Auth Proxy と Cloud SQL コネクタ ライブラリ: IAM に基づいてアクセスを提供する。
    • セルフマネージド SSL / TLS 証明書: 特定の公開鍵に基づく接続のみを許可する。
    • 承認済みネットワーク: 接続可能な IP アドレスのリスト。
  • 認証方法: データベースにログインする方法。
    • 組み込みのデータベース認証: データベース エンジンで設定されたユーザー名とパスワードでログイン。

以下の情報を参考に、最適な接続、認可、認証のオプションを決定してください。

始める前に

アプリケーションへのアクセスを付与しても、データベース ユーザー アカウントがインスタンスに自動的に接続できるようになるわけではありません。インスタンスに接続するには、接続に使用できるデータベース ユーザー アカウントが必要です。新しいインスタンスの場合、デフォルトのユーザー アカウントを構成しておく必要があります。詳細については、組み込み認証を使用してユーザーを管理するをご覧ください。

Cloud SQL に接続する方法

データベース接続は、サーバーと接続元アプリケーションのリソースを消費します。アプリケーションのフットプリントを最小限に抑え、Cloud SQL の接続制限を超える可能性を少なくするには、常に適切な接続管理方法を採用してください。詳細については、データベース接続の管理をご覧ください。

パブリック IP とプライベート IP

Cloud SQL では、パブリック IP は、インスタンスに公共のインターネット経由でアクセスできることを意味します。逆に、プライベート IP のみを使用するインスタンスに、公共のインターネットからはアクセスできませんが、Virtual Private Cloud(VPC)経由ではアクセスできます。Cloud SQL インスタンスでは、パブリック IP アドレスとプライベート IP アドレスのどちらも使用できます。

プライベート IP

プライベート IP は、Virtual Private Cloud(VPC)でアクセス可能な IPv4 アドレスです。

このアドレスを使用して、VPC にアクセスできる他のリソースから接続できます。プライベート IP 経由の接続では、インターネットを経由する必要がないため、通常はレイテンシが小さく、攻撃ベクトルが制限されます。任意で、すべての接続で Cloud SQL Proxy またはセルフマネージド SSL 証明書のいずれかを使用するよう要求できます。

VPC にアクセスできるリソース上のクライアントから接続を行う場合は、プライベート IP を使用するインスタンスを構成することをおすすめします。プライベート IP を使用できるリソースの詳細については、プライベート IP の要件をご覧ください。

プライベート IP パスの場合は、次のサービスとアプリケーションがサーバーレス VPC アクセスを介してインスタンスに直接接続されます。

  • App Engine スタンダード環境
  • App Engine フレキシブル環境
  • Cloud Functions
  • Cloud Run

詳細については Cloud SQL でプライベート IP を使用するをご覧ください。

インスタンスにプライベート IP を追加する手順については、次のいずれかをご覧ください。

パブリック IP

パブリック IP は、公共のインターネット上で外部から利用できる IPv4 アドレスです。このアドレスは、自宅や職場など、Google のネットワーク内外のデバイスからの接続を受信できます。

インスタンスのセキュリティを保つため、パブリック IP を使用する Cloud SQL インスタンスへの接続は、Cloud SQL Auth Proxy または承認済みネットワークのいずれかを使用して認可する必要があります。

VPC の要件を満たしていないクライアントから接続する場合は、パブリック IP を使用してインスタンスを構成することをおすすめします。

インスタンスにパブリック IP を追加する手順については、パブリック IP 接続を構成するをご覧ください。

パブリック IP を使用して sqlcmd クライアントを Cloud SQL インスタンスに接続する方法については、データベース クライアントを使用して接続するをご覧ください。

Cloud SQL の承認方法

Cloud SQL 言語コネクタ

Cloud SQL 言語コネクタは、Cloud SQL インスタンスへの接続時に暗号化と IAM 承認を行うクライアント ライブラリです。Cloud SQL インスタンスに接続するには、他の接続オプションではなく、Cloud SQL 言語コネクタを使用することをおすすめします。

これらのライブラリは、サポート対象のプログラミング言語から直接使用できます。外部プロセスを必要とせずに Cloud SQL Auth Proxy と同じ認証が行われます。これにより、セキュリティが向上し、Cloud SQL に接続するための構成要件が削減されます。Cloud SQL 言語コネクタは、パブリック IP アドレスまたはプライベート IP アドレスを使用して接続する場合も同じコードを使用します。

開始するには、Cloud SQL 言語コネクタについてをご覧ください。

Cloud SQL Auth Proxy

Cloud SQL Auth Proxy では、Identity and Access Management(IAM)権限を使用して接続を承認し、保護できます。Cloud SQL Auth Proxy は、ユーザーまたはサービス アカウントの認証情報を使用して接続を検証し、Cloud SQL インスタンスに対して承認された SSL / TLS レイヤに接続をラップします。Cloud SQL Auth Proxy の動作の詳細については、Cloud SQL Auth Proxy についてをご覧ください。

Cloud SQL インスタンスへの接続の認証には、Cloud SQL Auth Proxy を使用することをおすすめします。これは最も安全な方法です。

Cloud SQL Auth Proxy は、実行可能なバイナリとして配布されるオープンソース ライブラリです。Cloud SQL Auth Proxy は、受信接続をリッスンして SSL / TLS でラップし、Cloud SQL インスタンスに渡す中間サーバーとして機能します。

環境によっては、Cloud SQL Auth Proxy を使用して接続するメカニズムが提供されています。これらの環境を使用した接続の手順については、次のいずれかをご覧ください。

セルフマネージド SSL / TLS 証明書

Cloud SQL Auth Proxy を使用して接続を暗号化する代わりに、Cloud SQL インスタンスに固有のクライアントとサーバーの SSL / TLS 証明書を設定できます。この証明書は、クライアントとサーバーの両方を相互に検証し、その間の接続を暗号化するために使用されます。

Cloud SQL Auth Proxy を使用しない場合は、セルフマネージド SSL / TLS 証明書を使用して暗号化することを強くおすすめします。暗号化しないと、データが安全に送信されず、第三者によって傍受または監視されるおそれがあります。

セルフマネージド SSL / TLS 証明書のご利用にあたっては、SSL / TLS 証明書による承認をご覧ください。

承認済みネットワーク

Cloud SQL Auth Proxy を使用する場合を除き、インスタンスのパブリック IP アドレスへの接続は、接続が承認済みネットワークから送信された場合のみ許可されます。承認済みネットワークとは、ユーザーが接続権限を持たせるよう指定した IP アドレスまたは範囲のことです。

承認済みネットワークのご利用にあたっては、承認済みネットワークでの認証をご覧ください。

Cloud SQL への認証方法

認証とは、ユーザーの ID を確認することによるアクセス制御です。エンドユーザーについては、ユーザーが認証情報(ユーザー名とパスワード)を入力すると認証が行われます。アプリケーションでは、ユーザーの認証情報がサービス アカウントに割り当てられている場合に認証が行われます。

Cloud SQL では、ユーザー名とパスワードで認証を行うデータベースの組み込み認証を使用します。詳しくは、SQL Server ユーザーの作成と管理をご覧ください。

Cloud SQL に接続するためのツール

次の表に、Cloud SQL に接続するためのオプションを示します。

接続オプション 詳細
Cloud SQL Auth Proxy
gcloud CLI
Cloud SQL 言語コネクタ
Cloud Shell
Cloud Code
サードパーティのデータベース管理ツールを使用して接続する
SQL Server Management Studio
SSMS Object Explorer
Visual Studio

コードサンプル

TCP ソケットに接続できる任意の言語を使用して、Cloud SQL Auth Proxy に接続できます。アプリケーションでどのように連携するのかを把握できるように、GitHub の詳細な例からコード スニペットをいくつか紹介します。

TCP で接続

Cloud SQL Auth Proxy 呼び出しステートメント:

./cloud-sql-proxy INSTANCE_CONNECTION_NAME &

Python

このスニペットをウェブ アプリケーションのコンテキストで表示するには、GitHub の README をご覧ください。

import os

import sqlalchemy

def connect_tcp_socket() -> sqlalchemy.engine.base.Engine:
    """Initializes a TCP connection pool for a Cloud SQL instance of SQL Server."""
    # Note: Saving credentials in environment variables is convenient, but not
    # secure - consider a more secure solution such as
    # Cloud Secret Manager (https://cloud.google.com/secret-manager) to help
    # keep secrets safe.
    db_host = os.environ[
        "INSTANCE_HOST"
    ]  # e.g. '127.0.0.1' ('172.17.0.1' if deployed to GAE Flex)
    db_user = os.environ["DB_USER"]  # e.g. 'my-db-user'
    db_pass = os.environ["DB_PASS"]  # e.g. 'my-db-password'
    db_name = os.environ["DB_NAME"]  # e.g. 'my-database'
    db_port = os.environ["DB_PORT"]  # e.g. 1433

    pool = sqlalchemy.create_engine(
        # Equivalent URL:
        # mssql+pytds://<db_user>:<db_pass>@<db_host>:<db_port>/<db_name>
        sqlalchemy.engine.url.URL.create(
            drivername="mssql+pytds",
            username=db_user,
            password=db_pass,
            database=db_name,
            host=db_host,
            port=db_port,
        ),
        # ...
    )

    return pool

Java

このスニペットをウェブ アプリケーションのコンテキストで表示するには、GitHub の README をご覧ください。

注:

  • CLOUD_SQL_CONNECTION_NAME は <MY-PROJECT>:<INSTANCE-REGION>:<INSTANCE-NAME> のように指定する必要があります。
  • 引数 ipTypes=PRIVATE を使用すると、SocketFactory はインスタンスに関連付けられたプライベート IP を使用して接続するようになります。
  • pom.xml ファイルの JDBC ソケット ファクトリ バージョン要件については、こちらをご覧ください。


import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;
import javax.sql.DataSource;

public class TcpConnectionPoolFactory extends ConnectionPoolFactory {

  // Note: Saving credentials in environment variables is convenient, but not
  // secure - consider a more secure solution such as
  // Cloud Secret Manager (https://cloud.google.com/secret-manager) to help
  // keep secrets safe.
  private static final String DB_USER = System.getenv("DB_USER");
  private static final String DB_PASS = System.getenv("DB_PASS");
  private static final String DB_NAME = System.getenv("DB_NAME");

  private static final String INSTANCE_HOST = System.getenv("INSTANCE_HOST");
  private static final String DB_PORT = System.getenv("DB_PORT");

  public static DataSource createConnectionPool() {
    // The configuration object specifies behaviors for the connection pool.
    HikariConfig config = new HikariConfig();

    // Configure which instance and what database user to connect with.
    config.setJdbcUrl(
        String.format("jdbc:sqlserver://%s:%s;databaseName=%s", INSTANCE_HOST, DB_PORT, DB_NAME));
    config.setUsername(DB_USER); // e.g. "root", "sqlserver"
    config.setPassword(DB_PASS); // e.g. "my-password"

    // ... Specify additional connection properties here.
    // ...

    // Initialize the connection pool using the configuration object.
    return new HikariDataSource(config);
  }
}

Node.js

このスニペットをウェブ アプリケーションのコンテキストで表示するには、GitHub の README をご覧ください。

const mssql = require('mssql');

// createTcpPool initializes a TCP connection pool for a Cloud SQL
// instance of SQL Server.
const createTcpPool = async config => {
  // Note: Saving credentials in environment variables is convenient, but not
  // secure - consider a more secure solution such as
  // Cloud Secret Manager (https://cloud.google.com/secret-manager) to help
  // keep secrets safe.
  const dbConfig = {
    server: process.env.INSTANCE_HOST, // e.g. '127.0.0.1'
    port: parseInt(process.env.DB_PORT), // e.g. 1433
    user: process.env.DB_USER, // e.g. 'my-db-user'
    password: process.env.DB_PASS, // e.g. 'my-db-password'
    database: process.env.DB_NAME, // e.g. 'my-database'
    options: {
      trustServerCertificate: true,
    },
    // ... Specify additional properties here.
    ...config,
  };
  // Establish a connection to the database.
  return mssql.connect(dbConfig);
};

Go

このスニペットをウェブ アプリケーションのコンテキストで表示するには、GitHub の README をご覧ください。

package cloudsql

import (
	"database/sql"
	"fmt"
	"log"
	"os"
	"strings"

	_ "github.com/denisenkom/go-mssqldb"
)

// connectTCPSocket initializes a TCP connection pool for a Cloud SQL
// instance of SQL Server.
func connectTCPSocket() (*sql.DB, error) {
	mustGetenv := func(k string) string {
		v := os.Getenv(k)
		if v == "" {
			log.Fatalf("Fatal Error in connect_tcp.go: %s environment variable not set.\n", k)
		}
		return v
	}
	// Note: Saving credentials in environment variables is convenient, but not
	// secure - consider a more secure solution such as
	// Cloud Secret Manager (https://cloud.google.com/secret-manager) to help
	// keep secrets safe.
	var (
		dbUser    = mustGetenv("DB_USER")       // e.g. 'my-db-user'
		dbPwd     = mustGetenv("DB_PASS")       // e.g. 'my-db-password'
		dbTCPHost = mustGetenv("INSTANCE_HOST") // e.g. '127.0.0.1' ('172.17.0.1' if deployed to GAE Flex)
		dbPort    = mustGetenv("DB_PORT")       // e.g. '1433'
		dbName    = mustGetenv("DB_NAME")       // e.g. 'my-database'
	)

	dbURI := fmt.Sprintf("server=%s;user id=%s;password=%s;port=%s;database=%s;",
		dbTCPHost, dbUser, dbPwd, dbPort, dbName)

	// dbPool is the pool of database connections.
	dbPool, err := sql.Open("sqlserver", dbURI)
	if err != nil {
		return nil, fmt.Errorf("sql.Open: %w", err)
	}

	// ...

	return dbPool, nil
}

C#

このスニペットをウェブ アプリケーションのコンテキストで表示するには、GitHub の README をご覧ください。

using Microsoft.Data.SqlClient;
using System;

namespace CloudSql
{
    public class SqlServerTcp
    {
        public static SqlConnectionStringBuilder NewSqlServerTCPConnectionString()
        {
            // Equivalent connection string:
            // "User Id=<DB_USER>;Password=<DB_PASS>;Server=<INSTANCE_HOST>;Database=<DB_NAME>;"
            var connectionString = new SqlConnectionStringBuilder()
            {
                // Note: Saving credentials in environment variables is convenient, but not
                // secure - consider a more secure solution such as
                // Cloud Secret Manager (https://cloud.google.com/secret-manager) to help
                // keep secrets safe.
                DataSource = Environment.GetEnvironmentVariable("INSTANCE_HOST"), // e.g. '127.0.0.1'
                // Set Host to 'cloudsql' when deploying to App Engine Flexible environment
                UserID = Environment.GetEnvironmentVariable("DB_USER"),         // e.g. 'my-db-user'
                Password = Environment.GetEnvironmentVariable("DB_PASS"),       // e.g. 'my-db-password'
                InitialCatalog = Environment.GetEnvironmentVariable("DB_NAME"), // e.g. 'my-database'

                // The Cloud SQL proxy provides encryption between the proxy and instance
                Encrypt = false,
            };
            connectionString.Pooling = true;
            // Specify additional properties here.
            return connectionString;
        }
    }
}

Ruby

このスニペットをウェブ アプリケーションのコンテキストで表示するには、GitHub の README をご覧ください。

tcp: &tcp
  adapter: sqlserver
  # Configure additional properties here.
  # Note: Saving credentials in environment variables is convenient, but not
  # secure - consider a more secure solution such as
  # Cloud Secret Manager (https://cloud.google.com/secret-manager) to help
  # keep secrets safe.
  username: <%= ENV["DB_USER"] %>  # e.g. "my-database-user"
  password: <%= ENV["DB_PASS"] %> # e.g. "my-database-password"
  database: <%= ENV.fetch("DB_NAME") { "vote_development" } %>
  host: <%= ENV.fetch("INSTANCE_HOST") { "127.0.0.1" }%> # '172.17.0.1' if deployed to GAE Flex
  port: <%= ENV.fetch("DB_PORT") { 1433 }%> 

PHP

このスニペットをウェブ アプリケーションのコンテキストで表示するには、GitHub の README をご覧ください。

namespace Google\Cloud\Samples\CloudSQL\SQLServer;

use PDO;
use PDOException;
use RuntimeException;
use TypeError;

class DatabaseTcp
{
    public static function initTcpDatabaseConnection(): PDO
    {
        try {
            // Note: Saving credentials in environment variables is convenient, but not
            // secure - consider a more secure solution such as
            // Cloud Secret Manager (https://cloud.google.com/secret-manager) to help
            // keep secrets safe.
            $username = getenv('DB_USER'); // e.g. 'your_db_user'
            $password = getenv('DB_PASS'); // e.g. 'your_db_password'
            $dbName = getenv('DB_NAME'); // e.g. 'your_db_name'
            $instanceHost = getenv('INSTANCE_HOST'); // e.g. '127.0.0.1' ('172.17.0.1' for GAE Flex)

            // Connect using TCP
            $dsn = sprintf(
                'sqlsrv:server=%s;Database=%s',
                $instanceHost,
                $dbName
            );

            // Connect to the database
            $conn = new PDO(
                $dsn,
                $username,
                $password,
                # ...
            );
        } catch (TypeError $e) {
            throw new RuntimeException(
                sprintf(
                    'Invalid or missing configuration! Make sure you have set ' .
                        '$username, $password, $dbName, and $instanceHost (for TCP mode). ' .
                        'The PHP error was %s',
                    $e->getMessage()
                ),
                $e->getCode(),
                $e
            );
        } catch (PDOException $e) {
            throw new RuntimeException(
                sprintf(
                    'Could not connect to the Cloud SQL Database. Check that ' .
                        'your username and password are correct, that the Cloud SQL ' .
                        'proxy is running, and that the database exists and is ready ' .
                        'for use. For more assistance, refer to %s. The PDO error was %s',
                    'https://cloud.google.com/sql/docs/sqlserver/connect-external-app',
                    $e->getMessage()
                ),
                (int) $e->getCode(),
                $e
            );
        }

        return $conn;
    }
}

トラブルシューティング

接続に問題がある場合は、以下のページで既知の問題のデバッグ方法やソリューションを確認してください。

次のステップ