Tentang koneksi Cloud SQL

Halaman ini memberikan ringkasan tentang cara terhubung ke instance Cloud SQL dan menjelaskan opsi autentikasi dan otorisasi yang tersedia.

Ringkasan

Saat mempertimbangkan cara untuk terhubung ke instance Cloud SQL, terdapat banyak pilihan yang perlu diingat, termasuk:

  • Apakah Anda ingin instance Cloud SQL dapat diakses dari internet, atau dirahasiakan dalam jaringan Virtual Private Cloud (VPC), atau membuatnya dapat diakses secara publik dan pribadi?
  • Apakah Anda berencana menulis kode koneksi sendiri, atau ingin terhubung menggunakan alat yang tersedia untuk publik seperti Proxy Auth Cloud SQL atau klien mysql?
  • Apakah Anda ingin mewajibkan enkripsi melalui SSL/TLS atau mengizinkan traffic yang tidak terenkripsi?

Di bagian berikut, kita akan membahas opsi yang disediakan Cloud SQL untuk menghubungkan, memberi otorisasi, dan mengautentikasi ke database Anda.

  • Cara menghubungkan - jalur jaringan mana yang Anda gunakan untuk menjangkau instance:
    • Alamat IP internal khusus VPC (Pribadi).
    • Alamat IP eksternal yang dapat diakses internet (Publik).
  • Cara memberikan otorisasi - koneksi mana yang diotorisasi dan diizinkan untuk terhubung ke instance Cloud SQL Anda:
    • Library proxy Auth Cloud SQL dan konektor Cloud SQL untuk Java dan Python - library ini menyediakan akses berdasarkan IAM.
    • Sertifikat SSL/TLS yang dikelola sendiri - sertifikat ini hanya mengizinkan koneksi berdasarkan kunci publik tertentu.
    • Jaringan yang diizinkan - daftar alamat IP yang diizinkan untuk terhubung.
  • Cara mengautentikasi - metode untuk login ke database Anda.
    • Autentikasi database bawaan - login dengan nama pengguna/sandi yang disetel di mesin database.

Gunakan informasi berikut untuk memutuskan opsi koneksi, otorisasi, dan autentikasi yang paling cocok bagi Anda.

Sebelum memulai

Memberi akses ke aplikasi tidak otomatis mengaktifkan akun pengguna database untuk terhubung ke instance. Sebelum dapat terhubung ke instance, Anda harus memiliki akun pengguna database yang dapat dihubungkan. Untuk instance baru, ini berarti Anda harus mengonfigurasi akun pengguna default. Untuk mengetahui informasi selengkapnya, lihat Mengelola pengguna dengan autentikasi bawaan.

Cara terhubung ke Cloud SQL

Koneksi database menggunakan resource di server dan aplikasi yang terhubung. Selalu gunakan praktik pengelolaan koneksi yang baik untuk meminimalkan jejak aplikasi Anda dan mengurangi kemungkinan terlampauinya batas koneksi Cloud SQL. Untuk mengetahui informasi selengkapnya, lihat Mengelola koneksi database.

IP publik dan pribadi

Di Cloud SQL, IP publik berarti instance dapat diakses melalui internet publik. Sebaliknya, instance yang hanya menggunakan IP pribadi tidak dapat diakses melalui internet publik, tetapi dapat diakses melalui Virtual Private Cloud (VPC). Instance Cloud SQL dapat memiliki alamat IP publik dan pribadi.

IP Pribadi

IP pribadi adalah alamat IPv4 yang dapat diakses di Virtual Private Cloud (VPC).

Anda dapat menggunakan alamat ini untuk terhubung dari resource lain yang memiliki akses ke VPC. Koneksi melalui IP pribadi biasanya memberikan latensi yang lebih rendah dan vektor serangan terbatas karena tidak perlu melintasi internet. Secara opsional, Anda dapat mewajibkan agar semua koneksi menggunakan proxy Cloud SQL atau sertifikat SSL yang dikelola sendiri.

Sebaiknya konfigurasi instance dengan IP pribadi saat terhubung dari klien di resource yang memiliki akses ke VPC. Untuk mengetahui informasi lebih lanjut tentang resource yang dapat menggunakan IP pribadi, lihat Persyaratan untuk IP Pribadi.

