Conéctate con conectores de Cloud SQL

Los conectores de Cloud SQL son bibliotecas que proporcionan encriptación y autorización basada en IAM cuando se conectan a una instancia de Cloud SQL. No pueden proporcionar una ruta de red a una instancia de Cloud SQL, si aún no hay una.

Otras formas de conectarse a una instancia de Cloud SQL son el uso de un cliente de base de datos o el proxy de autenticación de Cloud SQL. Consulta la página Opciones de conexión para obtener más información sobre cómo conectarte a una instancia de Cloud SQL.

En esta página, se analizan los siguientes conectores de Cloud SQL:

  • El conector de Java de Cloud SQL
  • El conector de Python de Cloud SQL (Abrir en Colab)
  • El conector de Go en Cloud SQL

Beneficios

El uso de un conector de Cloud SQL proporciona los siguientes beneficios:

  • Autorización de IAM: Usa los permisos de administración de identidades y accesos (IAM) para controlar quién o qué puede conectarse a tus instancias de Cloud SQL.
  • Conveniencia: quita el requisito de administrar certificados SSL, configurar reglas de firewall o habilitar redes autorizadas.
  • Autenticación de la base de datos de IAM: Proporciona compatibilidad con la autenticación automática de la base de datos de IAM de Cloud SQL.

Antes de comenzar

Configuración

Java

El conector de Java de Cloud SQL es una biblioteca que proporciona encriptación y autorización basadas en IAM cuando se conecta a una instancia de Cloud SQL. No puede proporcionar una ruta de red a una instancia de Cloud SQL si aún no hay una.

Instalación

Si deseas obtener instrucciones para desarrollar y usar los controladores para JDBC y R2DBC con el conector de Java de Cloud SQL, consulta los siguientes vínculos:

JDBC: Conéctate a Postgres con JDBC.

R2DBC: Conéctate a Postgres con R2DBC

Para ver ejemplos de esta biblioteca que se usa en el contexto de una aplicación, consulta estas aplicaciones de muestra.

Autenticación

Esta biblioteca usa las credenciales predeterminadas de la aplicación para autenticar la conexión con el servidor de Cloud SQL.

Para activar las credenciales de forma local, usa el siguiente comando de gcloud:

    gcloud auth application-default login
    

Conéctate con IntelliJ

Para conectar IntelliJ a tu instancia de Cloud SQL, debes agregar la biblioteca como un JAR con dependencias en la sección Archivos adicionales en la página de configuración del controlador. Por ejemplo, los archivos de fat JAR precompilados se pueden encontrar en la página Versiones del conector de Java de Cloud SQL para este propósito.

Python

El conector de Python de Cloud SQL es una biblioteca que se puede usar junto con un controlador de base de datos a fin de permitir a los usuarios con permisos suficientes para conectarse a una base de datos de Cloud SQL sin tener que incluir IP en la lista de entidades permitidas ni administrar certificados SSL de forma manual.

Si deseas ver ejemplos interactivos sobre el uso del conector de Python de Cloud SQL, abre el notebook de conectores de Python de Cloud SQL.

El controlador compatible actual para PostgreSQL es pg8000.

Instalación

Para instalar la actualización más reciente, sigue estas instrucciones.

Authentication

Esta biblioteca usa las credenciales predeterminadas de la aplicación para autenticar la conexión con el servidor de Cloud SQL.

Para activar las credenciales de forma local, usa el siguiente comando de gcloud:

    gcloud auth application-default login
    

Go

El conector de Cloud SQL para Go es un conector de Cloud SQL diseñado para usarse con el lenguaje Go. Para mejorar la seguridad, este conector usa la encriptación sólida TLS 1.3 autenticada de forma manual entre el conector del cliente y el proxy del servidor, independientemente del protocolo de base de datos.

Instalación

Puedes instalar este repositorio con go get:

    go get cloud.google.com/go/cloudsqlconn
    

Uso

Java

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

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

public class ConnectorConnectionPoolFactory 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 INSTANCE_CONNECTION_NAME =
      System.getenv("INSTANCE_CONNECTION_NAME");
  private static final String INSTANCE_UNIX_SOCKET = System.getenv("INSTANCE_UNIX_SOCKET");
  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");

  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:///<DB_NAME>?cloudSqlInstance=<INSTANCE_CONNECTION_NAME>&
    // socketFactory=com.google.cloud.sql.postgres.SocketFactory&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", DB_NAME));
    config.setUsername(DB_USER); // e.g. "root", _postgres"
    config.setPassword(DB_PASS); // e.g. "my-password"

    config.addDataSourceProperty("socketFactory", "com.google.cloud.sql.postgres.SocketFactory");
    config.addDataSourceProperty("cloudSqlInstance", INSTANCE_CONNECTION_NAME);

    // The ipTypes argument can be used to specify a comma delimited list of preferred IP types
    // for connecting to a Cloud SQL instance. The argument ipTypes=PRIVATE will force the
    // SocketFactory to connect with an instance's associated private IP.
    config.addDataSourceProperty("ipTypes", "PUBLIC,PRIVATE");

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

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

Python

Consulta Cómo usar este conector para obtener instrucciones detalladas sobre cómo usar la biblioteca. Consulta el ejemplo de código de prueba de conexión en GitHub.

