Cloud SQL 언어 커넥터를 사용하여 연결

Cloud SQL 커넥터는 Cloud SQL 인스턴스에 연결할 때 암호화 및 Identity and Access Management(IAM) 기반 승인을 제공하는 라이브러리입니다. Cloud SQL 인스턴스가 아직 없는 경우 Cloud SQL 인스턴스에 대한 네트워크 경로를 제공할 수 없습니다.

Cloud SQL 인스턴스에 연결하는 다른 방법에는 데이터베이스 클라이언트 사용 또는 Cloud SQL 인증 프록시가 포함됩니다. Cloud SQL 인스턴스에 연결하는 방법에 대한 자세한 내용은 연결 옵션 정보 페이지를 참조하세요.

이 페이지에서는 다음 Cloud SQL 커넥터에 대해 설명합니다.

  • Cloud SQL Java 커넥터
  • Cloud SQL Python 커넥터(Colab에서 열기)
  • Cloud SQL Go 커넥터
  • Cloud SQL Node.js 커넥터

이점

Cloud SQL 커넥터를 사용하면 다음과 같은 이점이 있습니다.

  • IAM 승인: IAM 권한을 사용하여 Cloud SQL 인스턴스에 연결할 수 있는 사용자 또는 대상을 제어합니다.
  • 편의성: SSL 인증서 관리, 방화벽 규칙 구성 또는 승인된 네트워크 사용 설정에 대한 요구사항을 삭제합니다.

시작하기 전에

  • Cloud SQL Admin API를 사용 설정합니다.

    Enable the API

  • Cloud SQL 인스턴스를 만들고 기본 사용자를 구성합니다.

    인스턴스를 만드는 방법에 대한 자세한 내용은 인스턴스 만들기를 참조하세요.

    기본 사용자를 구성하는 방법에 대한 자세한 내용은 기본 사용자 계정의 비밀번호 설정을 참조하세요.

  • Cloud SQL 인스턴스에 연결하는 데 필요한 역할과 권한이 구성되었습니다.

설정

자바

Cloud SQL Java 커넥터는 Cloud SQL 인스턴스에 연결할 때 IAM 기반 승인 및 암호화를 제공하는 라이브러리입니다. Cloud SQL 인스턴스가 아직 없으면 네트워크 경로를 제공할 수 없습니다.

설치

Cloud SQL Java 커넥터를 사용하여 JDBC 및 R2DBC용 드라이버를 빌드하고 사용하는 방법은 다음 링크를 참조하세요.

애플리케이션의 컨텍스트에서 사용되는 이 라이브러리의 예시는 다음 샘플 애플리케이션을 참조하세요.

인증

이 라이브러리는 애플리케이션 기본 사용자 인증 정보를 사용하여 Cloud SQL 서버와의 연결을 인증합니다.

사용자 인증 정보를 로컬에서 활성화하려면 다음 gcloud 명령어를 사용하세요.

    gcloud auth application-default login
    

Intellij와 연결

Cloud SQL 인스턴스에 IntelliJ를 연결하려면 드라이버 설정 페이지의 추가 파일 섹션에서 종속 항목을 사용하여 라이브러리를 jar로 추가해야 합니다. 예를 들어 이를 위해 Cloud SQL Java 커넥터 출시 페이지에서 사전 빌드된 fat jar를 찾아볼 수 있습니다.

Python

Cloud SQL Python 커넥터는 Cloud SQL 데이터베이스에 연결할 수 있는 충분한 권한이 있는 사용자가 IP를 직접 허용 목록에 추가하거나 SSL 인증서를 관리할 필요 없이 데이터베이스 드라이버와 함께 사용할 수 있는 라이브러리입니다.

Cloud SQL Python 커넥터 사용의 대화형 예시는 Cloud SQL Python 커넥터 노트북을 엽니다.

MySQL에서 지원하는 드라이버는 pymysql입니다.

설치

