Cloud Run から接続する

このページには、Cloud Run で実行しているサービスから Cloud SQL インスタンスに接続するための情報と例が含まれています。

Cloud SQL に接続された Cloud Run のサンプル ウェブ アプリケーションを実行する手順ガイドについては、Cloud Run から接続するためのクイックスタートをご覧ください。

Cloud SQL は、クラウド内のリレーショナル データベースの設定、維持、管理に役立つフルマネージド データベース サービスです。

Cloud Run は、Google Cloud インフラストラクチャ上で直接コンテナを実行できるマネージド コンピューティング プラットフォームです。

Cloud SQL インスタンスを設定する

  1. 接続元の Google Cloud プロジェクトで Cloud SQL Admin API を有効にします(まだ有効にしていない場合)。

    Enable the API

  2. Cloud SQL for MySQL インスタンスを作成します。Cloud SQL のインスタンス ロケーションは、Cloud Run サービスと同じリージョンを選択することをおすすめします。このようにすると、レイテンシを短縮して、ネットワーク費用を回避し、リージョン間の障害リスクを軽減することができます。

    Cloud SQL は、デフォルトで新しいインスタンスにパブリック IP アドレスを割り振ります。 プライベート IP アドレスを割り当てることもできます。両方の接続オプションの詳細については、接続の概要ページをご覧ください。

Cloud Run を構成する

Cloud Run を構成する手順は、Cloud SQL インスタンスに割り当てた IP アドレスのタイプによって異なります。すべての下り(外向き)トラフィックをダイレクト VPC 下り(外向き)またはサーバーレス VPC アクセス コネクタ経由でルーティングする場合は、プライベート IP アドレスを使用します。2 つの下り(外向き)ネットワークを比較します

パブリック IP(デフォルト)

  • インスタンスにパブリック IP アドレスがあることを確認します。これは、Google Cloud コンソールのインスタンスの [概要] ページで確認できます。パブリック IP を追加する必要がある場合は、パブリック IP の構成ページの手順をご覧ください。
  • インスタンスの INSTANCE_CONNECTION_NAME を取得します。この値は、Google Cloud コンソールのインスタンスの [概要] ページに表示されます。また、次の gcloud sql instances describe コマンドで確認することもできます。
    gcloud sql instances describe INSTANCE_NAME
       
    INSTANCE_NAME は、Cloud SQL インスタンスの名前に置き換えます。
  • Cloud Run サービスの CLOUD_RUN_SERVICE_ACCOUNT_NAME を取得します。この値は、Google Cloud コンソールで Cloud Run サービスをホストしているプロジェクトの [IAM] ページで確認できます。また、Cloud Run サービスをホストしているプロジェクトで次の gcloud run services describe コマンドを実行して確認することもできます。
    gcloud run services describe CLOUD_RUN_SERVICE_NAME
    --region CLOUD_RUN_SERVICE_REGION --format="value(spec.template.spec.serviceAccountName)"
       
    次の変数を置き換えます。
    • CLOUD_RUN_SERVICE_NAME: Cloud Run サービスの名前
    • CLOUD_RUN_SERVICE_REGION: Cloud Run サービスのリージョン
  • Cloud Run サービスのサービス アカウントを構成します。サービス アカウントに適切な Cloud SQL のロールと Cloud SQL への接続権限があることを確認してください。
    • お使いのサービスのサービス アカウントには、次のいずれかの IAM ロールが必要です。
      • Cloud SQL Client(推奨)
      • Cloud SQL Admin
      または、次の IAM 権限を手動で割り当てることもできます。
      • cloudsql.instances.connect
      • cloudsql.instances.get
  • Cloud SQL 接続を新しいサービスに追加する場合は、サービスをコンテナ化して Container Registry または Artifact Registry にアップロードする必要があります。接続がまだない場合は、コンテナ イメージのビルドとデプロイに関する説明をご覧ください。

他の構成変更の場合と同様に、Cloud SQL 接続に新しい構成を設定すると、新しい Cloud Run リビジョンが作成されます。明示的に更新しない限り、以降のリビジョンでも、この Cloud SQL 接続が自動的に設定されます。

