Conectarse desde las funciones de Cloud Run

Esta página contiene información y ejemplos para conectarse a una instancia de Cloud SQL desde un servicio que se ejecuta en funciones de Cloud Run.

Para obtener instrucciones paso a paso sobre cómo ejecutar una aplicación web de muestra de funciones de Cloud Run conectada a Cloud SQL, consulte la guía de inicio rápido para conectarse desde funciones de Cloud Run .

Cloud SQL es un servicio de base de datos completamente administrado que le ayuda a configurar, mantener, administrar y gestionar sus bases de datos relacionales en la nube.

Las funciones de Cloud Run son una solución informática liviana que permite a los desarrolladores crear funciones independientes y de propósito único que responden a eventos de la nube sin la necesidad de administrar un servidor o un entorno de ejecución.

Configurar una instancia de Cloud SQL

  1. Habilite la API de administración de Cloud SQL en el Google Cloud proyecto desde el que te estás conectando, si aún no lo has hecho:

    Enable the API

  2. Cree una instancia de Cloud SQL para PostgreSQL . Le recomendamos que elija una ubicación de instancia de Cloud SQL en la misma región que su servicio Cloud Run para mejorar la latencia, evitar costos de red y reducir el riesgo de fallos entre regiones.

    De forma predeterminada, Cloud SQL asigna una dirección IP pública a cada nueva instancia. También puede asignar una dirección IP privada. Para obtener más información sobre las opciones de conectividad para ambas instancias, consulte la página "Resumen de la conexión" .

Configurar funciones de Cloud Run

Los pasos para configurar las funciones de Cloud Run dependen del tipo de dirección IP que haya asignado a su instancia de Cloud SQL.

IP pública (predeterminada)

Para configurar las funciones de Cloud Run para habilitar conexiones a una instancia de Cloud SQL:

  • Confirme que la instancia creada anteriormente tenga una dirección IP pública. Puede confirmarlo en la página Descripción general de la instancia en el Google Cloud consola . Si necesita agregar una dirección IP pública, consulte Configurar IP pública .
  • Obtener el INSTANCE_CONNECTION_NAME de la instancia. Este valor está disponible:
    • En la página Descripción general de la instancia, en el Google Cloud consola , o
    • Ejecutando el siguiente comando: gcloud sql instances describe [INSTANCE_NAME]
  • Configure la cuenta de servicio para su función. Si la cuenta de servicio que autoriza pertenece a un proyecto diferente al de la instancia de Cloud SQL, debe habilitar la API de administración de Cloud SQL y agregar el rol de IAM Cloud SQL Client a ambos proyectos.
  • Confirme que la cuenta de servicio tenga esta función para que pueda conectarse a Cloud SQL.
  • Si está utilizando funciones de Cloud Run y ​​no funciones de Cloud Run (1.ª generación) , se requieren los siguientes requisitos (consulte también Configurar Cloud Run ):
    1. Implemente inicialmente su función.
      Cuando comience a crear una función de Cloud Run en el Google Cloud Consola: el servicio subyacente de Cloud Run aún no se ha creado. No se puede configurar una conexión a Cloud SQL hasta que se cree dicho servicio (mediante la implementación de la función de Cloud Run).
    2. En el Google Cloud consola, en la parte superior derecha de la página Detalles de la función , en Desarrollado por Cloud Run , haga clic en el enlace para acceder al servicio Cloud Run subyacente.
    3. En la página de detalles del servicio Cloud Run, seleccione la pestaña Editar e implementar nueva revisión .
    4. Siga los pasos estándar (como en el caso de cualquier cambio de configuración) para establecer una nueva configuración para una conexión de Cloud SQL.
      Esto crea una nueva revisión de Cloud Run y ​​las revisiones posteriores reciben automáticamente esta conexión de Cloud SQL, a menos que la cambie explícitamente.

IP privada

Si la cuenta de servicio autorizadora pertenece a un proyecto diferente al que contiene la instancia de Cloud SQL, haga lo siguiente:

  • En ambos proyectos, habilite la API de administración de Cloud SQL.
  • Para la cuenta de servicio en el proyecto que contiene la instancia de Cloud SQL, agregue los permisos de IAM .
Un conector de acceso a VPC sin servidor utiliza direcciones IP privadas para gestionar la comunicación con su red de VPC. Para conectarse directamente con direcciones IP privadas, debe hacer lo siguiente:
  1. Asegúrese de que la instancia de Cloud SQL creada previamente tenga una dirección IP privada. Si necesita agregar una, consulte Configurar una IP privada para obtener instrucciones.
  2. Cree un conector de acceso a VPC sin servidor en la misma red de VPC que su instancia de Cloud SQL. Tenga en cuenta las siguientes condiciones:
    • A menos que estés usando VPC compartida , tu conector debe estar en el mismo proyecto y región que el recurso que lo usa, pero puede enviar tráfico a recursos en diferentes regiones.
    • El acceso a VPC sin servidor admite la comunicación con redes VPC conectadas mediante Cloud VPN y VPC Network Peering .
    • El acceso a VPC sin servidor no es compatible con redes heredadas .
  3. Configure las funciones de Cloud Run para usar el conector.
  4. Conéctese utilizando la dirección IP privada de su instancia y el puerto 5432 .

Conectarse a Cloud SQL

Después de configurar las funciones de Cloud Run, puede conectarse a su instancia de Cloud SQL.

IP pública (predeterminada)

Para las rutas de IP públicas, las funciones de Cloud Run proporcionan cifrado y se conectan mediante el proxy de autenticación de Cloud SQL de dos maneras:

IP privada