Untuk jalur IP pribadi, layanan dan aplikasi berikut terhubung langsung ke instance Anda melalui Akses VPC Serverless:

  • Lingkungan standar App Engine
  • Lingkungan fleksibel App Engine
  • Fungsi Cloud Run
  • Cloud Run

Pelajari lebih lanjut cara menggunakan IP pribadi dengan Cloud SQL

Untuk mengetahui petunjuk tentang cara menambahkan IP pribadi ke instance, lihat salah satu hal berikut:

IP Publik

IP publik adalah alamat IPv4 yang tersedia secara eksternal di internet publik. Alamat ini dapat menerima koneksi dari perangkat di dalam dan di luar jaringan Google, termasuk dari lokasi seperti rumah atau kantor Anda.

Untuk membantu menjaga keamanan instance Anda, setiap koneksi ke instance Cloud SQL yang menggunakan IP publik harus diberi otorisasi menggunakan Proxy Auth Cloud SQL atau jaringan yang diizinkan.

Mengonfigurasi instance dengan IP publik adalah cara terbaik saat terhubung dari klien yang tidak memenuhi persyaratan VPC.

Untuk mengetahui petunjuk tentang cara menambahkan IP publik ke instance, lihat Mengonfigurasi Konektivitas IP Publik.

Untuk mengetahui informasi tentang cara menghubungkan klien mysql ke instance Cloud SQL menggunakan IP publik, lihat Menghubungkan menggunakan klien database.

Alamat IP yang ditetapkan secara dinamis

Beberapa aplikasi perlu terhubung ke instance Cloud SQL Anda menggunakan alamat IP yang ditetapkan secara dinamis atau sementara. Hal ini berlaku untuk aplikasi Platform as a Service (PaaS), di antara lainnya.

Solusi terbaik untuk aplikasi ini adalah terhubung dengan menggunakan Proxy Auth Cloud SQL. Solusi ini memberikan kontrol akses terbaik untuk instance Anda.

Opsi koneksi untuk instance

Bagian ini berisi fitur yang didukung Cloud SQL untuk menghubungkan ke instance. Bagian ini juga berisi opsi koneksi yang didukung untuk membuat, menonaktifkan, dan mengaktifkan instance.

Fitur yang didukung

Tabel berikut mencantumkan fitur yang didukung Cloud SQL untuk menghubungkan ke instance menggunakan koneksi pribadi.

Fitur Instance dengan akses layanan pribadi saja Instance dengan Private Service Connect saja Instance dengan akses layanan pribadi dan Private Service Connect
Menghubungkan dari beberapa VPC Tidak didukung. Didukung. Didukung dengan menggunakan endpoint Private Service Connect.
Replika eksternal Didukung. Tidak didukung. Didukung dengan menggunakan konektivitas keluar untuk akses layanan pribadi.
Endpoint tulis Didukung. Tidak didukung. Didukung untuk akses layanan pribadi.
Mengubah jaringan VPC terkait untuk akses layanan pribadi Didukung. Tidak berlaku. Tidak didukung untuk akses layanan pribadi karena instance telah mengaktifkan Private Service Connect untuknya. Tidak berlaku untuk Private Service Connect.
Visibilitas alamat IP klien ke Cloud SQL Didukung. Tidak didukung. Didukung dengan menggunakan alamat IP akses layanan pribadi. Tidak didukung dengan menggunakan endpoint Private Service Connect.

Opsi koneksi untuk membuat instance

Cloud SQL mendukung konfigurasi IP pribadi dan IP publik. Anda dapat memilih opsi koneksi berdasarkan persyaratan aplikasi Anda.

Anda dapat mengonfigurasi IP pribadi agar instance Cloud SQL tetap bersifat pribadi dalam jaringan VPC. Jenis koneksi pribadi berikut didukung:

  • Akses layanan pribadi: terhubung ke instance Cloud SQL dari satu jaringan VPC
  • Private Service Connect: terhubung ke instance Cloud SQL dari beberapa jaringan VPC yang tergabung dalam grup, tim, project, atau organisasi yang berbeda

