연결 옵션 정보

이 페이지에서는 Cloud SQL 인스턴스에 연결할 수 있는 방법을 간략하게 설명하고 사용 가능한 인증 옵션과 승인 옵션을 설명합니다.

개요

Cloud SQL 인스턴스에 연결하는 방법을 고려할 때는 다음을 포함한 여러 선택사항에 유의해야 합니다.

  • 인터넷에서 Cloud SQL 인스턴스에 액세스하거나 Virtual Private Cloud(VPC) 네트워크 내에서 비공개로 유지하고 싶으신가요? 아니면 공개, 비공개 모두에서 액세스하고 싶으신가요?
  • 자체 연결 코드를 작성할 계획인가요? 아니면 Cloud SQL 인증 프록시 또는 sqlcmd 클라이언트와 같이 일반에 공개된 도구를 사용해 연결할 것인가요?
  • SSL/TLS를 통한 암호화를 요구하거나 암호화되지 않은 트래픽을 허용하고 싶으신가요?

다음 섹션에서는 Cloud SQL에서 제공하는 데이터베이스 연결, 승인, 인증 옵션을 설명합니다.

  • 연결 방법 - 인스턴스에 연결하는 데 사용할 네트워크 경로:
    • VPC 전용(비공개) 내부 IP 주소
    • 인터넷 액세스가 가능한(공개) 외부 IP 주소
  • 승인 방법 - Cloud SQL 인스턴스에 연결하도록 승인 및 허용되는 연결:
    • Cloud SQL 인증 프록시, Java 및 Python용 Cloud SQL 커넥터 라이브러리 - IAM을 기반으로 액세스를 제공합니다.
    • 자체 관리형 SSL/TLS 인증서 - 특정 공개 키를 기반으로 한 연결만 허용합니다.
    • 승인된 네트워크 - 연결이 허용된 IP 주소 목록입니다.
  • 인증 방법 - 데이터베이스에 로그인하는 방식입니다.
    • 기본 제공되는 데이터베이스 인증 - 데이터베이스 엔진에 설정된 사용자 이름/비밀번호로 로그인합니다.

다음 정보를 사용하여 가장 적합한 연결, 승인, 인증 옵션을 결정합니다.

시작하기 전에

애플리케이션에 액세스 권한을 부여하더라도 데이터베이스 사용자 계정이 인스턴스에 자동으로 연결되는 것은 아닙니다. 인스턴스에 연결하려면 연결할 수 있는 데이터베이스 사용자 계정이 있어야 합니다. 즉, 새 인스턴스의 경우 기본 사용자 계정을 구성해 놓아야 합니다. 자세한 내용은 기본 제공되는 인증으로 사용자 관리를 참조하세요.

Cloud SQL에 연결하는 방법

데이터베이스 연결은 서버 및 연결 애플리케이션의 리소스를 사용합니다. 항상 연결 관리 권장사항을 참고하여 애플리케이션의 사용 공간을 최소화하고 Cloud SQL 연결 한도를 초과할 가능성을 줄이세요. 자세한 내용은 데이터베이스 연결 관리를 참조하세요.

공개 IP와 비공개 IP

Cloud SQL에서 공개 IP는 공개 인터넷을 통해 인스턴스에 액세스할 수 있다는 의미입니다. 이와 반대로 공개 인터넷을 통해 비공개 IP만 사용하는 인스턴스에 액세스할 수 없지만 Virtual Private Cloud(VPC)를 통해서는 액세스할 수 있습니다. Cloud SQL 인스턴스에는 공개 및 비공개 IP 주소가 모두 있을 수 있습니다.

비공개 IP

비공개 IP는 Virtual Private Cloud(VPC)에서 액세스할 수 있는 IPv4 주소입니다.

이 주소를 사용하여 VPC에 대한 액세스 권한이 있는 다른 리소스에서 연결할 수 있습니다. 일반적으로 비공개 IP를 통한 연결은 인터넷을 거칠 필요가 없으므로 지연 시간이 짧고 공격 벡터가 제한됩니다. 필요한 경우 모든 연결에서 Cloud SQL 프록시 또는 자체 관리 SSL 인증서를 사용해야 할 수 있습니다.

VPC에 대한 액세스 권한이 있는 리소스의 클라이언트에서 연결할 때는 비공개 IP로 인스턴스를 구성하는 것이 좋습니다. 비공개 IP를 사용할 수 있는 리소스에 대한 자세한 내용은 비공개 IP 요구사항을 참조하세요.