Para las rutas IP privadas, la aplicación se conecta directamente a la instancia a través de una red VPC. Este método utiliza TCP para conectarse directamente a la instancia de Cloud SQL sin usar el proxy de autenticación de Cloud SQL.

Conectarse con TCP

Conéctese utilizando la dirección IP privada de su instancia de Cloud SQL como host y el puerto 5432 .

Pitón

Para ver este fragmento en el contexto de una aplicación web, consulte el archivo README en GitHub .

import os
import ssl

import sqlalchemy


def connect_tcp_socket() -> sqlalchemy.engine.base.Engine:
    """Initializes a TCP connection pool for a Cloud SQL instance of Postgres."""
    # 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. 5432

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

Java

Para ver este fragmento en el contexto de una aplicación web, consulte el archivo README en GitHub .

Nota:

  • CLOUD_SQL_CONNECTION_NAME debe representarse como <MI-PROYECTO>:<REGIÓN-DE-INSTANCIA>:<NOMBRE-DE-INSTANCIA>
  • El uso del argumento ipTypes=PRIVATE obligará a SocketFactory a conectarse con la IP privada asociada a una instancia
  • Consulte los requisitos de la versión de fábrica del socket JDBC para el archivo pom.xml aquí .


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();

    // The following URL is equivalent to setting the config options below:
    // jdbc:postgresql://<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:postgresql://%s:%s/%s", INSTANCE_HOST, DB_PORT, DB_NAME));
    config.setUsername(DB_USER); // e.g. "root", "postgres"
    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

Para ver este fragmento en el contexto de una aplicación web, consulte el archivo README en GitHub .

const Knex = require('knex');
const fs = require('fs');

// createTcpPool initializes a TCP connection pool for a Cloud SQL
// instance of Postgres.
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 = {
    client: 'pg',
    connection: {
      host: process.env.INSTANCE_HOST, // e.g. '127.0.0.1'
      port: process.env.DB_PORT, // e.g. '5432'
      user: process.env.DB_USER, // e.g. 'my-user'
      password: process.env.DB_PASS, // e.g. 'my-user-password'
      database: process.env.DB_NAME, // e.g. 'my-database'
    },
    // ... Specify additional properties here.
    ...config,
  };
  // Establish a connection to the database.
  return Knex(dbConfig);
};

Ir

Para ver este fragmento en el contexto de una aplicación web, consulte el archivo README en GitHub .

package cloudsql

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

	// Note: If connecting using the App Engine Flex Go runtime, use
	// "github.com/jackc/pgx/stdlib" instead, since v5 requires
	// Go modules which are not supported by App Engine Flex.
	_ "github.com/jackc/pgx/v5/stdlib"
)

// connectTCPSocket initializes a TCP connection pool for a Cloud SQL
// instance of Postgres.
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'
		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. '5432'
		dbName    = mustGetenv("DB_NAME")       // e.g. 'my-database'
	)

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


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

	// ...

	return dbPool, nil
}

PHP

Para ver este fragmento en el contexto de una aplicación web, consulte el archivo README en GitHub .

namespace Google\Cloud\Samples\CloudSQL\Postgres;

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

        return $conn;
    }
}

Mejores prácticas y otra información

Puedes usar el proxy de autenticación de Cloud SQL al probar tu aplicación localmente. Consulta la guía de inicio rápido para usar el proxy de autenticación de Cloud SQL para obtener instrucciones detalladas.

Grupos de conexiones

Las conexiones a las bases de datos subyacentes pueden interrumpirse, ya sea por el propio servidor de bases de datos o por la infraestructura subyacente a las funciones de Cloud Run. Recomendamos usar una biblioteca cliente compatible con grupos de conexiones que reconectan automáticamente las conexiones de cliente interrumpidas. Además, recomendamos usar un grupo de conexiones de alcance global para aumentar la probabilidad de que la función reutilice la misma conexión en invocaciones posteriores y la cierre automáticamente cuando se expulse la instancia (reducción automática de escala). Para obtener ejemplos más detallados sobre cómo usar grupos de conexiones, consulte Administrar conexiones de bases de datos .

Límites de conexión

Cloud SQL impone un límite máximo de conexiones simultáneas, que puede variar según el motor de base de datos elegido (consulte Cuotas y límites de Cloud SQL ). Se recomienda usar una conexión con funciones de Cloud Run, pero es importante establecer el número máximo de conexiones en 1.

Siempre que sea posible, asegúrese de inicializar un grupo de conexiones solo para las funciones que necesitan acceder a su base de datos. Algunos grupos de conexiones crean conexiones de forma preventiva, lo que puede consumir recursos excesivos y contabilizarse en sus límites de conexión. Por este motivo, se recomienda usar la inicialización diferida para retrasar la creación de un grupo de conexiones hasta que sea necesario e incluirlo solo en las funciones donde se utilice.

Para obtener ejemplos más detallados sobre cómo limitar la cantidad de conexiones, consulte Administrar conexiones de base de datos .

Límites de cuota de API

Las funciones de Cloud Run proporcionan un mecanismo que se conecta mediante el proxy de autenticación de Cloud SQL, que utiliza la API de administración de Cloud SQL. Se aplican límites de cuota de API al proxy de autenticación de Cloud SQL. La cuota de la API de administración de Cloud SQL utilizada es aproximadamente el doble de la cantidad de instancias de Cloud SQL configuradas multiplicada por la cantidad total de funciones implementadas. Puede establecer el número máximo de invocaciones simultáneas para modificar la cuota de API esperada consumida. Las funciones de Cloud Run también imponen límites de frecuencia en la cantidad de llamadas a la API permitidas cada 100 segundos.

