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를 사용 설정합니다.

    API 사용 설정

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

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

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

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

설정

Java

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 커넥터 노트북을 엽니다.

현재 지원되는 SQL Server용 드라이버는 pytds입니다.

설치

최신 출시 버전을 설치하려면 이 안내를 따르세요.

인증

이 라이브러리는 애플리케이션 기본 사용자 인증 정보를 사용하여 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
    

용도

Java

웹 애플리케이션의 컨텍스트에서 이 스니펫을 보려면 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 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 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);

    // The Java Connector provides SSL encryption, so it should be disabled
    // at the driver level.
    config.addDataSourceProperty("encrypt", "false");

    // ... 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 pytds

import sqlalchemy

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

    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.get("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)

    connect_args = {}
    # If your SQL Server instance requires SSL, you need to download the CA
    # certificate for your instance and include cafile={path to downloaded
    # certificate} and validate_host=False. This is a workaround for a known issue.
    if os.environ.get("DB_ROOT_CERT"):  # e.g. '/path/to/my/server-ca.pem'
        connect_args = {
            "cafile": os.environ["DB_ROOT_CERT"],
            "validate_host": False,
        }

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

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

Go

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

package cloudsql

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

	"cloud.google.com/go/cloudsqlconn"
	mssql "github.com/denisenkom/go-mssqldb"
)

type csqlDialer struct {
	dialer     *cloudsqlconn.Dialer
	connName   string
	usePrivate bool
}

// DialContext adheres to the mssql.Dialer interface.
func (c *csqlDialer) DialContext(ctx context.Context, network, addr string) (net.Conn, error) {
	var opts []cloudsqlconn.DialOption
	if c.usePrivate {
		opts = append(opts, cloudsqlconn.WithPrivateIP())
	}
	return c.dialer.Dial(ctx, c.connName, opts...)
}

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.\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 (
		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")
	)

	dbURI := fmt.Sprintf("user id=%s;password=%s;database=%s;", dbUser, dbPwd, dbName)
	c, err := mssql.NewConnector(dbURI)
	if err != nil {
		return nil, fmt.Errorf("mssql.NewConnector: %w", err)
	}
	dialer, err := cloudsqlconn.NewDialer(context.Background())
	if err != nil {
		return nil, fmt.Errorf("cloudsqlconn.NewDailer: %w", err)
	}
	c.Dialer = &csqlDialer{
		dialer:     dialer,
		connName:   instanceConnectionName,
		usePrivate: usePrivate != "",
	}

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

Node.js

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

const {Connection} = require('tedious');
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 TCP connection
// to a Cloud SQL instance of SQL Server.
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.getTediousOptions({
    instanceConnectionName: process.env.INSTANCE_CONNECTION_NAME,
    ipType: getIpType(),
  });
  const dbConfig = {
    // Please note that the `server` property here is not used and is only
    // defined due to a bug in the tedious driver
    // (ref: https://github.com/tediousjs/tedious/issues/1541)
    // With that in mind, do not try to change this value since it will have no
    // impact in how the connector works, this sample will be updated to remove
    // this property declaration as soon as the tedious driver bug is fixed
    server: '0.0.0.0', // e.g. '127.0.0.1'
    authentication: {
      type: 'default',
      options: {
        userName: process.env.DB_USER, // e.g. 'my-db-user'
        password: process.env.DB_PASS, // e.g. 'my-db-password'
      },
    },
    options: {
      ...clientOpts,
      // Please note that the `port` property here is not used and is only
      // defined due to a bug in the tedious driver
      // (ref: https://github.com/tediousjs/tedious/issues/1541)
      // With that in mind, do not try to change this value since it will have
      // no impact in how the connector works, this sample will be updated to
      // remove this property declaration as soon as the tedious driver bug is
      // fixed
      port: 9999,
      database: process.env.DB_NAME, // e.g. 'my-database'
      useColumnNames: true,
    },
    // ... Specify additional properties here.
    ...config,
  };

  // Establish a connection to the database.
  return new Connection(dbConfig);
};

문제 해결

드라이버 버전

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

연결 경로

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

연결 문제 디버그

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

다음 단계