Cloud Run(완전 관리형)에서 Cloud SQL로 연결

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

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

Cloud SQL 인스턴스 설정

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

    API 사용 설정

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

    기본적으로 Cloud SQL은 공개 IP 주소를 새 인스턴스에 할당합니다. 비공개 IP 주소를 할당할 수도 있습니다. 두 옵션의 연결 옵션에 대한 자세한 내용은 연결 개요 페이지를 참조하세요.

Cloud Run(완전 관리형) 구성

Cloud Run(완전 관리형)을 구성하는 단계는 Cloud SQL 인스턴스에 할당된 IP 주소 유형에 따라 다릅니다.

공개 IP(기본값)

  • 앞에서 만든 인스턴스에 공개 IP 주소가 있는지 확인합니다. Google Cloud Console의 인스턴스에 대한 개요 페이지에서 이를 확인할 수 있습니다. 공개 IP 주소를 추가해야 하는 경우 공개 IP 구성 페이지의 안내를 참조하세요.
  • 인스턴스의 INSTANCE_CONNECTION_NAME을 가져옵니다. Google Cloud Console의 인스턴스에 대한 개요 페이지에서 확인하거나 gcloud sql instances describe [INSTANCE_NAME] 명령어를 실행하여 확인할 수 있습니다.
  • Cloud SQL 호출을 인증하는 데 사용하는 서비스 계정에 적절한 Cloud SQL 역할과 권한이 있는지 확인합니다.
      서비스의 서비스 계정에는 다음 IAM 역할 중 하나가 필요합니다.
      • Cloud SQL Client(권장)
      • Cloud SQL Editor
      • Cloud SQL Admin
      또는 다음 IAM 권한을 수동으로 할당할 수도 있습니다.
      • cloudsql.instances.connect
      • cloudsql.instances.get
      IAM 역할을 서비스 계정에 추가하는 자세한 방법은 서비스 계정에 역할 부여를 참조하세요.

    기본적으로 앱은 Cloud Run(완전 관리형) 서비스 계정을 사용하여 연결을 승인합니다. 서비스 계정은 PROJECT_NUMBER-compute@developer.gserviceaccount.com 형식입니다.

    승인 서비스 계정이 Cloud SQL 인스턴스와 다른 프로젝트에 속하는 경우 두 프로젝트에 Cloud SQL Admin API와 IAM 권한을 추가해야 합니다.

다른 구성 변경과 마찬가지로 Cloud SQL 연결의 새 구성을 설정하면 새 Cloud Run 버전이 생성됩니다. 이를 변경하는 명시적 업데이트가 없으면 이후 버전에서도 이 Cloud SQL 연결이 자동으로 적용됩니다.

Console

  1. Cloud Run으로 이동

  2. 서비스 구성:

    • 새 서비스에 Cloud SQL 연결을 추가하는 경우:

      • 서비스를 컨테이너화하여 Container Registry에 업로드해야 합니다. 아직 컨테이너 이미지가 없으면 컨테이너 이미지 빌드 및 배포에 대한 안내를 참조하세요.

      • 서비스 만들기를 클릭합니다.

    • 기존 서비스에 Cloud SQL 연결을 추가하는 경우:

      • 서비스 이름을 클릭합니다.

      • 새 버전 배포를 클릭합니다.

  3. Cloud SQL 연결 사용 설정:

    • 선택적 설정 표시를 클릭합니다.

    Cloud SQL 연결 추가

    • 프로젝트의 Cloud SQL 인스턴스에 연결을 추가하는 경우 드롭다운 메뉴에서 원하는 Cloud SQL 인스턴스를 선택합니다.
    • 다른 프로젝트의 Cloud SQL 인스턴스를 사용하는 경우 드롭다운에서 커스텀 연결 문자열을 선택한 후 PROJECT-ID:REGION:INSTANCE-ID 형식으로 전체 인스턴스 연결 이름을 입력합니다.

    • 연결을 삭제하려면 마우스 커서를 연결 오른쪽으로 가져가서 휴지통 아이콘을 표시하고 클릭합니다.

  4. 만들기 또는 배포를 클릭합니다.

명령줄