Cloud SQL Python 커넥터의 최신 버전을 설치하려면 pip install 명령어를 사용하고 데이터베이스에 대해 pymysql 드라이버를 지정합니다.

    pip install "cloud-sql-python-connector[pymysql]"
    

인증

이 라이브러리는 애플리케이션 기본 사용자 인증 정보를 사용하여 Cloud SQL 서버와의 연결을 인증합니다.

사용자 인증 정보를 로컬에서 활성화하려면 다음 gcloud 명령어를 사용하세요.

    gcloud auth application-default login
    

Go

Cloud SQL Go 커넥터는 Go 언어와 함께 사용할 수 있도록 설계된 Cloud SQL 커넥터입니다. 이 커넥터는 보안 향상을 위해 데이터베이스 프로토콜에 관계없이 클라이언트 커넥터와 서버 측 프록시 사이에 강력하고 수동으로 인증된 TLS 1.3 암호화를 사용합니다.

설치

go get으로 이 저장소를 설치할 수 있습니다.

    go get cloud.google.com/go/cloudsqlconn
    

Node.js

Node.js 커넥터는 Cloud SQL 인스턴스에 안전하게 연결할 수 있는 Node.js 런타임에 사용하도록 설계된 라이브러리입니다.

설치

npm install로 라이브러리를 설치할 수 있습니다.

    npm install @google-cloud/cloud-sql-connector
    

사용

자바

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


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

    config.addDataSourceProperty("socketFactory", "com.google.cloud.sql.mysql.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

라이브러리 사용에 대한 자세한 내용은 이 커넥터 사용 방법을 참조하세요. GitHub에서 연결 테스트 코드 예시를 봅니다.

import os

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

import sqlalchemy


def connect_with_connector() -> sqlalchemy.engine.base.Engine:
    """
    Initializes a connection pool for a Cloud SQL instance of MySQL.

    Uses the Cloud SQL Python Connector package.
    """
    # 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

    connector = Connector(ip_type)

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

    pool = sqlalchemy.create_engine(
        "mysql+pymysql://",
        creator=getconn,
        # ...
    )
    return pool

Go

라이브러리 사용에 대한 자세한 안내는 사용량을 참조하세요. GitHub에서 연결 테스트 코드 예시를 봅니다.

package cloudsql

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

	"cloud.google.com/go/cloudsqlconn"
	"github.com/go-sql-driver/mysql"
)