Console

  1. [Cloud Run] に移動

  2. サービスの構成を開始します。Cloud SQL 接続を既存のサービスに追加するには、次の操作を行います。

    1. [サービス] リストで、目的のサービス名をクリックします。
    2. [Cloud Functions で表示] で、サービス名をクリックします。
    3. [編集して再デプロイ] をクリックします。
  3. Cloud SQL インスタンスへの接続を有効にします。
    1. [コンテナ、変数とシークレット、接続、セキュリティ] をクリックします。
    2. [コンテナ] タブをクリックします。
    3. [Cloud SQL 接続] までスクロールします。
    4. [Add connection] をクリックします。
    5. Cloud SQL Admin API をまだ有効にしていない場合は、[Enable the Cloud SQL Admin] ボタンをクリックします。

    Cloud SQL 接続を追加する

    • プロジェクト内の Cloud SQL インスタンスへの接続を追加する場合は、メニューから目的の Cloud SQL インスタンスを選択します。
    • 別のプロジェクトの Cloud SQL インスタンスを使用する場合は、メニューで [カスタムの接続文字列] を選択し、完全なインスタンス接続名を PROJECT-ID:REGION:INSTANCE-ID の形式で入力します。
    • 接続を削除するには、接続の右側にカーソルを置くと表示される 削除アイコンをクリックします。
  4. [作成] または [デプロイ] をクリックします。

コマンドライン

次のコマンドを使用する前に、次のように置き換えます。

  • IMAGE は、デプロイするイメージに置き換えます。
  • SERVICE_NAME は、Cloud Run サービスの名前に置き換えます。
  • INSTANCE_CONNECTION_NAME は、Cloud SQL インスタンスのインスタンス接続名、または接続名のカンマ区切りのリストに置き換えます。

    新しいコンテナをデプロイする場合は、次のコマンドを使用します。

    gcloud run deploy \
      --image=IMAGE \
      --add-cloudsql-instances=INSTANCE_CONNECTION_NAME
    既存のサービスを更新する場合は、次のコマンドを使用します。
    gcloud run services update SERVICE_NAME \
      --add-cloudsql-instances=INSTANCE_CONNECTION_NAME

Terraform

次のコードは、接続された Cloud SQL インスタンスを使用して Cloud Run のベースコンテナを作成します。

resource "google_cloud_run_v2_service" "default" {
  name     = "cloudrun-service"
  location = "us-central1"

  deletion_protection = false # set to "true" in production

  template {
    containers {
      image = "us-docker.pkg.dev/cloudrun/container/hello:latest" # Image to deploy

      volume_mounts {
        name       = "cloudsql"
        mount_path = "/cloudsql"
      }
    }
    volumes {
      name = "cloudsql"
      cloud_sql_instance {
        instances = [google_sql_database_instance.default.connection_name]
      }
    }
  }
  client     = "terraform"
  depends_on = [google_project_service.secretmanager_api, google_project_service.cloudrun_api, google_project_service.sqladmin_api]
}

  1. terraform apply」と入力して変更を適用します。
  2. Cloud Run サービスを確認して、[リビジョン] タブをクリックしてから [接続] タブをクリックし、変更を確認します。

プライベート IP

サービス アカウントの承認が、Cloud SQL インスタンスを含むプロジェクトとは異なるプロジェクトに属している場合、次の操作を行います。

  • 両方のプロジェクトで Cloud SQL Admin API を有効にします。
  • Cloud SQL インスタンスを含むプロジェクトのサービス アカウントに IAM 権限を追加します。