¿Qué sigue?

,

Esta página contiene información y ejemplos para conectarse a una instancia de Cloud SQL desde un servicio que se ejecuta en funciones de Cloud Run.

Para obtener instrucciones paso a paso sobre cómo ejecutar una aplicación web de muestra de funciones de Cloud Run conectada a Cloud SQL, consulte la guía de inicio rápido para conectarse desde funciones de Cloud Run .

Cloud SQL es un servicio de base de datos completamente administrado que le ayuda a configurar, mantener, administrar y gestionar sus bases de datos relacionales en la nube.

Las funciones de Cloud Run son una solución informática liviana que permite a los desarrolladores crear funciones independientes y de propósito único que responden a eventos de la nube sin la necesidad de administrar un servidor o un entorno de ejecución.

Configurar una instancia de Cloud SQL

  1. Habilite la API de administración de Cloud SQL en el Google Cloud proyecto desde el que te estás conectando, si aún no lo has hecho:

    Enable the API

  2. Cree una instancia de Cloud SQL para PostgreSQL . Le recomendamos que elija una ubicación de instancia de Cloud SQL en la misma región que su servicio Cloud Run para mejorar la latencia, evitar costos de red y reducir el riesgo de fallos entre regiones.

    De forma predeterminada, Cloud SQL asigna una dirección IP pública a cada nueva instancia. También puede asignar una dirección IP privada. Para obtener más información sobre las opciones de conectividad para ambas instancias, consulte la página "Resumen de la conexión" .

Configurar funciones de Cloud Run

Los pasos para configurar las funciones de Cloud Run dependen del tipo de dirección IP que haya asignado a su instancia de Cloud SQL.

IP pública (predeterminada)

Para configurar las funciones de Cloud Run para habilitar conexiones a una instancia de Cloud SQL:

  • Confirme que la instancia creada anteriormente tenga una dirección IP pública. Puede confirmarlo en la página Descripción general de la instancia en el Google Cloud consola . Si necesita agregar una dirección IP pública, consulte Configurar IP pública .
  • Obtener el INSTANCE_CONNECTION_NAME de la instancia. Este valor está disponible:
    • En la página Descripción general de la instancia, en el Google Cloud consola , o
    • Ejecutando el siguiente comando: gcloud sql instances describe [INSTANCE_NAME]
  • Configure la cuenta de servicio para su función. Si la cuenta de servicio que autoriza pertenece a un proyecto diferente al de la instancia de Cloud SQL, debe habilitar la API de administración de Cloud SQL y agregar el rol de IAM Cloud SQL Client a ambos proyectos.
  • Confirme que la cuenta de servicio tenga esta función para que pueda conectarse a Cloud SQL.
  • Si está utilizando funciones de Cloud Run y ​​no funciones de Cloud Run (1.ª generación) , se requieren los siguientes requisitos (consulte también Configurar Cloud Run ):
    1. Implemente inicialmente su función.
      Cuando comience a crear una función de Cloud Run en el Google Cloud Consola: el servicio subyacente de Cloud Run aún no se ha creado. No se puede configurar una conexión a Cloud SQL hasta que se cree dicho servicio (mediante la implementación de la función de Cloud Run).
    2. En el Google Cloud consola, en la parte superior derecha de la página Detalles de la función , en Desarrollado por Cloud Run , haga clic en el enlace para acceder al servicio Cloud Run subyacente.
    3. En la página de detalles del servicio Cloud Run, seleccione la pestaña Editar e implementar nueva revisión .
    4. Siga los pasos estándar (como en el caso de cualquier cambio de configuración) para establecer una nueva configuración para una conexión de Cloud SQL.
      Esto crea una nueva revisión de Cloud Run y ​​las revisiones posteriores reciben automáticamente esta conexión de Cloud SQL, a menos que la cambie explícitamente.

IP privada

Si la cuenta de servicio autorizadora pertenece a un proyecto diferente al que contiene la instancia de Cloud SQL, haga lo siguiente:

  • En ambos proyectos, habilite la API de administración de Cloud SQL.
  • Para la cuenta de servicio en el proyecto que contiene la instancia de Cloud SQL, agregue los permisos de IAM .
Un conector de acceso a VPC sin servidor utiliza direcciones IP privadas para gestionar la comunicación con su red de VPC. Para conectarse directamente con direcciones IP privadas, debe hacer lo siguiente:
  1. Asegúrese de que la instancia de Cloud SQL creada previamente tenga una dirección IP privada. Si necesita agregar una, consulte Configurar una IP privada para obtener instrucciones.
  2. Cree un conector de acceso a VPC sin servidor en la misma red de VPC que su instancia de Cloud SQL. Tenga en cuenta las siguientes condiciones:
    • A menos que estés usando VPC compartida , tu conector debe estar en el mismo proyecto y región que el recurso que lo usa, pero puede enviar tráfico a recursos en diferentes regiones.
    • El acceso a VPC sin servidor admite la comunicación con redes VPC conectadas mediante Cloud VPN y VPC Network Peering .
    • El acceso a VPC sin servidor no es compatible con redes heredadas .
  3. Configure las funciones de Cloud Run para usar el conector.
  4. Conéctese utilizando la dirección IP privada de su instancia y el puerto 5432 .

Conectarse a Cloud SQL

Después de configurar las funciones de Cloud Run, puede conectarse a su instancia de Cloud SQL.

IP pública (predeterminada)

Para las rutas de IP públicas, las funciones de Cloud Run proporcionan cifrado y se conectan mediante el proxy de autenticación de Cloud SQL de dos maneras:

IP privada

Para las rutas IP privadas, la aplicación se conecta directamente a la instancia a través de una red VPC. Este método utiliza TCP para conectarse directamente a la instancia de Cloud SQL sin usar el proxy de autenticación de Cloud SQL.

Conectarse con TCP

Conéctese utilizando la dirección IP privada de su instancia de Cloud SQL como host y el puerto 5432 .

Pitón

Para ver este fragmento en el contexto de una aplicación web, consulte el archivo README en GitHub .

import os
import ssl

import sqlalchemy


def connect_tcp_socket() -> sqlalchemy.engine.base.Engine:
    """Initializes a TCP connection pool for a Cloud SQL instance of Postgres."""
    # 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. 5432

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

Java

Para ver este fragmento en el contexto de una aplicación web, consulte el archivo README en GitHub .

Nota:

  • CLOUD_SQL_CONNECTION_NAME debe representarse como <MI-PROYECTO>:<REGIÓN-DE-INSTANCIA>:<NOMBRE-DE-INSTANCIA>
  • El uso del argumento ipTypes=PRIVATE obligará a SocketFactory a conectarse con la IP privada asociada a una instancia
  • Consulte los requisitos de la versión de fábrica del socket JDBC para el archivo pom.xml aquí .


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();

    // The following URL is equivalent to setting the config options below:
    // jdbc:postgresql://<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:postgresql://%s:%s/%s", INSTANCE_HOST, DB_PORT, DB_NAME));
    config.setUsername(DB_USER); // e.g. "root", "postgres"
    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

Para ver este fragmento en el contexto de una aplicación web, consulte el archivo README en GitHub .

const Knex = require('knex');
const fs = require('fs');

// createTcpPool initializes a TCP connection pool for a Cloud SQL
// instance of Postgres.
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 = {
    client: 'pg',
    connection: {
      host: process.env.INSTANCE_HOST, // e.g. '127.0.0.1'
      port: process.env.DB_PORT, // e.g. '5432'
      user: process.env.DB_USER, // e.g. 'my-user'
      password: process.env.DB_PASS, // e.g. 'my-user-password'
      database: process.env.DB_NAME, // e.g. 'my-database'
    },
    // ... Specify additional properties here.
    ...config,
  };
  // Establish a connection to the database.
  return Knex(dbConfig);
};

Ir

Para ver este fragmento en el contexto de una aplicación web, consulte el archivo README en GitHub .

package cloudsql

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

	// Note: If connecting using the App Engine Flex Go runtime, use
	// "github.com/jackc/pgx/stdlib" instead, since v5 requires
	// Go modules which are not supported by App Engine Flex.
	_ "github.com/jackc/pgx/v5/stdlib"
)

// connectTCPSocket initializes a TCP connection pool for a Cloud SQL
// instance of Postgres.
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'
		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. '5432'
		dbName    = mustGetenv("DB_NAME")       // e.g. 'my-database'
	)

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


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

	// ...

	return dbPool, nil
}

PHP

Para ver este fragmento en el contexto de una aplicación web, consulte el archivo README en GitHub .

namespace Google\Cloud\Samples\CloudSQL\Postgres;

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

        return $conn;
    }
}

Mejores prácticas y otra información

Puedes usar el proxy de autenticación de Cloud SQL al probar tu aplicación localmente. Consulta la guía de inicio rápido para usar el proxy de autenticación de Cloud SQL para obtener instrucciones detalladas.

Grupos de conexiones

Las conexiones a las bases de datos subyacentes pueden interrumpirse, ya sea por el propio servidor de bases de datos o por la infraestructura subyacente a las funciones de Cloud Run. Recomendamos usar una biblioteca cliente compatible con grupos de conexiones que reconectan automáticamente las conexiones de cliente interrumpidas. Además, recomendamos usar un grupo de conexiones de alcance global para aumentar la probabilidad de que la función reutilice la misma conexión en invocaciones posteriores y la cierre automáticamente cuando se expulse la instancia (reducción automática de escala). Para obtener ejemplos más detallados sobre cómo usar grupos de conexiones, consulte Administrar conexiones de bases de datos .

Límites de conexión

Cloud SQL impone un límite máximo de conexiones simultáneas, que puede variar según el motor de base de datos elegido (consulte Cuotas y límites de Cloud SQL ). Se recomienda usar una conexión con funciones de Cloud Run, pero es importante establecer el número máximo de conexiones en 1.

Siempre que sea posible, asegúrese de inicializar un grupo de conexiones solo para las funciones que necesitan acceder a su base de datos. Algunos grupos de conexiones crean conexiones de forma preventiva, lo que puede consumir recursos excesivos y contabilizarse en sus límites de conexión. Por este motivo, se recomienda usar la inicialización diferida para retrasar la creación de un grupo de conexiones hasta que sea necesario e incluirlo solo en las funciones donde se utilice.

Para obtener ejemplos más detallados sobre cómo limitar la cantidad de conexiones, consulte Administrar conexiones de base de datos .

Límites de cuota de API

Las funciones de Cloud Run proporcionan un mecanismo que se conecta mediante el proxy de autenticación de Cloud SQL, que utiliza la API de administración de Cloud SQL. Se aplican límites de cuota de API al proxy de autenticación de Cloud SQL. La cuota de la API de administración de Cloud SQL utilizada es aproximadamente el doble de la cantidad de instancias de Cloud SQL configuradas multiplicada por la cantidad total de funciones implementadas. Puede establecer el número máximo de invocaciones simultáneas para modificar la cuota de API esperada consumida. Las funciones de Cloud Run también imponen límites de frecuencia en la cantidad de llamadas a la API permitidas cada 100 segundos.

