Como se conectar do Cloud Run (totalmente gerenciado) ao Cloud SQL

Nesta página, você verá informações e exemplos de conexão a uma instância do Cloud SQL por meio de um serviço em execução no Cloud Run (totalmente gerenciado).

O Cloud SQL é um serviço de banco de dados totalmente gerenciado que ajuda a configurar, manter, gerenciar e administrar seus bancos de dados relacionais na nuvem.

Como configurar uma instância do Cloud SQL

  1. Ative a API Cloud SQL Admin no projeto do qual você está se conectando, caso ainda não tenha feito isso:

    Ative a API

  2. Crie uma instância do Cloud SQL para PostgreSQL.

    Por padrão, o Cloud SQL atribui um endereço IP público a uma nova instância. Você também tem a opção de atribuir um endereço IP particular. Para mais informações sobre as opções de conectividade de ambos, consulte a página Connecting Overview.

Como configurar o Cloud Run (totalmente gerenciado)

As etapas para configurar o Cloud Run (totalmente gerenciado) dependem do tipo de endereço IP atribuído à instância do Cloud SQL.

IP público (padrão)

  • Verifique se a instância criada anteriormente tem um endereço IP público. Você pode verificar isso na página Visão geral da sua instância no Console do Google Cloud. Se precisar adicionar um, consulte a página Como configurar o IP público para ver instruções.
  • Receba o INSTANCE_CONNECTION_NAME da instância. Isso pode ser encontrado na página Visão geral da instância no Console do Google Cloud ou executando o seguinte comando: gcloud sql instances describe [INSTANCE_NAME].
  • Configure a conta de serviço do serviço. Certifique-se de que a conta de serviço tenha os papéis e permissões do Cloud SQL apropriados para se conectar ao Cloud SQL.
      A conta de serviço precisa de um dos seguintes papéis do IAM:
      • Cloud SQL Client (recomendável)
      • Cloud SQL Editor
      • Cloud SQL Admin
      Também é possível atribuir manualmente as seguintes permissões do IAM:
      • cloudsql.instances.connect
      • cloudsql.instances.get

    Se a conta de serviço de autorização pertencer a um projeto diferente da instância do Cloud SQL, as permissões da API Cloud SQL Admin e do IAM precisarão ser adicionadas aos dois projetos.

Como qualquer alteração de configuração, definir uma nova configuração para a conexão do Cloud SQL leva à criação de uma nova revisão do Cloud Run. As revisões seguintes também receberão automaticamente essa conexão do Cloud SQL, a menos que você faça atualizações explícitas para alterá-la.

Console

  1. Acessar o Cloud Run

  2. Configure o serviço:

    • Se você estiver adicionando uma conexão do Cloud SQL a um novo serviço, faça o seguinte:

      • O serviço precisa estar em contêiner e ser enviado ao Container Registry. Se você ainda não tem, consulte estas instruções sobre como criar e implantar uma imagem de contêiner.

      • Clique em CRIAR SERVIÇO.

    • Se você estiver adicionando conexões do Cloud SQL a um serviço atual, faça o seguinte:

      • Clique no nome do serviço.

      • Clique em IMPLANTAR NOVA REVISÃO.

  3. Ative a conexão com o Cloud SQL:

    • Clique em MOSTRAR CONFIGURAÇÕES OPCIONAIS:

    Adicionar conexão com o Cloud SQL

    • Para adicionar uma conexão a uma instância do Cloud SQL no projeto, selecione a instância pretendida no menu suspenso.
    • Para usar uma instância do Cloud SQL de outro projeto, selecione string de conexão personalizada na lista suspensa e insira o nome completo da conexão da instância no formato PROJECT-ID:REGION:INSTANCE-ID.

    • Para excluir uma conexão, passe o cursor à direita da conexão para exibir o ícone de Lixeira e clique nele.

  4. Clique em Criar ou Implantar.

Linha de comando

