Cloud Run(フルマネージド)から Cloud SQL に接続する

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

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

Cloud SQL インスタンスの設定

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

    API を有効にする

  2. Cloud SQL for MySQL インスタンスを作成します

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

Cloud Run を構成する(フルマネージド)

Cloud Run(フルマネージド)を構成する手順は、Cloud SQL インスタンスに割り当てた IP アドレスのタイプによって異なります。

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

  • 作成したインスタンスにパブリック IP アドレスがあることを確認します。これは、Google Cloud Console のインスタンスの [概要] ページで確認できます。パブリック IP を追加する必要がある場合は、パブリック IP の構成ページの手順をご覧ください。
  • インスタンスの INSTANCE_CONNECTION_NAME を取得します。これは、Google Cloud Console のインスタンスの [概要] ページで確認できます。また、コマンド gcloud sql instances describe [INSTANCE_NAME] を実行して確認することもできます。
  • サービスが Cloud SQL の呼び出しを認証するために使用しているサービス アカウントに、適切な Cloud SQL のロールと権限があることを確認します。
      お使いのサービスのサービス アカウントには、次のいずれかの IAM ロールが必要です。
      • Cloud SQL Client(推奨)
      • Cloud SQL Editor
      • Cloud SQL Admin
      または、次の IAM 権限を手動で割り当てることもできます。
      • cloudsql.instances.connect
      • cloudsql.instances.get
      サービス アカウントに IAM ロールを追加する方法の詳細については、サービス アカウントへのロールの付与をご覧ください。

    デフォルトでは、アプリは Cloud Run(フルマネージド)サービス アカウントを使用して接続を認可します。サービス アカウントの形式は PROJECT_NUMBER-compute@developer.gserviceaccount.com です。

    サービス アカウントの承認が Cloud SQL インスタンスとは異なるプロジェクトに属している場合、Cloud SQL Admin API と IAM の権限を両方のプロジェクトに追加する必要があります。

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

Console

  1. Cloud Run に移動します

  2. サービスを構成します。

    • Cloud SQL 接続を新しいサービスに追加する場合:

      • サービスをコンテナ化して Container Registry にアップロードする必要があります。コンテナ イメージがまだない場合は、コンテナ イメージのビルドとデプロイに関する説明をご覧ください。

      • [サービスの作成] をクリックします。

    • Cloud SQL 接続を既存のサービスに追加する場合:

      • サービス名をクリックします。

      • [新しいリビジョンをデプロイ] をクリックします。

  3. Cloud SQL への接続を有効にします。

    • [オプションの設定を表示] をクリックします。

    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 \
      --update-env-vars INSTANCE_CONNECTION_NAME="INSTANCE-CONNECTION-NAME"
    既存のサービスを更新する場合は、次のコマンドを使用します。
    gcloud run services update SERVICE-NAME \
      --add-cloudsql-instances INSTANCE-CONNECTION-NAME \
      --update-env-vars INSTANCE_CONNECTION_NAME="INSTANCE-CONNECTION-NAME"

プライベート IP

サーバーレス VPC アクセス コネクタは VPC ネットワークとの通信を処理します。 プライベート IP に直接接続するには、次のようにする必要があります。

  1. 上記で作成した Cloud SQL インスタンスにプライベート IP アドレスが割り当てられていることを確認します。プライベート IP を追加する必要がある場合は、プライベート IP の構成ページの手順をご覧ください。
  2. Cloud SQL インスタンスと同じ VPC ネットワークにサーバーレス VPC アクセス コネクタを作成します。
  3. 共有 VPC を使用している場合を除き、コネクタは、それを使用するリソースと同じプロジェクトとリージョン内に配置されている必要がありますが、異なるリージョンのリソースにトラフィックを送信できます。

    サーバーレス VPC アクセスでは、Cloud VPNVPC ネットワーク ピアリングを介して接続された VPC ネットワークとの通信がサポートされています。

    サーバーレス VPC アクセスは、レガシー ネットワークをサポートしていません。

  4. コネクタを使用するように Cloud Run(フルマネージド)を構成します
  5. インスタンスのプライベート IP とポート 3306 を使用して接続します。

Cloud SQL への接続

Cloud Run(フルマネージド)を構成すると、Cloud SQL インスタンスに接続できます。Cloud Run(フルマネージド)では、Cloud SQL Proxy を使用して接続する仕組みが用意されています。

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