¿Qué sigue?

,

Esta página contiene información y ejemplos para conectarse a una instancia de Cloud SQL desde un servicio que se ejecuta en funciones de Cloud Run.

Para obtener instrucciones paso a paso sobre cómo ejecutar una aplicación web de muestra de funciones de Cloud Run conectada a Cloud SQL, consulte la guía de inicio rápido para conectarse desde funciones de Cloud Run .

Cloud SQL es un servicio de base de datos completamente administrado que le ayuda a configurar, mantener, administrar y gestionar sus bases de datos relacionales en la nube.

Las funciones de Cloud Run son una solución informática liviana que permite a los desarrolladores crear funciones independientes y de propósito único que responden a eventos de la nube sin la necesidad de administrar un servidor o un entorno de ejecución.

Configurar una instancia de Cloud SQL

  1. Habilite la API de administración de Cloud SQL en el Google Cloud proyecto desde el que te estás conectando, si aún no lo has hecho:

    Enable the API

  2. Cree una instancia de Cloud SQL para PostgreSQL . Le recomendamos que elija una ubicación de instancia de Cloud SQL en la misma región que su servicio Cloud Run para mejorar la latencia, evitar costos de red y reducir el riesgo de fallos entre regiones.

    De forma predeterminada, Cloud SQL asigna una dirección IP pública a cada nueva instancia. También puede asignar una dirección IP privada. Para obtener más información sobre las opciones de conectividad para ambas instancias, consulte la página "Resumen de la conexión" .

Configurar funciones de Cloud Run

Los pasos para configurar las funciones de Cloud Run dependen del tipo de dirección IP que haya asignado a su instancia de Cloud SQL.

IP pública (predeterminada)

Para configurar las funciones de Cloud Run para habilitar conexiones a una instancia de Cloud SQL:

  • Confirme que la instancia creada anteriormente tenga una dirección IP pública. Puede confirmarlo en la página Descripción general de la instancia en el Google Cloud consola . Si necesita agregar una dirección IP pública, consulte Configurar IP pública .
  • Obtener el INSTANCE_CONNECTION_NAME de la instancia. Este valor está disponible:
    • En la página Descripción general de la instancia, en el Google Cloud consola , o
    • Ejecutando el siguiente comando: gcloud sql instances describe [INSTANCE_NAME]
  • Configure la cuenta de servicio para su función. Si la cuenta de servicio que autoriza pertenece a un proyecto diferente al de la instancia de Cloud SQL, debe habilitar la API de administración de Cloud SQL y agregar el rol de IAM Cloud SQL Client a ambos proyectos.
  • Confirme que la cuenta de servicio tenga esta función para que pueda conectarse a Cloud SQL.
  • Si está utilizando funciones de Cloud Run y ​​no funciones de Cloud Run (1.ª generación) , se requieren los siguientes requisitos (consulte también Configurar Cloud Run ):
    1. Implemente inicialmente su función.
      Cuando comience a crear una función de Cloud Run en el Google Cloud Consola: el servicio subyacente de Cloud Run aún no se ha creado. No se puede configurar una conexión a Cloud SQL hasta que se cree dicho servicio (mediante la implementación de la función de Cloud Run).
    2. En el Google Cloud consola, en la parte superior derecha de la página Detalles de la función , en Desarrollado por Cloud Run , haga clic en el enlace para acceder al servicio Cloud Run subyacente.
    3. En la página de detalles del servicio Cloud Run, seleccione la pestaña Editar e implementar nueva revisión .
    4. Siga los pasos estándar (como en el caso de cualquier cambio de configuración) para establecer una nueva configuración para una conexión de Cloud SQL.
      Esto crea una nueva revisión de Cloud Run y ​​las revisiones posteriores reciben automáticamente esta conexión de Cloud SQL, a menos que la cambie explícitamente.

IP privada

Si la cuenta de servicio autorizadora pertenece a un proyecto diferente al que contiene la instancia de Cloud SQL, haga lo siguiente:

  • En ambos proyectos, habilite la API de administración de Cloud SQL.
  • Para la cuenta de servicio en el proyecto que contiene la instancia de Cloud SQL, agregue los permisos de IAM .
Un conector de acceso a VPC sin servidor utiliza direcciones IP privadas para gestionar la comunicación con su red de VPC. Para conectarse directamente con direcciones IP privadas, debe hacer lo siguiente:
  1. Asegúrese de que la instancia de Cloud SQL creada previamente tenga una dirección IP privada. Si necesita agregar una, consulte Configurar una IP privada para obtener instrucciones.
  2. Cree un conector de acceso a VPC sin servidor en la misma red de VPC que su instancia de Cloud SQL. Tenga en cuenta las siguientes condiciones:
    • A menos que estés usando VPC compartida , tu conector debe estar en el mismo proyecto y región que el recurso que lo usa, pero puede enviar tráfico a recursos en diferentes regiones.
    • El acceso a VPC sin servidor admite la comunicación con redes VPC conectadas mediante Cloud VPN y VPC Network Peering .
    • El acceso a VPC sin servidor no es compatible con redes heredadas .
  3. Configure las funciones de Cloud Run para usar el conector.
  4. Conéctese utilizando la dirección IP privada de su instancia y el puerto 5432 .

Conectarse a Cloud SQL

Después de configurar las funciones de Cloud Run, puede conectarse a su instancia de Cloud SQL.

IP pública (predeterminada)

Para las rutas de IP públicas, las funciones de Cloud Run proporcionan cifrado y se conectan mediante el proxy de autenticación de Cloud SQL de dos maneras:

IP privada

Para las rutas IP privadas, la aplicación se conecta directamente a la instancia a través de una red VPC. Este método utiliza TCP para conectarse directamente a la instancia de Cloud SQL sin usar el proxy de autenticación de Cloud SQL.

Conectarse con TCP

Conéctese utilizando la dirección IP privada de su instancia de Cloud SQL como host y el puerto 5432 .

Pitón

Para ver este fragmento en el contexto de una aplicación web, consulte el archivo README en GitHub .

import os
import ssl

import sqlalchemy


def connect_tcp_socket() -> sqlalchemy.engine.base.Engine:
    """Initializes a TCP connection pool for a Cloud SQL instance of Postgres."""
    # 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. 5432

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

Java

Para ver este fragmento en el contexto de una aplicación web, consulte el archivo README en GitHub .

Nota:

  • CLOUD_SQL_CONNECTION_NAME debe representarse como <MI-PROYECTO>:<REGIÓN-DE-INSTANCIA>:<NOMBRE-DE-INSTANCIA>
  • El uso del argumento ipTypes=PRIVATE obligará a SocketFactory a conectarse con la IP privada asociada a una instancia
  • Consulte los requisitos de la versión de fábrica del socket JDBC para el archivo pom.xml aquí .


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();

    // The following URL is equivalent to setting the config options below:
    // jdbc:postgresql://<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:postgresql://%s:%s/%s", INSTANCE_HOST, DB_PORT, DB_NAME));
    config.setUsername(DB_USER); // e.g. "root", "postgres"
    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

Para ver este fragmento en el contexto de una aplicación web, consulte el archivo README en GitHub .

const Knex = require('knex');
const fs = require('fs');

// createTcpPool initializes a TCP connection pool for a Cloud SQL
// instance of Postgres.
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 = {
    client: 'pg',
    connection: {
      host: process.env.INSTANCE_HOST, // e.g. '127.0.0.1'
      port: process.env.DB_PORT, // e.g. '5432'
      user: process.env.DB_USER, // e.g. 'my-user'
      password: process.env.DB_PASS, // e.g. 'my-user-password'
      database: process.env.DB_NAME, // e.g. 'my-database'
    },
    // ... Specify additional properties here.
    ...config,
  };
  // Establish a connection to the database.
  return Knex(dbConfig);
};

Ir

Para ver este fragmento en el contexto de una aplicación web, consulte el archivo README en GitHub .

package cloudsql

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

	// Note: If connecting using the App Engine Flex Go runtime, use
	// "github.com/jackc/pgx/stdlib" instead, since v5 requires
	// Go modules which are not supported by App Engine Flex.
	_ "github.com/jackc/pgx/v5/stdlib"
)

// connectTCPSocket initializes a TCP connection pool for a Cloud SQL
// instance of Postgres.
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'
		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. '5432'
		dbName    = mustGetenv("DB_NAME")       // e.g. 'my-database'
	)

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


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

	// ...

	return dbPool, nil
}

PHP

Para ver este fragmento en el contexto de una aplicación web, consulte el archivo README en GitHub .

namespace Google\Cloud\Samples\CloudSQL\Postgres;

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

        return $conn;
    }
}

Mejores prácticas y otra información

Puedes usar el proxy de autenticación de Cloud SQL al probar tu aplicación localmente. Consulta la guía de inicio rápido para usar el proxy de autenticación de Cloud SQL para obtener instrucciones detalladas.

Grupos de conexiones

Las conexiones a las bases de datos subyacentes pueden interrumpirse, ya sea por el propio servidor de bases de datos o por la infraestructura subyacente a las funciones de Cloud Run. Recomendamos usar una biblioteca cliente compatible con grupos de conexiones que reconectan automáticamente las conexiones de cliente interrumpidas. Además, recomendamos usar un grupo de conexiones de alcance global para aumentar la probabilidad de que la función reutilice la misma conexión en invocaciones posteriores y la cierre automáticamente cuando se expulse la instancia (reducción automática de escala). Para obtener ejemplos más detallados sobre cómo usar grupos de conexiones, consulte Administrar conexiones de bases de datos .

Límites de conexión

Cloud SQL impone un límite máximo de conexiones simultáneas, que puede variar según el motor de base de datos elegido (consulte Cuotas y límites de Cloud SQL ). Se recomienda usar una conexión con funciones de Cloud Run, pero es importante establecer el número máximo de conexiones en 1.

Siempre que sea posible, asegúrese de inicializar un grupo de conexiones solo para las funciones que necesitan acceder a su base de datos. Algunos grupos de conexiones crean conexiones de forma preventiva, lo que puede consumir recursos excesivos y contabilizarse en sus límites de conexión. Por este motivo, se recomienda usar la inicialización diferida para retrasar la creación de un grupo de conexiones hasta que sea necesario e incluirlo solo en las funciones donde se utilice.

Para obtener ejemplos más detallados sobre cómo limitar la cantidad de conexiones, consulte Administrar conexiones de base de datos .

Límites de cuota de API

Las funciones de Cloud Run proporcionan un mecanismo que se conecta mediante el proxy de autenticación de Cloud SQL, que utiliza la API de administración de Cloud SQL. Se aplican límites de cuota de API al proxy de autenticación de Cloud SQL. La cuota de la API de administración de Cloud SQL utilizada es aproximadamente el doble de la cantidad de instancias de Cloud SQL configuradas multiplicada por la cantidad total de funciones implementadas. Puede establecer el número máximo de invocaciones simultáneas para modificar la cuota de API esperada consumida. Las funciones de Cloud Run también imponen límites de frecuencia en la cantidad de llamadas a la API permitidas cada 100 segundos.