Antes de usar qualquer um dos comandos abaixo, faça as seguintes substituições:

  • IMAGE pela imagem que você está implantando;
  • SERVICE-NAME pelo nome do serviço do Cloud Run;
  • INSTANCE-CONNECTION-NAME pelo nome da conexão da instância do Cloud SQL ou uma lista de nomes de conexões separados por vírgulas.

    Para implantar um novo contêiner, use o comando a seguir:

    gcloud run deploy --image IMAGE \
      --add-cloudsql-instances INSTANCE-CONNECTION-NAME \
      --update-env-vars INSTANCE_CONNECTION_NAME="INSTANCE-CONNECTION-NAME"
    ` Para atualizar um serviço atual, use o comando a seguir:
    gcloud run services update SERVICE-NAME \
      --add-cloudsql-instances INSTANCE-CONNECTION-NAME \
      --update-env-vars INSTANCE_CONNECTION_NAME="INSTANCE-CONNECTION-NAME"

IP particular

Um conector de acesso VPC sem servidor processa a comunicação com sua rede VPC. Para se conectar diretamente com IP particular, é necessário:

  1. Verifique se a instância do Cloud SQL criada acima tem um endereço IP particular. Se você precisar adicionar um, consulte a página Como configurar o IP particular para ver instruções.
  2. Crie um conector de acesso VPC sem servidor na mesma rede VPC da sua instância do Cloud SQL.
  3. A menos que você esteja usando a VPC compartilhada, é necessário que um conector esteja no mesmo projeto e na mesma região do recurso que o utiliza, mas o conector pode enviar tráfego para recursos em regiões diferentes.

    O acesso VPC sem servidor é compatível com a comunicação com redes VPC conectadas por meio do Cloud VPN e de peering de rede VPC.

    O acesso VPC sem servidor não é compatível com redes legadas.

  4. Configure o Cloud Run (totalmente gerenciado) para usar o conector.
  5. Conecte-se usando o IP particular e a porta 5432 da instância.

Como se conectar ao Cloud SQL

Depois de configurar o Cloud Run (totalmente gerenciado), é possível se conectar à instância do Cloud SQL. O Cloud Run (totalmente gerenciado) fornece um mecanismo que se conecta usando o Cloud SQL Proxy.

IP público (padrão)

Como se conectar com soquetes Unix

Depois de configurá-lo corretamente, conecte o serviço ao soquete de domínio do Unix da instância do Cloud SQL que foi acessado no sistema de arquivos do ambiente por meio deste caminho: /cloudsql/INSTANCE_CONNECTION_NAME.

Essas conexões são criptografadas automaticamente sem qualquer configuração extra. Os exemplos de código mostrados abaixo são trechos de exemplos mais completos no site do GitHub. Clique em View on GitHub para ver mais.

Python

Para ver esse snippet no contexto de um aplicativo da Web, consulte o README no GitHub (em inglês).

# 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_socket_dir = os.environ.get("DB_SOCKET_DIR", "/cloudsql")
cloud_sql_connection_name = os.environ["CLOUD_SQL_CONNECTION_NAME"]

pool = sqlalchemy.create_engine(

    # Equivalent URL:
    # postgres+pg8000://<db_user>:<db_pass>@/<db_name>
    #                         ?unix_sock=<socket_path>/<cloud_sql_instance_name>/.s.PGSQL.5432
    sqlalchemy.engine.url.URL(
        drivername="postgresql+pg8000",
        username=db_user,  # e.g. "my-database-user"
        password=db_pass,  # e.g. "my-database-password"
        database=db_name,  # e.g. "my-database-name"
        query={
            "unix_sock": "{}/{}/.s.PGSQL.5432".format(
                db_socket_dir,  # e.g. "/cloudsql"
                cloud_sql_connection_name)  # i.e "<PROJECT-NAME>:<INSTANCE-REGION>:<INSTANCE-NAME>"
        }
    ),
    **db_config
)

Java

Para ver esse snippet no contexto de um aplicativo da Web, consulte o README no GitHub (em inglês).

// 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=<CLOUD_SQL_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"

// For Java users, the Cloud SQL JDBC Socket Factory can provide authenticated connections.
// See https://github.com/GoogleCloudPlatform/cloud-sql-jdbc-socket-factory for details.
config.addDataSourceProperty("socketFactory", "com.google.cloud.sql.postgres.SocketFactory");
config.addDataSourceProperty("cloudSqlInstance", CLOUD_SQL_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.
DataSource pool = new HikariDataSource(config);

Node.js

Para ver esse snippet no contexto de um aplicativo da Web, consulte o README no GitHub (em inglês).

const createUnixSocketPool = config => {
  const dbSocketPath = process.env.DB_SOCKET_PATH || '/cloudsql';

  // Establish a connection to the database
  return Knex({
    client: 'pg',
    connection: {
      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'
      host: `${dbSocketPath}/${process.env.CLOUD_SQL_CONNECTION_NAME}`,
    },
    // ... Specify additional properties here.
    ...config,
  });
};

C#

Para ver esse snippet no contexto de um aplicativo da Web, consulte o README no GitHub (em inglês).

            // Equivalent connection string:
            // "Server=<dbSocketDir>/<INSTANCE_CONNECTION_NAME>;Uid=<DB_USER>;Pwd=<DB_PASS>;Database=<DB_NAME>"
            String dbSocketDir = Environment.GetEnvironmentVariable("DB_SOCKET_PATH") ?? "/cloudsql";
            String instanceConnectionName = Environment.GetEnvironmentVariable("INSTANCE_CONNECTION_NAME");
            var connectionString = new NpgsqlConnectionStringBuilder()
            {
                // The Cloud SQL proxy provides encryption between the proxy and instance.
                SslMode = SslMode.Disable,
                // 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.
                Host = String.Format("{0}/{1}", dbSocketDir, instanceConnectionName),
                Username = 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.
            // ...
            NpgsqlConnection connection =
                new NpgsqlConnection(connectionString.ConnectionString);

Go

Para ver esse snippet no contexto de um aplicativo da Web, consulte o README no GitHub (em inglês).

var (
	dbUser                 = mustGetenv("DB_USER")                  // e.g. 'my-db-user'
	dbPwd                  = mustGetenv("DB_PASS")                  // e.g. 'my-db-password'
	instanceConnectionName = mustGetenv("INSTANCE_CONNECTION_NAME") // e.g. 'project:region:instance'
	dbName                 = mustGetenv("DB_NAME")                  // e.g. 'my-database'
)

socketDir, isSet := os.LookupEnv("DB_SOCKET_DIR")
if !isSet {
	socketDir = "/cloudsql"
}

var dbURI string
dbURI = fmt.Sprintf("user=%s password=%s database=%s host=%s/%s", dbUser, dbPwd, dbName, socketDir, instanceConnectionName)

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

// ...

return dbPool, nil

Ruby

Para ver esse snippet no contexto de um aplicativo da Web, consulte o README no GitHub (em inglês).

production:
  adapter: postgresql
  # 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_production" } %>
  # If connecting via unix domain socket, specify the socket path as host
  host:  "<%= ENV.fetch("DB_SOCKET_DIR") { '/cloudsql' } %>/<%= ENV["INSTANCE_CONNECTION_NAME"] %>"

PHP

Para ver esse snippet no contexto de um aplicativo da Web, consulte o README no GitHub (em inglês).

// $username = 'your_db_user';
// $password = 'yoursupersecretpassword';
// $db_name = 'your_db_name';
// $cloud_sql_connection_name = getenv("CLOUD_SQL_CONNECTION_NAME");
// $socket_dir = getenv('DB_SOCKET_DIR') ?: '/cloudsql';

// Connect using UNIX sockets
$dsn = sprintf(
    'pgsql:dbname=%s;host=%s/%s',
    $db_name,
    $socket_dir,
    $cloud_sql_connection_name
);

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

IP particular

Como se conectar com TCP

Conecte-se diretamente usando o endereço IP particular e a porta 5432 da instância.

Python

Para ver esse snippet no contexto de um aplicativo da Web, consulte o README no GitHub.

# 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:
    # postgres+pg8000://<db_user>:<db_pass>@<db_host>:<db_port>/<db_name>
    sqlalchemy.engine.url.URL(
        drivername="postgresql+pg8000",
        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. 5432
        database=db_name  # e.g. "my-database-name"
    ),
    **db_config
)

Java

Para ver esse snippet no contexto de um aplicativo da Web, consulte o README no GitHub (em inglês).

// 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=<CLOUD_SQL_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"

// For Java users, the Cloud SQL JDBC Socket Factory can provide authenticated connections.
// See https://github.com/GoogleCloudPlatform/cloud-sql-jdbc-socket-factory for details.
config.addDataSourceProperty("socketFactory", "com.google.cloud.sql.postgres.SocketFactory");
config.addDataSourceProperty("cloudSqlInstance", CLOUD_SQL_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.
DataSource pool = new HikariDataSource(config);

Node.js

Para ver esse snippet no contexto de um aplicativo da Web, consulte o README no GitHub.

const createTcpPool = config => {
  // Extract host and port from socket address
  const dbSocketAddr = process.env.DB_HOST.split(':'); // e.g. '127.0.0.1:5432'

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

Go

Para ver esse snippet no contexto de um aplicativo da Web, consulte o README no GitHub.

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. '5432'
	dbName    = mustGetenv("DB_NAME")     // e.g. 'my-database'
)

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

// ...

return dbPool, nil

C#

Para ver esse snippet no contexto de um aplicativo da Web, consulte o README no GitHub (em inglês).

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

                // 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.
                Host = Environment.GetEnvironmentVariable("DB_HOST"),     // e.g. '127.0.0.1'
                // Set Host to 'cloudsql' when deploying to App Engine Flexible environment
                Username = 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.
            // ...
            NpgsqlConnection connection =
                new NpgsqlConnection(connectionString.ConnectionString);

Ruby

Para ver esse snippet no contexto de um aplicativo da Web, consulte o README no GitHub.

development:
  adapter: postgresql
  # 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")  { 5432 }%> 

PHP

Para ver esse snippet no contexto de um aplicativo da Web, consulte o README no GitHub.

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

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

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

Práticas recomendadas e outras informações

É possível usar o Cloud SQL Proxy ao testar seu aplicativo localmente. Acesse o guia de início rápido sobre como usar o proxy para testes locais e veja instruções detalhadas.

Se preferir, teste usando o Cloud SQL Proxy por meio de um contêiner do Docker.

Pools de conexões

As conexões aos bancos de dados podem ser descartadas pelo próprio servidor de banco de dados ou pela infraestrutura da plataforma. Recomendamos o uso de uma biblioteca de cliente compatível com pools de conexões que reconectam automaticamente conexões de cliente danificadas. Para exemplos mais detalhados sobre como usar pools de conexões, consulte a página Como gerenciar conexões de banco de dados.

Limites de conexão

As edições MySQL e PostgreSQL do Cloud SQL impõem um limite máximo de conexões simultâneas. Esses limites podem variar dependendo do mecanismo de banco de dados escolhido. Consulte a página Limites e cotas do Cloud SQL.

Os serviços do Cloud Run (totalmente gerenciado) estão limitados a cem conexões a um banco de dados do Cloud SQL. Esse limite é aplicado por instância de serviço. Isso significa que cada instância do serviço Cloud Run (totalmente gerenciado) pode ter cem conexões com o banco de dados e, à medida que ela escalona, o número total de conexões por implantação pode aumentar.

É possível limitar o número máximo de conexões por instância usando um pool de conexões. Para exemplos mais detalhados sobre como limitar o número de conexões, consulte a página Como gerenciar conexões de banco de dados.

Limites de cota da API

O Cloud Run (totalmente gerenciado) fornece um mecanismo que se conecta usando o Cloud SQL Proxy, que usa a API Cloud SQL Admin. Os limites de cota da API se aplicam ao Cloud SQL Proxy.

Próximas etapas