비공개 IP 경로의 경우 다음 서비스와 애플리케이션이 서버리스 VPC 액세스를 통해 인스턴스에 직접 연결됩니다.

  • App Engine 표준 환경
  • App Engine 가변형 환경
  • Cloud Run 함수
  • Cloud Run

Cloud SQL에서 비공개 IP를 사용하는 방법을 자세히 알아보세요.

인스턴스에 비공개 IP를 추가하는 방법은 다음 중 하나를 참조하세요.

공개 IP

공개 IP는 공개 인터넷에서 외부적으로 사용 가능한 IPv4 주소입니다. 이 주소는 집이나 사무실의 장소를 포함하여 Google 네트워크의 내부 및 외부에 있는 모든 기기에서 연결을 수신할 수 있습니다.

인스턴스를 안전하게 유지하려면 공개 IP를 사용하는 Cloud SQL 인스턴스와의 모든 연결에 Cloud SQL 인증 프록시 또는 승인된 네트워크를 사용할 수 있는 권한이 있어야 합니다.

VPC의 요구사항을 충족하지 않는 클라이언트에서 연결할 때는 공개 IP로 인스턴스를 구성하는 것이 가장 좋습니다.

인스턴스에 공개 IP를 추가하는 방법은 공개 IP 연결 구성을 참조하세요.

공개 IP를 사용하여 sqlcmd 클라이언트를 Cloud SQL 인스턴스에 연결하는 방법은 데이터베이스 클라이언트를 사용하여 연결을 참조하세요.

Cloud SQL에 승인하는 방법

Cloud SQL 언어 커넥터

Cloud SQL 언어 커넥터는 Cloud SQL 인스턴스에 연결할 때 암호화 및 IAM 승인을 제공하는 클라이언트 라이브러리입니다. Cloud SQL에서는 다른 연결 옵션보다 Cloud SQL 언어 커넥터를 사용하여 Cloud SQL 인스턴스에 연결하는 것을 권장합니다.

지원되는 프로그래밍 언어로 직접 이러한 라이브러리를 사용할 수 있습니다. 외부 프로세스를 사용할 필요 없이 Cloud SQL 인증 프록시와 동일한 인증을 제공합니다. 보안이 개선되고 Cloud SQL에 연결하기 위한 구성 요구사항이 줄어듭니다. 또한 Cloud SQL 언어 커넥터는 공개 IP 주소 또는 비공개 IP 주소를 사용하여 연결할 때 동일한 코드를 사용합니다.

시작하려면 Cloud SQL 언어 커넥터 정보를 참조하세요.

Cloud SQL 인증 프록시

Cloud SQL 인증 프록시를 사용하면 Identity and Access Management(IAM) 권한을 사용하여 연결을 승인하고 보호할 수 있습니다. Cloud SQL 인증 프록시는 사용자 또는 서비스 계정의 사용자 인증 정보를 사용하고 Cloud SQL 인스턴스에 승인된 SSL/TLS 레이어로 연결을 래핑하여 연결을 검증합니다. Cloud SQL 인증 프록시 작동 방법에 대한 자세한 내용은 Cloud SQL 인증 프록시 정보를 참조하세요.

Cloud SQL 인증 프록시 사용은 Cloud SQL 인스턴스에 대한 연결을 인증하는 가장 안전한 방법이므로 이 방법을 사용하는 것이 좋습니다.

Cloud SQL 인증 프록시는 실행 가능한 바이너리로 배포되는 오픈소스 라이브러리입니다. Cloud SQL 인증 프록시는 수신 연결을 대기하고 SSL/TLS로 래핑한 후 Cloud SQL 인스턴스로 전달하는 중개 서버 역할을 합니다.

일부 환경에서는 Cloud SQL 인증 프록시를 사용하여 연결하는 메커니즘을 제공합니다. 이러한 환경에서 연결하는 방법은 다음 중 하나를 참조하세요.

자체 관리형 SSL/TLS 인증서

Cloud SQL 인증 프록시를 사용하여 연결을 암호화하는 대신 Cloud SQL 인스턴스에 고유한 클라이언트/서버 SSL/TLS 인증서를 설정할 수 있습니다. 이 인증서는 클라이언트 및 서버의 유효성을 상호 검증하고 둘 사이의 연결을 암호화하는 데 사용됩니다.