ダイレクト VPC 下り(外向き)とコネクタは、プライベート IP アドレスを使用して VPC ネットワークへの通信を処理します。これらの下り(外向き)方法のいずれかを使用してプライベート IP アドレスに直接接続するには、次の操作を行います。
  1. 事前に作成した Cloud SQL インスタンスにプライベート IP アドレスが割り当てられていることを確認します。内部 IP アドレスを追加するには、プライベート IP を構成するをご覧ください。
  2. Cloud SQL インスタンスと同じ VPC ネットワークに接続するように下り(外向き)メソッドを構成します。次の条件に注意してください。
    • ダイレクト VPC 下り(外向き)とサーバーレス VPC アクセスはどちらも、Cloud VPNVPC ネットワーク ピアリングを使用して接続された VPC ネットワークとの通信をサポートしています。
    • ダイレクト VPC 下り(外向き)とサーバーレス VPC アクセスは、レガシー ネットワークをサポートしていません。
    • 共有 VPC を使用している場合を除き、コネクタは、それを使用するリソースと同じプロジェクトとリージョン内に配置されている必要がありますが、異なるリージョンのリソースにトラフィックを送信できます。
  3. インスタンスのプライベート IP アドレスとポート 3306 を使用して接続します。

Cloud SQL に接続する

Cloud Run を構成すると、Cloud SQL インスタンスに接続できます。

パブリック IP(デフォルト)

パブリック IP パスの場合、Cloud Run は次の 2 つの方法で Cloud SQL Auth Proxyを使用して、暗号化と接続を行います。

Secret Manager を使用する

SQL 認証情報などの機密情報の格納には、Secret Manager を使用することをおすすめします。Cloud Run を使用すると、シークレットを環境変数として渡すか、ボリュームとしてマウントできます。

Secret Manager でシークレットを作成した後、次のコマンドを使用して既存のサービスを更新します。

コマンドライン

gcloud run services update SERVICE_NAME \
  --add-cloudsql-instances=INSTANCE_CONNECTION_NAME
  --update-env-vars=INSTANCE_CONNECTION_NAME=INSTANCE_CONNECTION_NAME_SECRET \
  --update-secrets=DB_USER=DB_USER_SECRET:latest \
  --update-secrets=DB_PASS=DB_PASS_SECRET:latest \
  --update-secrets=DB_NAME=DB_NAME_SECRET:latest

Terraform

以下では、google_secret_manager_secretgoogle_secret_manager_secret_version を使用してデータベース ユーザー、パスワード、名前の値を安全に保持するシークレット リソースを作成します。各シークレットにアクセスできるように、プロジェクトのコンピューティング サービス アカウントを更新する必要があります。


# Create dbuser secret
resource "google_secret_manager_secret" "dbuser" {
  secret_id = "dbusersecret"
  replication {
    auto {}
  }
  depends_on = [google_project_service.secretmanager_api]
}

# Attaches secret data for dbuser secret
resource "google_secret_manager_secret_version" "dbuser_data" {
  secret      = google_secret_manager_secret.dbuser.id
  secret_data = "secret-data" # Stores secret as a plain txt in state
}

# Update service account for dbuser secret
resource "google_secret_manager_secret_iam_member" "secretaccess_compute_dbuser" {
  secret_id = google_secret_manager_secret.dbuser.id
  role      = "roles/secretmanager.secretAccessor"
  member    = "serviceAccount:${data.google_project.project.number}-compute@developer.gserviceaccount.com" # Project's compute service account
}


# Create dbpass secret
resource "google_secret_manager_secret" "dbpass" {
  secret_id = "dbpasssecret"
  replication {
    auto {}
  }
  depends_on = [google_project_service.secretmanager_api]
}

# Attaches secret data for dbpass secret
resource "google_secret_manager_secret_version" "dbpass_data" {
  secret      = google_secret_manager_secret.dbpass.id
  secret_data = "secret-data" # Stores secret as a plain txt in state
}

# Update service account for dbpass secret
resource "google_secret_manager_secret_iam_member" "secretaccess_compute_dbpass" {
  secret_id = google_secret_manager_secret.dbpass.id
  role      = "roles/secretmanager.secretAccessor"
  member    = "serviceAccount:${data.google_project.project.number}-compute@developer.gserviceaccount.com" # Project's compute service account
}


# Create dbname secret
resource "google_secret_manager_secret" "dbname" {
  secret_id = "dbnamesecret"
  replication {
    auto {}
  }
  depends_on = [google_project_service.secretmanager_api]
}

