התחברות מ-Cloud Run

בדף הזה מוסבר איך להתחבר למכונה של Cloud SQL משירות שפועל ב-Cloud Run, ומוצגות דוגמאות.

להוראות מפורטות להפעלת אפליקציית אינטרנט לדוגמה ב-Cloud Run שמחוברת ל-Cloud SQL, קראו את המדריך למתחילים להתחברות מ-Cloud Run.

‫Cloud SQL הוא שירות מנוהל של מסד נתונים, שבעזרתו אפשר ליצור, לתחזק ולנהל מסדי נתונים רלציוניים בענן.

‫Cloud Run היא פלטפורמת מחשוב מנוהלת שמאפשרת להריץ קונטיינרים ישירות על גבי תשתית Cloud de Confiance by S3NS .

הגדרת מכונה של Cloud SQL

  1. אם עדיין לא עשיתם את זה, מפעילים את Cloud SQL Admin API בפרויקט Cloud de Confiance שממנו מתחברים:

    התפקידים שנדרשים כדי להפעיל ממשקי API

    כדי להפעיל ממשקי API, צריך את ההרשאה serviceusage.services.enable. אם יצרתם את הפרויקט, סביר להניח שכבר יש לכם את ההרשאה הזו דרך התפקיד "בעלים" (roles/owner). אחרת, תוכלו לקבל את ההרשאה הזו דרך התפקיד "אדמין בממשק 'שימוש בשירות'" (roles/serviceusage.serviceUsageAdmin). איך מקצים תפקידים

    להפעלת ה-API

  2. יצירת מכונה של Cloud SQL ל-MySQL. כדי לשפר את זמן האחזור, להימנע מעלויות מסוימות של הרשת ולהפחית את הסיכון לכשלים בין אזורים, מומלץ לבחור מיקום למכונה של Cloud SQL באותו אזור של שירות Cloud Run.

    כברירת מחדל, Cloud SQL מקצה כתובת IP ציבורית למכונה חדשה. אפשר גם להקצות כתובת IP פרטית. למידע נוסף על אפשרויות הקישוריות של שניהם, קראו את הדף סקירה כללית על התחברות.

  3. כשיוצרים את המכונה, אפשר לבחור את היררכיית אישורי השרת (CA) עבור המכונה, ואז להגדיר את ההיררכיה כ-serverCaMode עבור המכונה. צריך לבחור באפשרות של רשות אישורים לכל מופע (GOOGLE_MANAGED_INTERNAL_CA) כמצב רשות האישורים של השרת עבור מופעים שרוצים להתחבר אליהם מאפליקציות אינטרנט.

הגדרת Cloud Run

השלבים להגדרת Cloud Run תלויים בסוג כתובת ה-IP שהקציתם למכונת Cloud SQL. אם אתם מנתבים את כל תעבורת הנתונים היוצאת דרך Direct VPC או דרך מחבר של חיבור לרשת (VPC) מאפליקציית serverless, אתם צריכים להשתמש בכתובת IP פרטית. להשוואה בין שתי השיטות לתעבורת נתונים יוצאת, ראו השוואה בין Direct VPC לבין מחברי VPC.