Cloud SQL 인증 프록시를 사용하지 않는 경우에는 자체 관리형 SSL/TLS 인증서를 사용하여 암호화를 제공하는 것이 좋습니다. 이렇게 하지 않으면 데이터가 안전하지 않은 방식으로 전송되므로 제3자가 가로채거나 들여다볼 수 있습니다.

자체 관리형 SSL/TLS 인증서를 시작하려면 SSL/TLS 인증서로 승인을 참조하세요.

승인된 네트워크

Cloud SQL 인증 프록시를 사용하지 않는 경우 인스턴스의 공개 IP 주소와의 연결은 승인된 네트워크에서 시작되는 연결인 경우에만 허용됩니다. 승인된 네트워크는 사용자가 연결할 권한을 갖도록 지정한 IP 주소 또는 범위입니다.

승인된 네트워크를 시작하려면 승인된 네트워크로 승인을 참조하세요.

Cloud SQL에 인증하는 방법

인증은 사용자의 ID를 확인하여 액세스 제어를 제공합니다. 최종 사용자의 경우 사용자가 사용자 인증 정보(사용자 이름 및 비밀번호)를 입력하면 인증이 수행됩니다. 애플리케이션의 경우, 사용자 인증 정보가 서비스 계정에 할당되어 있으면 인증이 수행됩니다.

Cloud SQL은 사용자 이름과 비밀번호를 사용하여 인증하는 데이터베이스의 기본 인증을 사용합니다. 자세한 내용은 SQL Server 사용자 만들기 및 관리를 참조하세요.

Cloud SQL 연결 도구

다음 표에는 Cloud SQL에 연결하기 위한 옵션이 포함되어 있습니다.

연결 옵션 추가 정보
Cloud SQL 인증 프록시
gcloud CLI
Cloud SQL 언어 커넥터
Cloud Shell
Cloud Code
타사 데이터베이스 관리 도구를 사용하여 연결
SQL Server Management Studio
SSMS 객체 탐색기
Visual Studio

코드 샘플

TCP 소켓에 연결할 수 있게 해주는 모든 언어에서 Cloud SQL 인증 프록시에 연결할 수 있습니다. 다음은 애플리케이션에서 어떻게 함께 작동하는지 이해하는 데 도움이 되는 GitHub 전체 예시의 몇 가지 코드 스니펫입니다.

TCP로 연결

Cloud SQL 인증 프록시 호출 문:

./cloud-sql-proxy INSTANCE_CONNECTION_NAME &

Python

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

import os

import sqlalchemy


def connect_tcp_socket() -> sqlalchemy.engine.base.Engine:
    """Initializes a TCP connection pool for a Cloud SQL instance of SQL Server."""
    # 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.
    db_host = os.environ[
        "INSTANCE_HOST"
    ]  # e.g. '127.0.0.1' ('172.17.0.1' if deployed to GAE Flex)
    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'
    db_port = os.environ["DB_PORT"]  # e.g. 1433

    pool = sqlalchemy.create_engine(
        # Equivalent URL:
        # mssql+pytds://<db_user>:<db_pass>@<db_host>:<db_port>/<db_name>
        sqlalchemy.engine.url.URL.create(
            drivername="mssql+pytds",
            username=db_user,
            password=db_pass,
            database=db_name,
            host=db_host,
            port=db_port,
        ),
        # ...
    )

    return pool

자바

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

참고:

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


import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;
import javax.sql.DataSource;

public class TcpConnectionPoolFactory 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 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");

  private static final String INSTANCE_HOST = System.getenv("INSTANCE_HOST");
  private static final String DB_PORT = System.getenv("DB_PORT");


  public static DataSource createConnectionPool() {
    // The configuration object specifies behaviors for the connection pool.
    HikariConfig config = new HikariConfig();

    // Configure which instance and what database user to connect with.
    config.setJdbcUrl(
        String.format("jdbc:sqlserver://%s:%s;databaseName=%s", INSTANCE_HOST, DB_PORT, DB_NAME));
    config.setUsername(DB_USER); // e.g. "root", "sqlserver"
    config.setPassword(DB_PASS); // e.g. "my-password"


    // ... Specify additional connection properties here.
    // ...

    // Initialize the connection pool using the configuration object.
    return new HikariDataSource(config);
  }
}