# Attaches secret data for dbname secret
resource "google_secret_manager_secret_version" "dbname_data" {
  secret      = google_secret_manager_secret.dbname.id
  secret_data = "secret-data" # Stores secret as a plain txt in state
}

# Update service account for dbname secret
resource "google_secret_manager_secret_iam_member" "secretaccess_compute_dbname" {
  secret_id = google_secret_manager_secret.dbname.id
  role      = "roles/secretmanager.secretAccessor"
  member    = "serviceAccount:${data.google_project.project.number}-compute@developer.gserviceaccount.com" # Project's compute service account
}

新しいシークレットが含まれるようにメインの Cloud Run リソースを更新します。

resource "google_cloud_run_v2_service" "default" {
  name     = "cloudrun-service"
  location = "us-central1"

  deletion_protection = false # set to "true" in production

  template {
    containers {
      image = "us-docker.pkg.dev/cloudrun/container/hello:latest" # Image to deploy

      # Sets a environment variable for instance connection name
      env {
        name  = "INSTANCE_CONNECTION_NAME"
        value = google_sql_database_instance.default.connection_name
      }
      # Sets a secret environment variable for database user secret
      env {
        name = "DB_USER"
        value_source {
          secret_key_ref {
            secret  = google_secret_manager_secret.dbuser.secret_id # secret name
            version = "latest"                                      # secret version number or 'latest'
          }
        }
      }
      # Sets a secret environment variable for database password secret
      env {
        name = "DB_PASS"
        value_source {
          secret_key_ref {
            secret  = google_secret_manager_secret.dbpass.secret_id # secret name
            version = "latest"                                      # secret version number or 'latest'
          }
        }
      }
      # Sets a secret environment variable for database name secret
      env {
        name = "DB_NAME"
        value_source {
          secret_key_ref {
            secret  = google_secret_manager_secret.dbname.secret_id # secret name
            version = "latest"                                      # secret version number or 'latest'
          }
        }
      }

      volume_mounts {
        name       = "cloudsql"
        mount_path = "/cloudsql"
      }
    }
    volumes {
      name = "cloudsql"
      cloud_sql_instance {
        instances = [google_sql_database_instance.default.connection_name]
      }
    }
  }
  client     = "terraform"
  depends_on = [google_project_service.secretmanager_api, google_project_service.cloudrun_api, google_project_service.sqladmin_api]
}

terraform apply」と入力して変更を適用します。

このコマンドの例では、シークレット バージョン latest を使用していますが、特定のバージョン SECRET_NAME:v1シークレットを固定することをおすすめします。

プライベート IP

プライベート IP パスの場合、アプリケーションは VPC ネットワークを介してインスタンスに直接接続します。この方法では、Cloud SQL Auth Proxy を使用せずに、TCP を使用して Cloud SQL インスタンスに直接接続します。

TCP による接続