כתובת IP ציבורית (ברירת מחדל)

  • מוודאים שלמופע יש כתובת IP ציבורית. אפשר לבדוק את זה בדף Overview של המופע בCloud de Confiance מסוף. אם אתם צריכים להוסיף כתובת IP ציבורית, תוכלו להיעזר בהוראות שבמאמר בנושא הגדרה של כתובת IP ציבורית.
  • משיגים את INSTANCE_CONNECTION_NAME של המכונה. אפשר למצוא את הערך הזה בדף Overview של המכונה במסוףCloud de Confiance , או על ידי הרצת הפקודה הבאה של gcloud sql instances describe:
       gcloud sql instances describe INSTANCE_NAME
       
    מחליפים את INSTANCE_NAME בשם של המכונה ב-Cloud SQL.
  • מקבלים את CLOUD_RUN_SERVICE_ACCOUNT_NAME של שירות Cloud Run. אפשר למצוא את הערך הזה בדף IAM של הפרויקט שמארח את שירות Cloud Run בCloud de Confiance מסוף, או על ידי הפעלת הפקודה הבאה של gcloud run services describe בפרויקט שמארח את שירות Cloud Run:
    gcloud run services describe CLOUD_RUN_SERVICE_NAME
    --region CLOUD_RUN_SERVICE_REGION --format="value(spec.template.spec.serviceAccountName)"
       
    מחליפים את המשתנים הבאים:
    • ‫CLOUD_RUN_SERVICE_NAME: השם של שירות Cloud Run
    • ‫CLOUD_RUN_SERVICE_REGION: האזור של שירות Cloud Run
  • מגדירים את חשבון השירות של שירות Cloud Run. כדי להתחבר ל-Cloud SQL, צריך לוודא שלחשבון השירות יש Cloud SQL Client תפקיד IAM.
  • אם אתם מוסיפים חיבור של Cloud SQL לשירות חדש, אתם צריכים להכניס את השירות לקונטיינר ולהעלות אותו ל-Container Registry או ל-Artifact Registry. אם עדיין אין לכם חיבור, תוכלו להיעזר בהוראות לבנייה ולפריסה של קובץ אימג' של קונטיינר.
  • אם אתם מתחברים למופעים שהוגדרו עם האפשרות של רשות אישורים (CA) משותפת (GOOGLE_MANAGED_CAS_CA) או עם האפשרות של CA בניהול הלקוח (CUSTOMER_MANAGED_CAS_CA) בתור מצב CA של השרת, אתם צריכים לבחור את סביבת ההפעלה מהדור השני כשבוחרים את סביבת ההפעלה של השירות. שתי האפשרויות של מצב CA של השרת מחייבות חיבור למכונה באמצעות Cloud SQL Auth Proxy v2.

    אם השירות פועל בסביבת זמן ריצה מהדור הראשון, אפשר להתחבר רק למכונות Cloud SQL שמוגדרות עם האפשרות של רשות אישורים (CA) לכל מכונה (GOOGLE_MANAGED_INTERNAL_CA) כמצב ה-CA של השרת. סביבת זמן הריצה מהדור הראשון של Cloud Run כוללת את גרסה 1 של Cloud SQL Auth Proxy. מידע נוסף על דרישות החיבור ל-Cloud SQL עבור Cloud SQL Auth Proxy זמין במאמר בנושא דרישות לשימוש ב-Cloud SQL Auth Proxy.

כמו כל שינוי בהגדרות, הגדרת תצורה חדשה לחיבור ל-Cloud SQL מובילה ליצירת גרסה חדשה של Cloud Run. גם הגרסאות הבאות יקבלו באופן אוטומטי את החיבור הזה ל-Cloud SQL, אלא אם תבצעו עדכונים מפורשים כדי לשנות אותו.

המסוף

  1. כניסה ל-Cloud Run

  2. מתחילים להגדיר את השירות. כדי להוסיף חיבורים של Cloud SQL לשירות קיים:

    1. ברשימה Services, לוחצים על שם השירות הרצוי.
    2. לוחצים על עריכה ופריסה של גרסה חדשה.
  3. מפעילים את האפשרות להתחבר למכונת Cloud SQL:
    1. לוחצים על Container(s) (מאגרי תגים) ואז על Settings (הגדרות).
    2. גוללים לקטע Cloud SQL connections.
    3. לוחצים על הוספת חיבור.
    4. אם עדיין לא הפעלתם את Cloud SQL Admin API, לוחצים על הכפתור Enable the Cloud SQL Admin.

    הוספת חיבור ל-Cloud SQL

    • אם מוסיפים חיבור למכונה של Cloud SQL בפרויקט, בוחרים את המכונה הרצויה של Cloud SQL מהתפריט.
    • אם משתמשים במכונה של Cloud SQL מפרויקט אחר, בוחרים בתפריט באפשרות custom connection string ומזינים את השם המלא של החיבור למכונה בפורמט PROJECT-ID:REGION:INSTANCE-ID.
    • כדי למחוק חיבור, מציבים את הסמן מימין לחיבור עד שמופיע הסמל Delete ולוחצים עליו.
  4. לוחצים על Create או על Deploy.

שורת הפקודה

לפני שמשתמשים בפקודות הבאות, צריך להחליף את הערכים בשדות הבאים:

  • IMAGE עם קובץ האימג' שפורסים
  • ‫SERVICE_NAME בשם של שירות Cloud Run
  • ‫INSTANCE_CONNECTION_NAME עם שם החיבור של המכונה שלכם ב-Cloud SQL, או רשימה של שמות חיבורים שמופרדים בפסיקים.

    אם אתם פורסים קונטיינר חדש, משתמשים בפקודה הבאה:

    gcloud run deploy \
      --image=IMAGE \
      --add-cloudsql-instances=INSTANCE_CONNECTION_NAME
    אם מעדכנים שירות קיים, משתמשים בפקודה הבאה:
    gcloud run services update SERVICE_NAME \
      --add-cloudsql-instances=INSTANCE_CONNECTION_NAME