아래 명령어 중 하나를 사용하기 전에 다음과 같이 바꿉니다.

  • IMAGE를 배포할 이미지로 바꿉니다.
  • SERVICE-NAME을 Cloud Run 서비스 이름으로 바꿉니다.
  • INSTANCE-CONNECTION-NAME을 Cloud SQL 인스턴스의 인스턴스 연결 이름 또는 쉼표로 구분된 연결 이름 목록으로 바꿉니다.

    새 컨테이너를 배포하는 경우 다음 명령어를 사용합니다.

    gcloud run deploy --image IMAGE \
      --add-cloudsql-instances INSTANCE-CONNECTION-NAME \
      --update-env-vars INSTANCE_CONNECTION_NAME="INSTANCE-CONNECTION-NAME"
    ` 기존 서비스를 업데이트하는 경우 다음 명령어를 사용합니다.
    gcloud run services update SERVICE-NAME \
      --add-cloudsql-instances INSTANCE-CONNECTION-NAME \
      --update-env-vars INSTANCE_CONNECTION_NAME="INSTANCE-CONNECTION-NAME"

비공개 IP

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

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

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

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

  4. 커넥터를 사용하도록 Cloud Run(완전 관리형)을 구성합니다.
  5. 인스턴스의 비공개 IP와 포트 3306를 사용하여 연결합니다.

Cloud SQL에 연결

Cloud Run(완전 관리형)을 구성한 후 Cloud SQL 인스턴스에 연결할 수 있습니다. Cloud Run(완전 관리형)은 Cloud SQL 프록시를 사용하여 연결하는 메커니즘을 제공합니다.

공개 IP(기본값)

비공개 IP

TCP로 연결

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

Python

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

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

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

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

Node.js

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

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

  // Establish a connection to the database
  return await mysql.createPool({
    user: process.env.DB_USER, // e.g. 'my-db-user'
    password: process.env.DB_PASS, // e.g. 'my-db-password'
    database: process.env.DB_NAME, // e.g. 'my-database'
    host: dbSocketAddr[0], // e.g. '127.0.0.1'
    port: dbSocketAddr[1], // e.g. '3306'
    // ... Specify additional properties here.
    ...config,
  });
};

Go

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

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

var dbURI string
dbURI = fmt.Sprintf("%s:%s@tcp(%s:%s)/%s?parseTime=true", dbUser, dbPwd, dbTcpHost, dbPort, dbName)

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

// ...

return dbPool, nil

C#

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

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

                // Remember - storing secrets in plaintext is potentially unsafe. Consider using
                // something like https://cloud.google.com/secret-manager/docs/overview to help keep
                // secrets secret.
                Server = Environment.GetEnvironmentVariable("DB_HOST"),   // e.g. '127.0.0.1'
                // Set Host to 'cloudsql' when deploying to App Engine Flexible environment
                UserID = Environment.GetEnvironmentVariable("DB_USER"),   // e.g. 'my-db-user'
                Password = Environment.GetEnvironmentVariable("DB_PASS"), // e.g. 'my-db-password'
                Database = Environment.GetEnvironmentVariable("DB_NAME"), // e.g. 'my-database'
            };
            connectionString.Pooling = true;
            // Specify additional properties here.
            // ...
            DbConnection connection =
                new MySqlConnection(connectionString.ConnectionString);

Ruby

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

development:
  adapter: mysql2
  # Configure additional properties here
  username: <%= ENV["DB_USER"] %>  # e.g. "my-database-user"
  password: <%= ENV["DB_PASS"] %> # e.g. "my-database-password"
  database: <%= ENV.fetch("DB_NAME") { "vote_development" } %>
  host: <%= ENV.fetch("DB_HOST") { "127.0.0.1" }%> # '172.17.0.1' if deployed to GAE Flex
  port: <%= ENV.fetch("DB_PORT") { 3306 }%> 

PHP

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

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

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

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

권장사항 및 기타 정보

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

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

연결 풀

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

연결 한도

Cloud SQL의 MySQL과 PostgreSQL 버전 모두 동시 연결 수에 최대 한도를 적용합니다. 이러한 한도는 선택한 데이터베이스 엔진에 따라 달라질 수 있습니다(Cloud SQL 할당량 및 한도 페이지 참조). Cloud Run(완전 관리형)은 부하가 증가할 때 더 많은 인스턴스를 자동으로 생성할 수 있으며, 이 경우 이러한 한도를 초과할 수 있습니다. 연결 풀을 사용하면 인스턴스마다 사용되는 최대 연결 수를 제한할 수 있습니다. 연결 수를 제한하는 방법에 대한 자세한 예시는 데이터베이스 연결 관리 페이지를 참조하세요.

API 할당량 한도

Cloud Run(완전 관리형)은 Cloud SQL Admin API를 사용하는 Cloud SQL 프록시를 사용하여 연결하는 메커니즘을 제공합니다. API 할당량 한도는 Cloud SQL 프록시에 적용됩니다.

다음 단계