Cloud SQL インスタンスのプライベート IP アドレスをホストとポートの 3306 として使用して接続します。

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 MySQL."""
    # 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. 3306

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

Java

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

注:

  • INSTANCE_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 {

  // Saving credentials in environment variables is convenient, but not secure - consider a more
  // secure solution such as 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();

    // The following URL is equivalent to setting the config options below:
    // jdbc:mysql://<INSTANCE_HOST>:<DB_PORT>/<DB_NAME>?user=<DB_USER>&password=<DB_PASS>
    // See the link below for more info on building a JDBC URL for the Cloud SQL JDBC Socket Factory
    // https://github.com/GoogleCloudPlatform/cloud-sql-jdbc-socket-factory#creating-the-jdbc-url

    // Configure which instance and what database user to connect with.
    config.setJdbcUrl(String.format("jdbc:mysql://%s:%s/%s", INSTANCE_HOST, DB_PORT, DB_NAME));
    config.setUsername(DB_USER); // e.g. "root", "mysql"
    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 mysql = require('promise-mysql');
const fs = require('fs');

// createTcpPool initializes a TCP connection pool for a Cloud SQL
// instance of MySQL.
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 = {
    host: process.env.INSTANCE_HOST, // e.g. '127.0.0.1'
    port: process.env.DB_PORT, // e.g. '3306'
    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'
    // ... Specify additional properties here.
    ...config,
  };
  // Establish a connection to the database.
  return mysql.createPool(dbConfig);
};

Go

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

package cloudsql

import (
	"crypto/tls"
	"crypto/x509"
	"database/sql"
	"errors"
	"fmt"
	"io/ioutil"
	"log"
	"os"

	"github.com/go-sql-driver/mysql"
)

// connectTCPSocket initializes a TCP connection pool for a Cloud SQL
// instance of MySQL.
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.", 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'
		dbName    = mustGetenv("DB_NAME")       // e.g. 'my-database'
		dbPort    = mustGetenv("DB_PORT")       // e.g. '3306'
		dbTCPHost = mustGetenv("INSTANCE_HOST") // e.g. '127.0.0.1' ('172.17.0.1' if deployed to GAE Flex)
	)

	dbURI := fmt.Sprintf("%s:%s@tcp(%s:%s)/%s?parseTime=true",
		dbUser, dbPwd, dbTCPHost, dbPort, dbName)


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

	// ...

	return dbPool, nil
}

C#

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

using MySql.Data.MySqlClient;
using System;

namespace CloudSql
{
    public class MySqlTcp
    {
        public static MySqlConnectionStringBuilder NewMysqlTCPConnectionString()
        {
            // Equivalent connection string:
            // "Uid=<DB_USER>;Pwd=<DB_PASS>;Host=<INSTANCE_HOST>;Database=<DB_NAME>;"
            var connectionString = new MySqlConnectionStringBuilder()
            {
                // 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.
                Server = 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'
                Database = Environment.GetEnvironmentVariable("DB_NAME"), // e.g. 'my-database'

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

        }
    }
}

Ruby

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

tcp: &tcp
  adapter: mysql2
  # 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") { 3306 }%>

PHP

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

namespace Google\Cloud\Samples\CloudSQL\MySQL;

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('mysql:dbname=%s;host=%s', $dbName, $instanceHost);

            // 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/mysql/connect-external-app',
                    $e->getMessage()
                ),
                $e->getCode(),
                $e
            );
        }

        return $conn;
    }
}

ベスト プラクティスとその他の情報

アプリケーションをローカルでテストする場合は、Cloud SQL Auth Proxy を使用できます。詳細な手順については、Cloud SQL Auth Proxy を使用するためのクイックスタートをご覧ください。

また、Docker コンテナ経由で Cloud SQL Proxy を使用してもテストできます。

接続プール

データベースサーバー自体またはプラットフォーム インフラストラクチャによって、基盤となるデータベースとの接続が切断される可能性があります。切断されたクライアント接続を自動的に再接続する接続プールをサポートするクライアント ライブラリを使用することをおすすめします。接続プールの使用方法の詳しい例については、データベース接続の管理ページをご覧ください。

接続上限

Cloud SQL の MySQL エディションと PostgreSQL エディションの両方で、同時接続の上限が設定されています。これらの上限は、選択したデータベース エンジンによって異なります(詳しくは、Cloud SQL の割り当てと上限ページをご覧ください)。

Cloud Run コンテナ インスタンスは、Cloud SQL データベースに対して 100 接続に制限されています。Cloud Run サービスまたはジョブの各インスタンスには、データベースに対して 100 個の接続を含めることができます。このサービスまたはジョブがスケーリングすると、デプロイあたりの接続の合計数が増加する可能性があります。

インスタンスごとの最大接続数は、接続プールを使用して制限できます。接続数の制限方法の詳しい例については、データベース接続の管理ページをご覧ください。

API の割り当て上限

Cloud Run には、Cloud SQL Admin API を使用する Cloud SQL Auth Proxy で接続する仕組みが用意されています。Cloud SQL Auth Proxy には API 割り当て上限が適用されます。使用される Cloud SQL Admin API の割り当ては、一度にデプロイされる特定のサービスの Cloud Run インスタンス数によって構成される Cloud SQL インスタンス数の約 2 倍です。想定される API 割り当ての使用量を変更するには、Cloud Run インスタンスの数を制限するか、増やしてください

次のステップ