func connectWithConnector() (*sql.DB, error) {
	mustGetenv := func(k string) string {
		v := os.Getenv(k)
		if v == "" {
			log.Fatalf("Fatal Error in connect_connector.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 passwords and other secrets safe.
	var (
		dbUser                 = mustGetenv("DB_USER")                  // e.g. 'my-db-user'
		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")
	)

	d, err := cloudsqlconn.NewDialer(context.Background())
	if err != nil {
		return nil, fmt.Errorf("cloudsqlconn.NewDialer: %w", err)
	}
	var opts []cloudsqlconn.DialOption
	if usePrivate != "" {
		opts = append(opts, cloudsqlconn.WithPrivateIP())
	}
	mysql.RegisterDialContext("cloudsqlconn",
		func(ctx context.Context, addr string) (net.Conn, error) {
			return d.Dial(ctx, instanceConnectionName, opts...)
		})

	dbURI := fmt.Sprintf("%s:%s@cloudsqlconn(localhost:3306)/%s?parseTime=true",
		dbUser, dbPwd, dbName)

	dbPool, err := sql.Open("mysql", dbURI)
	if err != nil {
		return nil, fmt.Errorf("sql.Open: %w", err)
	}
	return dbPool, nil
}

Node.js

라이브러리 사용 방법에 대한 자세한 내용은 사용을 참조하세요.

const mysql = require('mysql2/promise');
const {Connector} = require('@google-cloud/cloud-sql-connector');

// In case the PRIVATE_IP environment variable is defined then we set
// the ipType=PRIVATE for the new connector instance, otherwise defaults
// to public ip type.
const getIpType = () =>
  process.env.PRIVATE_IP === '1' || process.env.PRIVATE_IP === 'true'
    ? 'PRIVATE'
    : 'PUBLIC';

// connectWithConnector initializes a connection pool for a Cloud SQL instance
// of MySQL using the Cloud SQL Node.js Connector.
const connectWithConnector = 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 connector = new Connector();
  const clientOpts = await connector.getOptions({
    instanceConnectionName: process.env.INSTANCE_CONNECTION_NAME,
    ipType: getIpType(),
  });
  const dbConfig = {
    ...clientOpts,
    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'
    // ... Specify additional properties here.
    ...config,
  };
  // Establish a connection to the database.
  return mysql.createPool(dbConfig);
};

적용

커넥터 적용을 사용하면 Cloud SQL 인증 프록시 또는 Cloud SQL 언어 커넥터만 사용하여 Cloud SQL 인스턴스에 연결하도록 적용할 수 있습니다. 커넥터 적용을 사용하면 Cloud SQL에서 데이터베이스에 대한 직접 연결을 거부합니다.

Private Service Connect가 사용 설정된 인스턴스를 사용하는 경우 제한사항이 있습니다. 인스턴스에 커넥터 적용이 사용 설정된 경우 인스턴스의 읽기 복제본을 만들 수 없습니다. 마찬가지로 인스턴스에 읽기 복제본이 있는 경우 인스턴스에 커넥터 적용을 사용 설정할 수 없습니다.

gcloud

Cloud SQL 인증 프록시 또는 Cloud SQL 언어 커넥터만 사용하여 인스턴스에 연결하도록 적용하려면 gcloud sql instances patch 명령어를 사용하세요.

gcloud sql instances patch INSTANCE_NAME \
--connector-enforcement=REQUIRED

INSTANCE_NAME을 Cloud SQL 인스턴스의 이름으로 바꿉니다.

REST

요청 데이터를 사용하기 전에 다음을 바꿉니다.

  • PROJECT_ID: 인스턴스가 포함된 Google Cloud 프로젝트의 ID 또는 프로젝트 번호
  • INSTANCE_NAME: Cloud SQL 인스턴스의 이름

HTTP 메서드 및 URL:

PATCH https://sqladmin.googleapis.com/v1/projects/PROJECT_ID/instances/INSTANCE_NAME

JSON 요청 본문:

{
  "kind": "sql#instance",
  "name": INSTANCE_NAME,
  "project": PROJECT_ID,
  "settings": {
  "connectorEnforcement": "REQUIRED",
  "kind": "sql#settings"
  }
}

요청을 보내려면 다음 옵션 중 하나를 펼칩니다.

다음과 비슷한 JSON 응답이 표시됩니다.

{
  "kind": "sql#operation",
  "targetLink": "https://sqladmin.googleapis.com/v1/projects/PROJECT_ID/instances/INSTANCE_NAME",
  "status": "PENDING",
  "user": "user@example.com",
  "insertTime": "2020-01-16T02:32:12.281Z",
  "operationType": "UPDATE",
  "name": "OPERATION_ID",
  "targetId": "INSTANCE_NAME",
  "selfLink": "https://sqladmin.googleapis.com/v1/projects/PROJECT_ID/operations/OPERATION_ID",
  "targetProject": "PROJECT_ID"
}

문제 해결

드라이버 버전

비호환성을 방지하려면 최신 버전의 Cloud SQL 커넥터 및 데이터베이스 드라이버를 사용해야 합니다. 일부 이전 버전의 드라이버는 지원되지 않습니다.

연결 경로

Cloud SQL 커넥터는 연결에 대한 승인을 제공하지만 연결에 대한 새 경로는 제공하지 않습니다. 예를 들어 비공개 IP 주소를 사용하여 Cloud SQL 인스턴스에 연결하려면 애플리케이션에 이미 VPC 액세스 권한이 있어야 합니다.

연결 문제 디버그

연결 문제와 관련해 추가 도움이 필요하면 문제 해결연결 문제 디버그 페이지를 참조하세요.

다음 단계