import os

from google.cloud.sql.connector import Connector, IPTypes
import pg8000

import sqlalchemy

# connect_with_connector initializes a connection pool for a
# Cloud SQL instance of Postgres using the Cloud SQL Python Connector.
def connect_with_connector() -> sqlalchemy.engine.base.Engine:
    # 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.

    instance_connection_name = os.environ["INSTANCE_CONNECTION_NAME"]  # e.g. 'project:region:instance'
    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'

    ip_type = IPTypes.PRIVATE if os.environ.get("PRIVATE_IP") else IPTypes.PUBLIC

    # initialize Cloud SQL Python Connector object
    connector = Connector()

    def getconn() -> pg8000.dbapi.Connection:
        conn: pg8000.dbapi.Connection = connector.connect(
            instance_connection_name,
            "pg8000",
            user=db_user,
            password=db_pass,
            db=db_name,
            ip_type=ip_type,
        )
        return conn

    # The Cloud SQL Python Connector can be used with SQLAlchemy
    # using the 'creator' argument to 'create_engine'
    pool = sqlalchemy.create_engine(
        "postgresql+pg8000://",
        creator=getconn,
        # ...
    )
    return pool

Go

Consulta Uso para obtener instrucciones detalladas sobre el uso de la biblioteca. Consulta el ejemplo de código de prueba de conexión en GitHub.

package cloudsql

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

	"cloud.google.com/go/cloudsqlconn"
	"github.com/jackc/pgx/v4"
	"github.com/jackc/pgx/v4/stdlib"
)

func connectWithConnector() (*sql.DB, error) {
	mustGetenv := func(k string) string {
		v := os.Getenv(k)
		if v == "" {
			log.Fatalf("Warning: %s environment variable not set.\n", k)
		}
		return v
	}
	// Note: Saving credentials in environment variables is convenient, but not
	// secure - consider a more secure solution such as
	// Cloud Secret Manager (https://cloud.google.com/secret-manager) to help
	// keep secrets safe.
	var (
		// Either a DB_USER or a DB_IAM_USER should be defined. If both are
		// defined, DB_IAM_USER takes precedence.
		dbUser                 = os.Getenv("DB_USER")                   // e.g. 'my-db-user'
		dbIAMUser              = os.Getenv("DB_IAM_USER")               // e.g. 'sa-name@project-id.iam'
		dbPwd                  = mustGetenv("DB_PASS")                  // e.g. 'my-db-password'
		dbName                 = mustGetenv("DB_NAME")                  // e.g. 'my-database'
		instanceConnectionName = mustGetenv("INSTANCE_CONNECTION_NAME") // e.g. 'project:region:instance'
		usePrivate             = os.Getenv("PRIVATE_IP")
	)
	if dbUser == "" && dbIAMUser == "" {
		log.Fatal("Warning: One of DB_USER or DB_IAM_USER must be defined")
	}

	dsn := fmt.Sprintf("user=%s password=%s database=%s", dbUser, dbPwd, dbName)
	config, err := pgx.ParseConfig(dsn)
	if err != nil {
		return nil, err
	}
	config.DialFunc = func(ctx context.Context, network, instance string) (net.Conn, error) {
		if dbIAMUser != "" {
			d, err := cloudsqlconn.NewDialer(ctx, cloudsqlconn.WithIAMAuthN())
			if err != nil {
				return nil, err
			}
			return d.Dial(ctx, instanceConnectionName)
		}
		if usePrivate != "" {
			d, err := cloudsqlconn.NewDialer(
				ctx,
				cloudsqlconn.WithDefaultDialOptions(cloudsqlconn.WithPrivateIP()),
			)
			if err != nil {
				return nil, err
			}
			return d.Dial(ctx, instanceConnectionName)
		}
		// Use the Cloud SQL connector to handle connecting to the instance.
		// This approach does *NOT* require the Cloud SQL proxy.
		d, err := cloudsqlconn.NewDialer(ctx)
		if err != nil {
			return nil, err
		}
		return d.Dial(ctx, instanceConnectionName)
	}
	dbURI := stdlib.RegisterConnConfig(config)
	dbPool, err := sql.Open("pgx", dbURI)
	if err != nil {
		return nil, fmt.Errorf("sql.Open: %v", err)
	}
	return dbPool, nil
}

Solucionar problemas

Versiones del controlador

Asegúrate de usar la versión más reciente de los conectores de Cloud SQL y el controlador de base de datos para evitar incompatibilidades. Algunas versiones anteriores de controladores no son compatibles.

Rutas de conexión

Los conectores de Cloud SQL proporcionan autorización para las conexiones, pero no proporcionan rutas de acceso nuevas a la conectividad. Por ejemplo, para conectarte a una instancia de Cloud SQL mediante una dirección IP privada, tu aplicación ya debe tener acceso a VPC. Para conectarte a una instancia de Cloud SQL con una dirección IP pública, tu aplicación debe estar en una red autorizada.

Depurar problemas de conexión

Para obtener ayuda adicional con problemas de conexión, consulta las páginas Solución de problemas y Depurar problemas de conexión.

¿Qué sigue?