Terraform

הקוד הבא יוצר קונטיינר בסיסי של Cloud Run, עם מכונה מחוברת של Cloud SQL.

resource "google_cloud_run_v2_service" "default" {
  name     = "cloudrun-service"
  location = "us-central1"

  deletion_protection = false # set to "true" in production

  template {
    containers {
      image = "us-docker.pkg.dev/cloudrun/container/hello:latest" # Image to deploy

      volume_mounts {
        name       = "cloudsql"
        mount_path = "/cloudsql"
      }
    }
    volumes {
      name = "cloudsql"
      cloud_sql_instance {
        instances = [google_sql_database_instance.default.connection_name]
      }
    }
  }
  client     = "terraform"
  depends_on = [google_project_service.secretmanager_api, google_project_service.cloudrun_api, google_project_service.sqladmin_api]
}

  1. מזינים terraform apply כדי להחיל את השינויים.
  2. כדי לוודא שהשינויים בוצעו, לוחצים על השם של שירות Cloud Run, ואז בכרטיסייה Containers מאתרים את ההגדרה Cloud SQL connections.

כתובת IP פרטית

אם חשבון השירות המאשר שייך לפרויקט אחר מזה שמכיל את המכונה של Cloud SQL, מבצעים את הפעולות הבאות:

  • מפעילים את Cloud SQL Admin API בשני הפרויקטים.
  • מוסיפים את הרשאות ה-IAM לחשבון השירות בפרויקט שמכיל את המכונה של Cloud SQL.
תעבורת נתונים יוצאת ישירה ל-VPC ומחברים משתמשים בכתובות IP פרטיות כדי לטפל בתקשורת לרשת ה-VPC. כדי להתחבר ישירות לכתובות IP פרטיות באמצעות אחת משיטות תעבורת הנתונים היוצאת (egress) האלה:
  1. מוודאים שלמכונת Cloud SQL שנוצרה קודם יש כתובת IP פרטית. כדי להוסיף כתובת IP פנימית, אפשר לעיין במאמר בנושא הגדרת כתובת IP פרטית.
  2. מגדירים את שיטת תעבורת הנתונים היוצאת כדי להתחבר לאותה רשת VPC של המכונה ב-Cloud SQL. שימו לב לתנאים הבאים:
    • Direct VPC egress ו-Serverless VPC Access תומכים בתקשורת לרשתות VPC שמחוברות באמצעות Cloud VPN וVPC Network Peering.
    • Direct VPC egress ו-Serverless VPC Access לא תומכים ברשתות מדור קודם.
    • אם אתם לא משתמשים ב- VPC משותף, המחבר צריך להיות באותו פרויקט ובאותו אזור כמו המשאב שמשתמש בו, אבל המחבר יכול לשלוח תנועה למשאבים באזורים שונים.
  3. מתחברים באמצעות כתובת ה-IP הפרטית והיציאה של המופע 3306.

התחברות ל-Cloud SQL

אחרי שמגדירים את Cloud Run, אפשר להתחבר למכונת Cloud SQL.

כתובת IP ציבורית (ברירת מחדל)

בנתיבי IP ציבוריים, אפשר להגדיר את Cloud Run לשימוש בCloud SQL Auth Proxy להצפנה בשתי דרכים:

שימוש ב-Secret Manager

‫Google ממליצה להשתמש ב-Secret Manager כדי לאחסן מידע רגיש כמו פרטי כניסה ל-SQL. ב-Cloud Run, אתם יכולים להעביר סודות כמשתני סביבה או לטעון אותם כנפח אחסון.

אחרי יצירת סוד ב-Secret Manager, מעדכנים שירות קיים באמצעות הפקודה הבאה:

שורת הפקודה

gcloud run services update SERVICE_NAME \
  --add-cloudsql-instances=INSTANCE_CONNECTION_NAME
  --update-env-vars=INSTANCE_CONNECTION_NAME=INSTANCE_CONNECTION_NAME_SECRET \
  --update-secrets=DB_USER=DB_USER_SECRET:latest \
  --update-secrets=DB_PASS=DB_PASS_SECRET:latest \
  --update-secrets=DB_NAME=DB_NAME_SECRET:latest

Terraform

הפקודה הבאה יוצרת משאבים סודיים כדי לאחסן בצורה מאובטחת את הערכים של שם המשתמש, הסיסמה והשם של מסד הנתונים באמצעות google_secret_manager_secret ו-google_secret_manager_secret_version. שימו לב: צריך לעדכן את חשבון השירות של פרויקט Compute כדי שתהיה לו גישה לכל סוד.