Jika Anda ingin instance mengakses koneksi dari klien di dalam dan di luar jaringan Google Cloudmelalui internet publik, konfigurasikan IP publik untuk instance.

Cloud SQL mendukung opsi koneksi berikut untuk membuat instance:

Menonaktifkan opsi koneksi

Cloud SQL mendukung penonaktifan opsi koneksi berikut untuk instance:

  • IP publik di instance dengan akses layanan pribadi dan IP publik
  • IP publik di instance dengan IP publik, akses layanan pribadi, dan Private Service Connect
  • Private Service Connect di instance dengan Private Service Connect dan akses layanan pribadi
  • Private Service Connect di instance dengan Private Service Connect, akses layanan pribadi, dan IP publik

Mengaktifkan opsi koneksi

Cloud SQL mendukung pengaktifan opsi koneksi berikut untuk instance:

  • Akses layanan pribadi di instance dengan IP publik saja
  • Private Service Connect di instance dengan akses layanan pribadi saja
  • Private Service Connect di instance dengan akses layanan pribadi dan IP publik
  • IP publik di instance dengan akses layanan pribadi saja

Batasan

  • Membuat instance dengan IP publik dan Private Service Connect tidak didukung.
  • Menonaktifkan akses layanan pribadi pada instance dengan akses layanan pribadi dan Private Service Connect tidak didukung.
  • Menonaktifkan akses layanan pribadi pada instance dengan akses layanan pribadi dan IP publik tidak didukung.
  • Jika Anda memiliki instance yang hanya menggunakan IP publik, mengaktifkan akses layanan pribadi dan Private Service Connect secara bersamaan tidak didukung. Pertama, aktifkan akses layanan pribadi, lalu aktifkan Private Service Connect.
  • Pemberian izin berbasis IP dengan menggunakan jaringan yang diotorisasi tidak didukung untuk instance yang mengaktifkan Private Service Connect.

Cara memberikan otorisasi ke Cloud SQL

Cloud SQL Language Connector

Konektor Bahasa Cloud SQL adalah library klien yang memberikan enkripsi dan otorisasi IAM saat terhubung ke instance Cloud SQL. Cloud SQL merekomendasikan penggunaan Cloud SQL Language Connectors untuk terhubung ke instance Cloud SQL Anda, bukan opsi koneksi lainnya.

Anda dapat menggunakan library ini secara langsung dari bahasa pemrograman yang didukung. Keduanya memberikan autentikasi yang sama dengan Proxy Auth Cloud SQL tanpa memerlukan proses eksternal. Hal ini memberikan keamanan yang lebih kuat dan persyaratan konfigurasi yang lebih rendah untuk terhubung ke Cloud SQL. Cloud SQL Language Connector juga menggunakan kode yang sama saat terhubung menggunakan alamat IP publik atau alamat IP pribadi.

Untuk memulai, lihat Cloud SQL Language Connector.

Proxy Auth Cloud SQL

Dengan Proxy Auth Cloud SQL, Anda dapat memberi otorisasi dan mengamankan koneksi menggunakan izin Identity and Access Management (IAM). Proxy Auth Cloud SQL memvalidasi koneksi menggunakan kredensial untuk pengguna atau akun layanan, dan menggabungkan koneksi dalam lapisan SSL/TLS yang diberi otorisasi untuk instance Cloud SQL. Untuk mengetahui detail selengkapnya tentang cara kerja Proxy Auth Cloud SQL, lihat Tentang Proxy Auth Cloud SQL.

Menggunakan Proxy Auth Cloud SQL adalah metode yang direkomendasikan untuk mengautentikasi koneksi ke instance Cloud SQL karena merupakan metode teraman.

Proxy Auth Cloud SQL adalah library open source yang didistribusikan sebagai biner yang dapat dieksekusi. Proxy Auth Cloud SQL bertindak sebagai server perantara yang memproses koneksi masuk, menggabungkannya ke dalam SSL/TLS, lalu meneruskannya ke instance Cloud SQL.

Beberapa lingkungan menyediakan mekanisme yang terhubung menggunakan Proxy Auth Cloud SQL. Untuk mengetahui petunjuk tentang cara menghubungkan menggunakan lingkungan tersebut, lihat salah satu hal berikut:

Sertifikat SSL/TLS yang dikelola sendiri

Daripada menggunakan Proxy Auth Cloud SQL untuk mengenkripsi koneksi Anda, ini memungkinkan untuk menyiapkan sertifikat SSL/TLS klien/server yang khusus untuk instance Cloud SQL. Sertifikat ini digunakan untuk memvalidasi klien dan server satu sama lain dan mengenkripsi koneksi di antara keduanya.

Sangat disarankan untuk menggunakan sertifikat SSL/TLS yang dikelola sendiri untuk memberikan enkripsi saat tidak menggunakan Proxy Auth Cloud SQL. Jika hal ini tidak dilakukan, data Anda akan disebarkan secara tidak aman dan mungkin dicegat atau diperiksa oleh pihak ketiga.

Untuk mulai menggunakan sertifikat SSL/TLS yang dikelola sendiri, lihat Memberikan otorisasi dengan sertifikat SSL/TLS.

Jaringan resmi

Kecuali menggunakan Proxy Auth Cloud SQL, koneksi ke alamat IP publik suatu instance hanya diizinkan jika koneksi tersebut berasal dari jaringan resmi. Jaringan yang diizinkan adalah alamat atau rentang IP yang telah ditentukan sebagai pengguna memiliki izin untuk terhubung.

Untuk mulai menggunakan jaringan resmi lihat Memberikan otorisasi dengan Jaringan Resmi.

Cara mengautentikasi ke Cloud SQL

Autentikasi memberikan kontrol akses dengan memverifikasi identitas pengguna. Untuk pengguna akhir, autentikasi dicapai saat pengguna memasukkan kredensial (nama pengguna dan sandi). Untuk aplikasi, autentikasi dilakukan saat kredensial pengguna ditetapkan ke akun layanan.

Cloud SQL menggunakan autentikasi bawaan database yang melakukan autentikasi menggunakan nama pengguna dan sandi. Untuk mengetahui informasi selengkapnya, lihat membuat dan mengelola pengguna MySQL.

Alat untuk terhubung ke Cloud SQL

Tabel berikut berisi beberapa opsi untuk terhubung ke Cloud SQL:

Contoh kode

Anda dapat terhubung ke Proxy Auth Cloud SQL dari bahasa apa pun yang memungkinkan Anda terhubung ke soket Unix atau TCP. Di bawah ini terdapat beberapa cuplikan kode dari contoh lengkap di GitHub untuk membantu memahami cara kerja dalam aplikasi.

Menghubungkan dengan TCP

Pernyataan pemanggilan Proxy Auth Cloud SQL:

./cloud-sql-proxy INSTANCE_CONNECTION_NAME &

Untuk melihat cuplikan ini dalam konteks aplikasi web, lihat README di GitHub.

import os

import sqlalchemy


def connect_tcp_socket() -> sqlalchemy.engine.base.Engine:
    """Initializes a TCP connection pool for a Cloud SQL instance of MySQL."""
    # 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. 3306

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

Untuk melihat cuplikan ini dalam konteks aplikasi web, lihat README di GitHub.

Catatan:

  • INSTANCE_CONNECTION_NAME harus direpresentasikan sebagai <MY-PROJECT>:<INSTANCE-REGION>:<INSTANCE-NAME>
  • Menggunakan argumen ipTypes=PRIVATE akan memaksa SocketFactory untuk terhubung dengan IP pribadi yang terkait dengan sebuah instance
  • Lihat persyaratan versi factory soket JDBC untuk file pom.xml di sini .


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

public class TcpConnectionPoolFactory extends ConnectionPoolFactory {

  // Saving credentials in environment variables is convenient, but not secure - consider a more
  // secure solution such as 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();

    // The following URL is equivalent to setting the config options below:
    // jdbc:mysql://<INSTANCE_HOST>:<DB_PORT>/<DB_NAME>?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:%s/%s", INSTANCE_HOST, DB_PORT, DB_NAME));
    config.setUsername(DB_USER); // e.g. "root", "mysql"
    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);
  }
}

Untuk melihat cuplikan ini dalam konteks aplikasi web, lihat README di GitHub.

const mysql = require('promise-mysql');
const fs = require('fs');