Node.js

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

const mssql = require('mssql');

// createTcpPool initializes a TCP connection pool for a Cloud SQL
// instance of SQL Server.
const createTcpPool = 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 dbConfig = {
    server: process.env.INSTANCE_HOST, // e.g. '127.0.0.1'
    port: parseInt(process.env.DB_PORT), // e.g. 1433
    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'
    options: {
      trustServerCertificate: true,
    },
    // ... Specify additional properties here.
    ...config,
  };
  // Establish a connection to the database.
  return mssql.connect(dbConfig);
};

Go

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

package cloudsql

import (
	"database/sql"
	"fmt"
	"log"
	"os"
	"strings"

	_ "github.com/denisenkom/go-mssqldb"
)

// connectTCPSocket initializes a TCP connection pool for a Cloud SQL
// instance of SQL Server.
func connectTCPSocket() (*sql.DB, error) {
	mustGetenv := func(k string) string {
		v := os.Getenv(k)
		if v == "" {
			log.Fatalf("Fatal Error in connect_tcp.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'
		dbTCPHost = mustGetenv("INSTANCE_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("sqlserver", dbURI)
	if err != nil {
		return nil, fmt.Errorf("sql.Open: %w", err)
	}

	// ...

	return dbPool, nil
}

C#

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

using Microsoft.Data.SqlClient;
using System;

namespace CloudSql
{
    public class SqlServerTcp
    {
        public static SqlConnectionStringBuilder NewSqlServerTCPConnectionString()
        {
            // Equivalent connection string:
            // "User Id=<DB_USER>;Password=<DB_PASS>;Server=<INSTANCE_HOST>;Database=<DB_NAME>;"
            var connectionString = new SqlConnectionStringBuilder()
            {
                // 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.
                DataSource = Environment.GetEnvironmentVariable("INSTANCE_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'
                InitialCatalog = Environment.GetEnvironmentVariable("DB_NAME"), // e.g. 'my-database'

                // The Cloud SQL proxy provides encryption between the proxy and instance
                Encrypt = false,
            };
            connectionString.Pooling = true;
            // Specify additional properties here.
            return connectionString;
        }
    }
}

Ruby

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

tcp: &tcp
  adapter: sqlserver
  # Configure additional properties here.
  # 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.
  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("INSTANCE_HOST") { "127.0.0.1" }%> # '172.17.0.1' if deployed to GAE Flex
  port: <%= ENV.fetch("DB_PORT") { 1433 }%> 

PHP

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

namespace Google\Cloud\Samples\CloudSQL\SQLServer;

use PDO;
use PDOException;
use RuntimeException;
use TypeError;

class DatabaseTcp
{
    public static function initTcpDatabaseConnection(): PDO
    {
        try {
            // 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.
            $username = getenv('DB_USER'); // e.g. 'your_db_user'
            $password = getenv('DB_PASS'); // e.g. 'your_db_password'
            $dbName = getenv('DB_NAME'); // e.g. 'your_db_name'
            $instanceHost = getenv('INSTANCE_HOST'); // e.g. '127.0.0.1' ('172.17.0.1' for GAE Flex)

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

            // Connect to the database
            $conn = new PDO(
                $dsn,
                $username,
                $password,
                # ...
            );
        } catch (TypeError $e) {
            throw new RuntimeException(
                sprintf(
                    'Invalid or missing configuration! Make sure you have set ' .
                        '$username, $password, $dbName, and $instanceHost (for TCP mode). ' .
                        'The PHP error was %s',
                    $e->getMessage()
                ),
                $e->getCode(),
                $e
            );
        } catch (PDOException $e) {
            throw new RuntimeException(
                sprintf(
                    'Could not connect to the Cloud SQL Database. Check that ' .
                        'your username and password are correct, that the Cloud SQL ' .
                        'proxy is running, and that the database exists and is ready ' .
                        'for use. For more assistance, refer to %s. The PDO error was %s',
                    'https://cloud.google.com/sql/docs/sqlserver/connect-external-app',
                    $e->getMessage()
                ),
                (int) $e->getCode(),
                $e
            );
        }

        return $conn;
    }
}

문제 해결

연결 문제가 발생하면 다음 페이지를 참조하여 디버깅이나 알려진 문제의 해결책을 찾아보세요.

다음 단계