Cloud Run에서 Cloud SQL로 연결

이 페이지에는 Cloud Run에서 실행되는 서비스에서 Cloud SQL 인스턴스에 연결하는 방법에 대한 정보와 예시가 있습니다.

Cloud SQL은 클라우드에서 관계형 데이터베이스를 설정, 유지, 관리할 수 있는 완전 관리형 데이터베이스 서비스입니다.

Cloud SQL 인스턴스 설정

  1. 아직 사용 설정하지 않은 경우에는 연결 중인 프로젝트에서 Cloud SQL API를 사용 설정합니다.

    API 사용 설정

  2. SQL Server용 Cloud SQL 인스턴스를 만듭니다.

    기본적으로 Cloud SQL은 공개 IP 주소를 새 인스턴스에 할당합니다. Cloud Run은 공개 IP를 통한 SQL Server용 Cloud SQL 연결을 지원하지 않습니다. 대신 비공개 IP를 사용합니다. 자세한 내용은 비공개 IP 구성을 참조하세요.

Cloud Run 구성

Cloud Run을 구성하는 단계는 Cloud SQL 인스턴스에 할당된 IP 주소 유형에 따라 다릅니다. VPC 커넥터를 통해 모든 이그레스 트래픽을 라우팅하는 경우 비공개 IP를 사용해야 합니다.

공개 IP(기본값)

Cloud Run은 공개 IP를 통한 SQL Server용 Cloud SQL 연결을 지원하지 않습니다. 대신 비공개 IP를 사용합니다.

비공개 IP

서버리스 VPC 액세스 커넥터는 VPC 네트워크와의 통신을 처리합니다. 비공개 IP로 직접 연결하려면 다음을 수행해야 합니다.

  1. 위에서 만든 Cloud SQL 인스턴스에 비공개 IP 주소가 있는지 확인합니다. 추가해야 하는 경우 비공개 IP 구성 페이지를 참조하세요.
  2. Cloud SQL 인스턴스와 동일한 VPC 네트워크에 서버리스 VPC 액세스 커넥터를 만듭니다.
  3. 공유 VPC를 사용하지 않는 한 커넥터는 커넥터를 사용하는 리소스와 동일한 프로젝트와 리전에 있어야 하지만 이 커넥터는 서로 다른 리전의 리소스로 트래픽을 전송할 수 있습니다.

    서버리스 VPC 액세스는 Cloud VPNVPC 네트워크 피어링을 통해 연결된 VPC 네트워크와의 통신을 지원합니다.

    서버리스 VPC 액세스는 기존 네트워크를 지원하지 않습니다.

  4. 커넥터를 사용하도록 Cloud Run을 구성합니다.
  5. 인스턴스의 비공개 IP와 포트 1433를 사용하여 연결합니다.

Cloud SQL에 연결

Cloud Run을 구성한 후 Cloud SQL 인스턴스에 연결할 수 있습니다.

공개 IP(기본값)

Cloud Run은 공개 IP를 통한 SQL Server용 Cloud SQL 연결을 지원하지 않습니다. 대신 비공개 IP를 사용합니다.

공개 IP 경로의 경우 Cloud Run은 암호화를 제공하고 Unix 소켓을 통해 Cloud SQL 인증 프록시를 사용하여 연결합니다.

비공개 IP

비공개 IP 경로의 경우 애플리케이션은 서버리스 VPC 액세스를 통해 인스턴스에 직접 연결됩니다. 이 메서드는 TCP를 사용하여 Cloud SQL 인증 프록시를 사용하지 않고 Cloud SQL 인스턴스에 직접 연결합니다.

TCP로 연결

인스턴스의 비공개 IP 주소와 포트 1433을 사용하여 직접 연결합니다.

Python

웹 애플리케이션의 컨텍스트에서 이 스니펫을 보려면 GitHub의 README를 참조하세요.

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

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

# SQL Server drivers don't account for this
if db_hostname == "localhost":
    db_hostname = "127.0.0.1"

# The SQLAlchemy engine will help manage interactions, including automatically
# managing a pool of connections to your database
pool = sqlalchemy.create_engine(
    # Equivalent URL:
    # mssql+pytds://<db_user>:<db_pass>@/<host>:<port>/<db_name>?driver=ODBC+Driver+17+for+SQL+Server
    sqlalchemy.engine.url.URL.create(
        "mssql+pytds",
        username=db_user,
        password=db_pass,
        database=db_name,
        host=db_hostname,
        port=db_port,
    ),
    **db_config
)

자바

웹 애플리케이션의 컨텍스트에서 이 스니펫을 보려면 GitHub의 README를 참조하세요.

참고:

  • CLOUD_SQL_CONNECTION_NAME은 <MY-PROJECT>:<INSTANCE-REGION>:<INSTANCE-NAME>으로 표현되어야 합니다.
  • 인수 ipTypes=PRIVATE을 사용하면 SocketFactory가 인스턴스의 연결된 비공개 IP와 강제로 연결됩니다.
  • pom.xml 파일에 대한 JDBC 소켓 팩토리 버전 요구사항은 여기를 참조하세요.