# Create dbuser secret
resource "google_secret_manager_secret" "dbuser" {
  secret_id = "dbusersecret"
  replication {
    auto {}
  }
  depends_on = [google_project_service.secretmanager_api]
}

# Attaches secret data for dbuser secret
resource "google_secret_manager_secret_version" "dbuser_data" {
  secret      = google_secret_manager_secret.dbuser.id
  secret_data = "secret-data" # Stores secret as a plain txt in state
}

# Update service account for dbuser secret
resource "google_secret_manager_secret_iam_member" "secretaccess_compute_dbuser" {
  secret_id = google_secret_manager_secret.dbuser.id
  role      = "roles/secretmanager.secretAccessor"
  member    = "serviceAccount:${data.google_project.project.number}-compute@developer.gserviceaccount.com" # Project's compute service account
}


# Create dbpass secret
resource "google_secret_manager_secret" "dbpass" {
  secret_id = "dbpasssecret"
  replication {
    auto {}
  }
  depends_on = [google_project_service.secretmanager_api]
}

# Attaches secret data for dbpass secret
resource "google_secret_manager_secret_version" "dbpass_data" {
  secret      = google_secret_manager_secret.dbpass.id
  secret_data = "secret-data" # Stores secret as a plain txt in state
}

# Update service account for dbpass secret
resource "google_secret_manager_secret_iam_member" "secretaccess_compute_dbpass" {
  secret_id = google_secret_manager_secret.dbpass.id
  role      = "roles/secretmanager.secretAccessor"
  member    = "serviceAccount:${data.google_project.project.number}-compute@developer.gserviceaccount.com" # Project's compute service account
}


# Create dbname secret
resource "google_secret_manager_secret" "dbname" {
  secret_id = "dbnamesecret"
  replication {
    auto {}
  }
  depends_on = [google_project_service.secretmanager_api]
}

# Attaches secret data for dbname secret
resource "google_secret_manager_secret_version" "dbname_data" {
  secret      = google_secret_manager_secret.dbname.id
  secret_data = "secret-data" # Stores secret as a plain txt in state
}

# Update service account for dbname secret
resource "google_secret_manager_secret_iam_member" "secretaccess_compute_dbname" {
  secret_id = google_secret_manager_secret.dbname.id
  role      = "roles/secretmanager.secretAccessor"
  member    = "serviceAccount:${data.google_project.project.number}-compute@developer.gserviceaccount.com" # Project's compute service account
}

מעדכנים את המשאב הראשי של Cloud Run כך שיכלול את הסודות החדשים.

resource "google_cloud_run_v2_service" "default" {
  name     = "cloudrun-service"
  location = "us-central1"

  deletion_protection = false # set to "true" in production

  template {
    containers {
      image = "us-docker.pkg.dev/cloudrun/container/hello:latest" # Image to deploy

      # Sets a environment variable for instance connection name
      env {
        name  = "INSTANCE_CONNECTION_NAME"
        value = google_sql_database_instance.default.connection_name
      }
      # Sets a secret environment variable for database user secret
      env {
        name = "DB_USER"
        value_source {
          secret_key_ref {
            secret  = google_secret_manager_secret.dbuser.secret_id # secret name
            version = "latest"                                      # secret version number or 'latest'
          }
        }
      }
      # Sets a secret environment variable for database password secret
      env {
        name = "DB_PASS"
        value_source {
          secret_key_ref {
            secret  = google_secret_manager_secret.dbpass.secret_id # secret name
            version = "latest"                                      # secret version number or 'latest'
          }
        }
      }
      # Sets a secret environment variable for database name secret
      env {
        name = "DB_NAME"
        value_source {
          secret_key_ref {
            secret  = google_secret_manager_secret.dbname.secret_id # secret name
            version = "latest"                                      # secret version number or 'latest'
          }
        }
      }

      volume_mounts {
        name       = "cloudsql"
        mount_path = "/cloudsql"
      }
    }
    volumes {
      name = "cloudsql"
      cloud_sql_instance {
        instances = [google_sql_database_instance.default.connection_name]
      }
    }
  }
  client     = "terraform"
  depends_on = [google_project_service.secretmanager_api, google_project_service.cloudrun_api, google_project_service.sqladmin_api]
}

מזינים terraform apply כדי להחיל את השינויים.

בפקודה לדוגמה נעשה שימוש בגרסת הסוד latest, אבל Google ממליצה להצמיד את הסוד לגרסה ספציפית, SECRET_NAME:v1.

כתובת IP פרטית