¿Qué sigue?

,

Esta página contiene información y ejemplos para conectarse a una instancia de Cloud SQL desde un servicio que se ejecuta en funciones de Cloud Run.

Para obtener instrucciones paso a paso sobre cómo ejecutar una aplicación web de muestra de funciones de Cloud Run conectada a Cloud SQL, consulte la guía de inicio rápido para conectarse desde funciones de Cloud Run .

Cloud SQL es un servicio de base de datos completamente administrado que le ayuda a configurar, mantener, administrar y gestionar sus bases de datos relacionales en la nube.

Las funciones de Cloud Run son una solución informática liviana que permite a los desarrolladores crear funciones independientes y de propósito único que responden a eventos de la nube sin la necesidad de administrar un servidor o un entorno de ejecución.

Configurar una instancia de Cloud SQL

  1. Habilite la API de administración de Cloud SQL en el Google Cloud proyecto desde el que te estás conectando, si aún no lo has hecho:

    Enable the API

  2. Cree una instancia de Cloud SQL para PostgreSQL . Le recomendamos que elija una ubicación de instancia de Cloud SQL en la misma región que su servicio Cloud Run para mejorar la latencia, evitar costos de red y reducir el riesgo de fallos entre regiones.

    De forma predeterminada, Cloud SQL asigna una dirección IP pública a cada nueva instancia. También puede asignar una dirección IP privada. Para obtener más información sobre las opciones de conectividad para ambas instancias, consulte la página "Resumen de la conexión" .

Configurar funciones de Cloud Run

Los pasos para configurar las funciones de Cloud Run dependen del tipo de dirección IP que haya asignado a su instancia de Cloud SQL.

IP pública (predeterminada)

Para configurar las funciones de Cloud Run para habilitar conexiones a una instancia de Cloud SQL:

  • Confirme que la instancia creada anteriormente tenga una dirección IP pública. Puede confirmarlo en la página Descripción general de la instancia en el Google Cloud consola . Si necesita agregar una dirección IP pública, consulte Configurar IP pública .
  • Obtener el INSTANCE_CONNECTION_NAME de la instancia. Este valor está disponible:
    • En la página Descripción general de la instancia, en el Google Cloud consola , o
    • Ejecutando el siguiente comando: gcloud sql instances describe [INSTANCE_NAME]
  • Configure la cuenta de servicio para su función. Si la cuenta de servicio que autoriza pertenece a un proyecto diferente al de la instancia de Cloud SQL, debe habilitar la API de administración de Cloud SQL y agregar el rol de IAM Cloud SQL Client a ambos proyectos.
  • Confirme que la cuenta de servicio tenga esta función para que pueda conectarse a Cloud SQL.
  • Si está utilizando funciones de Cloud Run y ​​no funciones de Cloud Run (1.ª generación) , se requieren los siguientes requisitos (consulte también Configurar Cloud Run ):
    1. Implemente inicialmente su función.
      Cuando comience a crear una función de Cloud Run en el Google Cloud Consola: el servicio subyacente de Cloud Run aún no se ha creado. No se puede configurar una conexión a Cloud SQL hasta que se cree dicho servicio (mediante la implementación de la función de Cloud Run).
    2. En el Google Cloud consola, en la parte superior derecha de la página Detalles de la función , en Desarrollado por Cloud Run , haga clic en el enlace para acceder al servicio Cloud Run subyacente.
    3. En la página de detalles del servicio Cloud Run, seleccione la pestaña Editar e implementar nueva revisión .
    4. Siga los pasos estándar (como en el caso de cualquier cambio de configuración) para establecer una nueva configuración para una conexión de Cloud SQL.
      Esto crea una nueva revisión de Cloud Run y ​​las revisiones posteriores reciben automáticamente esta conexión de Cloud SQL, a menos que la cambie explícitamente.

IP privada

Si la cuenta de servicio autorizadora pertenece a un proyecto diferente al que contiene la instancia de Cloud SQL, haga lo siguiente:

  • En ambos proyectos, habilite la API de administración de Cloud SQL.
  • Para la cuenta de servicio en el proyecto que contiene la instancia de Cloud SQL, agregue los permisos de IAM .
Un conector de acceso a VPC sin servidor utiliza direcciones IP privadas para gestionar la comunicación con su red de VPC. Para conectarse directamente con direcciones IP privadas, debe hacer lo siguiente:
  1. Asegúrese de que la instancia de Cloud SQL creada previamente tenga una dirección IP privada. Si necesita agregar una, consulte Configurar una IP privada para obtener instrucciones.
  2. Cree un conector de acceso a VPC sin servidor en la misma red de VPC que su instancia de Cloud SQL. Tenga en cuenta las siguientes condiciones:
    • A menos que estés usando VPC compartida , tu conector debe estar en el mismo proyecto y región que el recurso que lo usa, pero puede enviar tráfico a recursos en diferentes regiones.
    • El acceso a VPC sin servidor admite la comunicación con redes VPC conectadas mediante Cloud VPN y VPC Network Peering .
    • El acceso a VPC sin servidor no es compatible con redes heredadas .
  3. Configure las funciones de Cloud Run para usar el conector.
  4. Conéctese utilizando la dirección IP privada de su instancia y el puerto 5432 .

Conectarse a Cloud SQL

Después de configurar las funciones de ejecución de la nube, puede conectarse a su instancia de Cloud SQL.

IP pública (predeterminado)

Para las rutas de IP públicas, las funciones de ejecución de nubes proporcionan cifrado y se conecta utilizando el proxy de autenticación Cloud SQL de dos maneras:

IP privada

Para rutas IP privadas, su aplicación se conecta directamente a su instancia a través de una red VPC. Este método utiliza TCP para conectarse directamente a la instancia de Cloud SQL sin usar el proxy de autenticación SQL Cloud.

Conectarse con TCP

Conecte utilizando la dirección IP privada de su instancia de Cloud SQL como host y puerto 5432 .

Pitón

Para ver este fragmento en el contexto de una aplicación web, consulte el archivo README en GitHub .

import os
import ssl

import sqlalchemy


def connect_tcp_socket() -> sqlalchemy.engine.base.Engine:
    """Initializes a TCP connection pool for a Cloud SQL instance of Postgres."""
    # 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. 5432

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

Java

Para ver este fragmento en el contexto de una aplicación web, consulte el archivo README en GitHub .

Nota:

  • Cloud_sql_connection_name debe representarse como <MyProject>: <Sance-Rregion>: <Sance-Name>
  • El uso del argumento ipTypes=PRIVATE obligará a SocketFactory a conectarse con la IP privada asociada a una instancia
  • Consulte los requisitos de la versión de fábrica del socket JDBC para el archivo pom.xml aquí .


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();

    // The following URL is equivalent to setting the config options below:
    // jdbc:postgresql://<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:postgresql://%s:%s/%s", INSTANCE_HOST, DB_PORT, DB_NAME));
    config.setUsername(DB_USER); // e.g. "root", "postgres"
    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

Para ver este fragmento en el contexto de una aplicación web, consulte el archivo README en GitHub .

const Knex = require('knex');
const fs = require('fs');

// createTcpPool initializes a TCP connection pool for a Cloud SQL
// instance of Postgres.
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 = {
    client: 'pg',
    connection: {
      host: process.env.INSTANCE_HOST, // e.g. '127.0.0.1'
      port: process.env.DB_PORT, // e.g. '5432'
      user: process.env.DB_USER, // e.g. 'my-user'
      password: process.env.DB_PASS, // e.g. 'my-user-password'
      database: process.env.DB_NAME, // e.g. 'my-database'
    },
    // ... Specify additional properties here.
    ...config,
  };
  // Establish a connection to the database.
  return Knex(dbConfig);
};

Ir

Para ver este fragmento en el contexto de una aplicación web, consulte el archivo README en GitHub .

package cloudsql

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

	// Note: If connecting using the App Engine Flex Go runtime, use
	// "github.com/jackc/pgx/stdlib" instead, since v5 requires
	// Go modules which are not supported by App Engine Flex.
	_ "github.com/jackc/pgx/v5/stdlib"
)

// connectTCPSocket initializes a TCP connection pool for a Cloud SQL
// instance of Postgres.
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'
		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. '5432'
		dbName    = mustGetenv("DB_NAME")       // e.g. 'my-database'
	)

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


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

	// ...

	return dbPool, nil
}

PHP

Para ver este fragmento en el contexto de una aplicación web, consulte el archivo README en GitHub .

namespace Google\Cloud\Samples\CloudSQL\Postgres;

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

        return $conn;
    }
}

Las mejores prácticas y otra información

Puede usar el proxy Cloud SQL Auth al probar su aplicación localmente. Consulte el WickStart para usar el proxy de autores Cloud SQL para obtener instrucciones detalladas.

Grupos de conexiones

Las conexiones a las bases de datos subyacentes pueden ser eliminadas, ya sea por el servidor de la base de datos o por la infraestructura subyacente a las funciones de ejecución de la nube. Recomendamos usar una biblioteca de clientes que admite grupos de conexión que reconectan automáticamente las conexiones del cliente rotas. Además, recomendamos utilizar un grupo de conexión de alcance global para aumentar la probabilidad de que su función reutilice la misma conexión para las invocaciones posteriores de la función, y cierra la conexión naturalmente cuando la instancia está desalojada (escalada automáticamente). Para ver ejemplos más detallados sobre cómo usar grupos de conexión, consulte Administración de conexiones de bases de datos .

Límites de conexión

La nube SQL impone un límite máximo en las conexiones concurrentes, y estos límites pueden variar según el motor de la base de datos elegido (ver cuotas y límites de SQL de la nube ). Se recomienda utilizar una conexión con las funciones de ejecución de la nube, pero es importante establecer el número máximo de conexiones en 1.

Siempre que sea posible, debe tener cuidado de inicializar solo un grupo de conexión para las funciones que necesitan acceso a su base de datos. Algunos grupos de conexión crearán conexiones preventivamente, lo que puede consumir recursos en exceso y contar para sus límites de conexión. Por esta razón, se recomienda utilizar la inicialización perezosa para retrasar la creación de un grupo de conexión hasta que sea necesario, e solo incluye el grupo de conexión en funciones donde se usa.

Para ejemplos más detallados sobre cómo limitar el número de conexiones, consulte Administración de conexiones de bases de datos .

Límites de cuota de API

Las funciones de ejecución de nubes proporcionan un mecanismo que se conecta utilizando el proxy de autores SQL Cloud, que utiliza la API de administración de Cloud SQL. Los límites de cuotas API se aplican al proxy de autenticación SQL Cloud. La cuota de la API de administración de Cloud SQL utilizada es aproximadamente dos veces el número de instancias de Cloud SQL Configurado tiempos del número total de funciones implementadas. Puede establecer el número de invocaciones concurrentes máximas para modificar la cuota API esperada consumida. Las funciones de ejecución de nubes también imponen límites de velocidad en el número de llamadas API permitidas por 100 segundos.

¿Qué sigue?