// createTcpPool initializes a TCP connection pool for a Cloud SQL
// instance of MySQL.
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 = {
    host: process.env.INSTANCE_HOST, // e.g. '127.0.0.1'
    port: process.env.DB_PORT, // e.g. '3306'
    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);
};

Untuk melihat cuplikan ini dalam konteks aplikasi web, lihat README di GitHub.

package cloudsql

import (
	"crypto/tls"
	"crypto/x509"
	"database/sql"
	"errors"
	"fmt"
	"log"
	"os"

	"github.com/go-sql-driver/mysql"
)

// connectTCPSocket initializes a TCP connection pool for a Cloud SQL
// instance of MySQL.
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.", 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'
		dbPort    = mustGetenv("DB_PORT")       // e.g. '3306'
		dbTCPHost = mustGetenv("INSTANCE_HOST") // e.g. '127.0.0.1' ('172.17.0.1' if deployed to GAE Flex)
	)

	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: %w", err)
	}

	// ...

	return dbPool, nil
}

Untuk melihat cuplikan ini dalam konteks aplikasi web, lihat README di GitHub.

using MySql.Data.MySqlClient;
using System;

namespace CloudSql
{
    public class MySqlTcp
    {
        public static MySqlConnectionStringBuilder NewMysqlTCPConnectionString()
        {
            // Equivalent connection string:
            // "Uid=<DB_USER>;Pwd=<DB_PASS>;Host=<INSTANCE_HOST>;Database=<DB_NAME>;"
            var connectionString = new MySqlConnectionStringBuilder()
            {
                // 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.
                Server = 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'
                Database = Environment.GetEnvironmentVariable("DB_NAME"), // e.g. 'my-database'

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

        }
    }
}

Untuk melihat cuplikan ini dalam konteks aplikasi web, lihat README di GitHub.

tcp: &tcp
  adapter: mysql2
  # 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") { 3306 }%>

Untuk melihat cuplikan ini dalam konteks aplikasi web, lihat README di GitHub.

namespace Google\Cloud\Samples\CloudSQL\MySQL;

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('mysql:dbname=%s;host=%s', $dbName, $instanceHost);

            // 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/mysql/connect-external-app',
                    $e->getMessage()
                ),
                $e->getCode(),
                $e
            );
        }

        return $conn;
    }
}

Pernyataan pemanggilan Proxy Auth Cloud SQL:

./cloud-sql-proxy --unix-socket /cloudsql INSTANCE_CONNECTION_NAME &

Untuk melihat cuplikan ini dalam konteks aplikasi web, lihat README di GitHub.

import os

import sqlalchemy


def connect_unix_socket() -> sqlalchemy.engine.base.Engine:
    """Initializes a Unix socket connection pool for a Cloud SQL instance of MySQL."""
    # 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_user = os.environ["DB_USER"]  # e.g. 'my-database-user'
    db_pass = os.environ["DB_PASS"]  # e.g. 'my-database-password'
    db_name = os.environ["DB_NAME"]  # e.g. 'my-database'
    unix_socket_path = os.environ[
        "INSTANCE_UNIX_SOCKET"
    ]  # e.g. '/cloudsql/project:region:instance'

    pool = sqlalchemy.create_engine(
        # Equivalent URL:
        # mysql+pymysql://<db_user>:<db_pass>@/<db_name>?unix_socket=<socket_path>/<cloud_sql_instance_name>
        sqlalchemy.engine.url.URL.create(
            drivername="mysql+pymysql",
            username=db_user,
            password=db_pass,
            database=db_name,
            query={"unix_socket": unix_socket_path},
        ),
        # ...
    )
    return pool

Untuk melihat cuplikan ini dalam konteks aplikasi web, lihat README di GitHub.


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);

    // Unix sockets are not natively supported in Java, so it is necessary to use the Cloud SQL
    // Java Connector to connect. When setting INSTANCE_UNIX_SOCKET, the connector will 
    // call an external package that will enable Unix socket connections.
    // Note: For Java users, the Cloud SQL Java Connector can provide authenticated connections
    // which is usually preferable to using the Cloud SQL Proxy with Unix sockets.
    // See https://github.com/GoogleCloudPlatform/cloud-sql-jdbc-socket-factory for details.
    if (INSTANCE_UNIX_SOCKET != null) {
      config.addDataSourceProperty("unixSocketPath", INSTANCE_UNIX_SOCKET);
    }


    // cloudSqlRefreshStrategy set to "lazy" is used to perform a
    // refresh when needed, rather than on a scheduled interval.
    // This is recommended for serverless environments to
    // avoid background refreshes from throttling CPU.
    config.addDataSourceProperty("cloudSqlRefreshStrategy", "lazy");

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

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