// Note: For Java users, the Cloud SQL JDBC Socket Factory can provide authenticated connections
// which is preferred to using the Cloud SQL Proxy with Unix sockets.
// See https://github.com/GoogleCloudPlatform/cloud-sql-jdbc-socket-factory for details.

// The configuration object specifies behaviors for the connection pool.
HikariConfig config = new HikariConfig();

// The following is equivalent to setting the config options below:
// jdbc:sqlserver://;user=<DB_USER>;password=<DB_PASS>;databaseName=<DB_NAME>;
// socketFactoryClass=com.google.cloud.sql.sqlserver.SocketFactory;
// socketFactoryConstructorArg=<INSTANCE_CONNECTION_NAME>

// 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
    .setDataSourceClassName("com.microsoft.sqlserver.jdbc.SQLServerDataSource");
config.setUsername(DB_USER); // e.g. "root", "sqlserver"
config.setPassword(DB_PASS); // e.g. "my-password"
config.addDataSourceProperty("databaseName", DB_NAME);

config.addDataSourceProperty("socketFactoryClass",
    "com.google.cloud.sql.sqlserver.SocketFactory");
config.addDataSourceProperty("socketFactoryConstructorArg", INSTANCE_CONNECTION_NAME);

// ... Specify additional connection properties here.

// ...

// Initialize the connection pool using the configuration object.
DataSource pool = new HikariDataSource(config);

Node.js

웹 애플리케이션의 컨텍스트에서 이 스니펫을 보려면 GitHub의 README를 참조하세요.

const createPool = async () => {
  const config = {pool: {}, options: {}};
  config.user = process.env.DB_USER; // e.g. 'my-db-user'
  config.password = process.env.DB_PASS; // e.g. 'my-db-password'
  config.database = process.env.DB_NAME; // e.g. 'my-database'
  // set the server to '172.17.0.1' when connecting from App Engine Flex
  config.server = process.env.DEPLOYED ? '172.17.0.1' : '127.0.0.1';
  config.port = 1433;

  // ...
  config.options.trustServerCertificate = true;
  return await mssql.connect(config);
};

Go

웹 애플리케이션의 컨텍스트에서 이 스니펫을 보려면 GitHub의 README를 참조하세요.

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

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

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

// ...

return dbPool, nil

Ruby

웹 애플리케이션의 컨텍스트에서 이 스니펫을 보려면 GitHub의 README를 참조하세요.

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

PHP

웹 애플리케이션의 컨텍스트에서 이 스니펫을 보려면 GitHub의 README를 참조하세요.

// $username = 'your_db_user';
// $password = 'yoursupersecretpassword';
// $dbName = 'your_db_name';
// $dbHost = "127.0.0.1";

// Connect using TCP
$dsn = sprintf('sqlsrv:server=%s;Database=%s', $dbHost, $dbName);

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

권장사항 및 기타 정보

로컬에서 애플리케이션을 테스트할 때 Cloud SQL 인증 프록시를 사용할 수 있습니다. 자세한 내용은 빠른 시작: Cloud SQL 인증 프록시 사용을 참조하세요.

Docker 컨테이너를 통해 Cloud SQL 프록시를 사용하여 테스트할 수도 있습니다.

연결 풀

기본 데이터베이스에 대한 연결이 데이터베이스 서버 자체 또는 플랫폼 인프라에 의해 중단될 수 있습니다. 클라이언트 연결이 중단되었을 때 자동으로 다시 연결하는 연결 풀을 지원하는 클라이언트 라이브러리를 사용하는 것이 좋습니다. 연결 풀 사용 방법에 대한 자세한 예시는 데이터베이스 연결 관리 페이지를 참조하세요.

연결 한도

Cloud SQL의 MySQL과 PostgreSQL 버전 모두 동시 연결 수에 최대 한도를 적용합니다. 이러한 한도는 선택한 데이터베이스 엔진에 따라 달라질 수 있습니다(Cloud SQL 할당량 및 한도 페이지 참조).

Cloud Run 서비스는 Cloud SQL 데이터베이스에 대한 100개의 연결로 제한됩니다. 이 한도는 서비스 인스턴스별로 적용됩니다. 즉, Cloud Run 서비스의 각 인스턴스는 데이터베이스에 100개의 연결을 가질 수 있으며, 배포당 총 연결 수가 증가할 수 있습니다.

연결 풀을 사용하여 인스턴스당 사용되는 최대 연결 수를 제한할 수 있습니다. 연결 수를 제한하는 방법에 대한 자세한 예시는 데이터베이스 연결 관리 페이지를 참조하세요.

API 할당량 한도

Cloud Run은 Cloud SQL API를 사용하는 Cloud SQL 인증 프록시를 사용하여 연결하는 메커니즘을 제공합니다. API 할당량 한도는 Cloud SQL 인증 프록시에 적용됩니다. 사용된 Cloud SQL Admin API 할당량은 한 번에 배포된 특정 서비스의 Cloud Run 인스턴스 수로 구성된 Cloud SQL 인스턴스 수의 약 2배입니다. Cloud Run 인스턴스 수를 제한하거나 늘려 사용되는 예상 API 할당량을 수정할 수 있습니다.

다음 단계