プライベート IP

TCP で接続

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

Python

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

# Remember - storing secrets in plaintext is potentially unsafe. Consider using
# something like https://cloud.google.com/secret-manager/docs/overview to help keep
# secrets secret.
db_user = os.environ["DB_USER"]
db_pass = os.environ["DB_PASS"]
db_name = os.environ["DB_NAME"]
db_host = os.environ["DB_HOST"]

# Extract host and port from db_host
host_args = db_host.split(":")
db_hostname, db_port = host_args[0], int(host_args[1])

pool = sqlalchemy.create_engine(
    # Equivalent URL:
    # mysql+pymysql://<db_user>:<db_pass>@<db_host>:<db_port>/<db_name>
    sqlalchemy.engine.url.URL(
        drivername="mysql+pymysql",
        username=db_user,  # e.g. "my-database-user"
        password=db_pass,  # e.g. "my-database-password"
        host=db_hostname,  # e.g. "127.0.0.1"
        port=db_port,  # e.g. 3306
        database=db_name,  # e.g. "my-database-name"
    ),
    # ... Specify additional properties here.
)

Node.js

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

const createTcpPool = async (config) => {
  // Extract host and port from socket address
  const dbSocketAddr = process.env.DB_HOST.split(":")

  // Establish a connection to the database
  return await mysql.createPool({
    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'
    host: dbSocketAddr[0], // e.g. '127.0.0.1'
    port: dbSocketAddr[1], // e.g. '3306'
    // ... Specify additional properties here.
    ...config
  });
}

Go

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

var (
	dbUser    = mustGetenv("DB_USER")     // e.g. 'my-db-user'
	dbPwd     = mustGetenv("DB_PASS")     // e.g. 'my-db-password'
	dbTcpHost = mustGetenv("DB_TCP_HOST") // e.g. '127.0.0.1' ('172.17.0.1' if deployed to GAE Flex)
	dbPort    = mustGetenv("DB_PORT")     // e.g. '3306'
	dbName    = mustGetenv("DB_NAME")     // e.g. 'my-database'
)

var dbURI string
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: %v", err)
}

// ...

return dbPool, nil

C#

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

            // Equivalent connection string:
            // "Uid=<DB_USER>;Pwd=<DB_PASS>;Host=<DB_HOST>;Database=<DB_NAME>;"
            var connectionString = new MySqlConnectionStringBuilder()
            {
                // The Cloud SQL proxy provides encryption between the proxy and instance.
                SslMode = MySqlSslMode.None,

                // Remember - storing secrets in plaintext is potentially unsafe. Consider using
                // something like https://cloud.google.com/secret-manager/docs/overview to help keep
                // secrets secret.
                Server = Environment.GetEnvironmentVariable("DB_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'
            };
            connectionString.Pooling = true;
            // Specify additional properties here.
            // ...
            DbConnection connection =
                new MySqlConnection(connectionString.ConnectionString);

Ruby

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

development:
  adapter: mysql2
  # Configure additional properties here
  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("DB_HOST") { "127.0.0.1" }%> # '172.17.0.1' if deployed to GAE Flex
  port: <%= ENV.fetch("DB_PORT") { 3306 }%> 

PHP

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

// // $username = 'your_db_user';
// // $password = 'yoursupersecretpassword';
// // $db_name = 'your_db_name';
// // $host = "127.0.0.1";

// Connect using TCP
$dsn = sprintf('mysql:dbname=%s;host=%s', $db_name, $host);

// Connect to the database.
$conn = new PDO($dsn, $username, $password, $conn_config);

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

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

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

接続プール

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

接続上限

Cloud SQL の MySQL エディションと PostgreSQL エディションの両方で、同時接続の上限が設定されています。これらの上限は、選択したデータベース エンジンによって異なります。詳しくは、Cloud SQL の割り当てと上限ページをご覧ください。Cloud Run(フルマネージド)では、負荷の増加に応じて自動的にインスタンスが作成されるため、これらの上限を超える可能性があります。インスタンスごとの最大接続数は、接続プールを使用して制限できます。接続数の制限方法の詳しい例については、データベース接続の管理ページをご覧ください。

API の割り当て上限

Cloud Run(フルマネージド)には、Cloud SQL Admin API を使用する Cloud SQL Proxy で接続する仕組みが用意されています。Cloud SQL Proxy には API 割り当て上限が適用されます。

次のステップ