Untuk melihat cuplikan ini dalam konteks aplikasi web, lihat README di GitHub.

const mysql = require('promise-mysql');

// createUnixSocketPool initializes a Unix socket connection pool for
// a Cloud SQL instance of MySQL.
const createUnixSocketPool = 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.
  return 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'
    socketPath: process.env.INSTANCE_UNIX_SOCKET, // e.g. '/cloudsql/project:region:instance'
    // Specify additional properties here.
    ...config,
  });
};

Untuk melihat cuplikan ini dalam konteks aplikasi web, lihat README di GitHub.

using MySql.Data.MySqlClient;
using System;

namespace CloudSql
{
    public class MySqlUnix
    {
        public static MySqlConnectionStringBuilder NewMysqlUnixSocketConnectionString()
        {
            // Equivalent connection string:
            // "Server=<INSTANCE_UNIX_SOCKET>;Uid=<DB_USER>;Pwd=<DB_PASS>;Database=<DB_NAME>;Protocol=unix"
            var connectionString = new MySqlConnectionStringBuilder()
            {
                // The Cloud SQL proxy provides encryption between the proxy and instance.
                SslMode = MySqlSslMode.Disabled,

                // 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.
                Server = Environment.GetEnvironmentVariable("INSTANCE_UNIX_SOCKET"), // e.g. '/cloudsql/project:region:instance'
                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'
                ConnectionProtocol = MySqlConnectionProtocol.UnixSocket
            };
            connectionString.Pooling = true;
            // Specify additional properties here.
            return connectionString;
        }
    }
}

Untuk melihat cuplikan ini dalam konteks aplikasi web, lihat README di GitHub.

package cloudsql

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

	_ "github.com/go-sql-driver/mysql"
)

// connectUnixSocket initializes a Unix socket connection pool for
// a Cloud SQL instance of MySQL.
func connectUnixSocket() (*sql.DB, error) {
	mustGetenv := func(k string) string {
		v := os.Getenv(k)
		if v == "" {
			log.Fatalf("Fatal Error in connect_unix.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 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'
		unixSocketPath = mustGetenv("INSTANCE_UNIX_SOCKET") // e.g. '/cloudsql/project:region:instance'
	)

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

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

	// ...

	return dbPool, nil
}

Untuk melihat cuplikan ini dalam konteks aplikasi web, lihat README di GitHub.

unix: &unix
  adapter: mysql2
  # 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" } %>
  # Specify the Unix socket path as host
  socket: "<%= ENV["INSTANCE_UNIX_SOCKET"] %>"

Untuk melihat cuplikan ini dalam konteks aplikasi web, lihat README di GitHub.

namespace Google\Cloud\Samples\CloudSQL\MySQL;

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

class DatabaseUnix
{
    public static function initUnixDatabaseConnection(): 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'
            $instanceUnixSocket = getenv('INSTANCE_UNIX_SOCKET'); // e.g. '/cloudsql/project:region:instance'

            // Connect using UNIX sockets
            $dsn = sprintf(
                'mysql:dbname=%s;unix_socket=%s',
                $dbName,
                $instanceUnixSocket
            );

            // 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 $instanceUnixSocket (for UNIX socket mode). ' .
                        'The PHP error was %s',
                    $e->getMessage()
                ),
                (int) $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/mysql/connect-external-app',
                    $e->getMessage()
                ),
                (int) $e->getCode(),
                $e
            );
        }

        return $conn;
    }
}

Memecahkan masalah

Jika Anda mengalami masalah saat menghubungkan, periksa halaman berikut untuk membantu melakukan proses debug atau menemukan solusi untuk masalah umum:

Langkah berikutnya