בנתיבי IP פרטיים, האפליקציה מתחברת ישירות למופע דרך רשת VPC. בשיטה הזו נעשה שימוש ב-TCP כדי להתחבר ישירות למכונה של Cloud SQL בלי להשתמש ב-Cloud SQL Auth Proxy.

חיבור באמצעות TCP

מתחברים באמצעות כתובת ה-IP הפרטית של מכונת Cloud SQL בתור המארח והיציאה 3306.

Python

כדי לראות את קטע הקוד הזה בהקשר של אפליקציית אינטרנט, אפשר לעיין ב-README ב-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

Java

כדי לראות את קטע הקוד הזה בהקשר של אפליקציית אינטרנט, עיינו ב-README ב-GitHub.

הערה:


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

Node.js

כדי לראות את קטע הקוד הזה בהקשר של אפליקציית אינטרנט, אפשר לעיין בקובץ ה-README ב-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);
};

המשך

כדי לראות את קטע הקוד הזה בהקשר של אפליקציית אינטרנט, אפשר לעיין ב-README ב-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
}

C#‎

כדי לראות את קטע הקוד הזה בהקשר של אפליקציית אינטרנט, אפשר לעיין בקובץ ה-README ב-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;

        }
    }
}

Ruby

כדי לראות את קטע הקוד הזה בהקשר של אפליקציית אינטרנט, אפשר לעיין ב-README ב-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 }%>

PHP

כדי לראות את קטע הקוד הזה בהקשר של אפליקציית אינטרנט, אפשר לעיין בקובץ ה-README ב-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;
    }
}

שיטות מומלצות ומידע נוסף

אתם יכולים להשתמש ב-Cloud SQL Auth Proxy כשאתם בודקים את האפליקציה באופן מקומי. הוראות מפורטות מופיעות במאמר התחלה מהירה: שימוש ב-Cloud SQL Auth Proxy.

אפשר גם לבדוק באמצעות שרת proxy ל-Cloud SQL דרך קונטיינר של Docker.

מאגרי חיבורים

יכול להיות שהחיבורים למסדי נתונים בסיסיים ינותקו, על ידי שרת מסד הנתונים עצמו או על ידי תשתית הפלטפורמה. מומלץ להשתמש בספריית לקוח שתומכת במאגרי חיבורים, שמבצעת חיבור מחדש אוטומטי לחיבורי לקוח שנפסקו. אתם יכולים להשתמש בניהול מאגר חיבורים עם המכונות שלכם ב-Cloud SQL, כדי לשנות את גודל עומסי העבודה על ידי אופטימיזציה של ניצול המשאבים ושל זמן האחזור של החיבורים למכונות שלכם ב-Cloud SQL באמצעות מאגר חיבורים. סקירה כללית על מאגר מנוהל של חיבורים

דוגמאות מפורטות יותר לשימוש במאגרי חיבורים מופיעות בדף ניהול החיבורים למסד הנתונים.

מגבלות על חיבורים

גם במהדורת MySQL וגם במהדורת PostgreSQL של Cloud SQL יש מגבלה על מספר החיבורים בו-זמנית, והמגבלות האלה עשויות להשתנות בהתאם למנוע של מסד הנתונים שנבחר (ראו את הדף מכסות ומגבלות ב-Cloud SQL).

מכונות קונטיינר של Cloud Run מוגבלות ל-100 חיבורים למסד נתונים של Cloud SQL. לכל מכונה של שירות או משימה ב-Cloud Run יכולים להיות 100 חיבורים למסד הנתונים, וככל שהשירות או המשימה גדלים, המספר הכולל של החיבורים לכל פריסה יכול לגדול.

אתם יכולים להגביל את מספר החיבורים המקסימלי לכל מכונה באמצעות מאגר חיבורים. דוגמאות מפורטות יותר להגבלת מספר החיבורים מופיעות בדף ניהול החיבורים למסד הנתונים.

מגבלות מכסה ל-API

ב-Cloud Run יש מנגנון שמתחבר באמצעות Cloud SQL Auth Proxy, שמשתמש ב-Cloud SQL Admin API. מגבלות מכסת ה-API חלות על Cloud SQL Auth Proxy. המיכסה של Cloud SQL Admin API שנעשה בה שימוש היא בערך פי שניים ממספר המכונות של Cloud SQL שהוגדרו, כפול מספר המכונות של Cloud Run של שירות מסוים שנפרס בכל זמן נתון. אתם יכולים להגביל או להגדיל את מספר המופעים של Cloud Run כדי לשנות את מכסת ה-API הצפויה לשימוש.

המאמרים הבאים