Configurer Private Service Connect pour un cluster de destination

Cette page explique comment configurer Database Migration Service pour migrer vos charges de travail Oracle vers AlloyDB pour PostgreSQL à l'aide de l'adresse IP privée du cluster AlloyDB pour PostgreSQL de destination. Les connexions privées permettent à Database Migration Service d'accéder aux services sans passer par Internet ni utiliser d'adresses IP externes.

Database Migration Service utilise Private Service Connect pour se connecter à votre cluster AlloyDB pour PostgreSQL à l'aide d'une adresse IP privée. Avec Private Service Connect, vous pouvez exposer votre base de données de destination aux connexions entrantes sécurisées et contrôler qui peut y accéder.

Private Service Connect pour les clusters AlloyDB pour PostgreSQL compatibles avec PSC

Si vous créez votre instance de destination AlloyDB pour PostgreSQL avec Private Service Connect activé, vous pouvez utiliser la connectivité par adresse IP privée sans aucune configuration réseau supplémentaire. Lorsque vous créez le profil de connexion de la base de données de destination, vous devez vous assurer de respecter les points suivants:

  • Utilisez l'enregistrement DNS de votre cluster AlloyDB pour PostgreSQL au lieu du nom d'hôte de la destination.

  • Pour un accès programmatique via la CLI Google Cloud ou l'API uniquement: spécifiez explicitement l'attachement de service de votre destination dans la requête (cela est effectué automatiquement par Database Migration Service lorsque vous créez des profils de connexion dans la console Google Cloud ).

Private Service Connect pour les clusters AlloyDB pour PostgreSQL non compatibles avec PSC

Pour exposer un service à l'aide de Private Service Connect pour les clusters AlloyDB pour PostgreSQL, créez un rattachement de service dans votre projet. Vous pouvez utiliser des exemples de scripts gcloud et Terraform dans la section Créer la configuration du producteur Private Service Connect pour créer les ressources requises.

Le diagramme suivant illustre les différentes ressources de calcul et de mise en réseau utilisées par Database Migration Service pour configurer une connectivité privée avec votre cluster AlloyDB pour PostgreSQL.

Configuration de Private Service Connect

Le worker Database Migration Service est une unité de traitement interne chargée de votre migration Database Migration Service. Il utilise une règle de transfert Private Service Connect sortante pour envoyer le trafic du nœud de calcul vers le réseau VPC dans lequel se trouve la machine virtuelle (VM) de bastion.

Voici les principales ressources que les scripts vous aident à créer:

  • Rattachement de service: ressource qui expose un service en transférant le trafic vers son service cible. Dans le schéma, le service cible est une règle de transfert entrante.
  • Règle de transfert entrante: transfert du trafic entrant de l'attachement de service vers une cible dédiée (par exemple, une VM ou un groupe d'instances). Dans le diagramme, la règle transfère le trafic vers une VM bastion.
  • VM bastion: VM dotée de deux contrôleurs d'interface réseau (NIC), dont l'un est associé au réseau Private Service Connect dédié et l'autre au réseau auquel le cluster AlloyDB pour PostgreSQL est associé. Le bastion exécute un serveur SOCKS Dante, qui permet de transférer les connexions de manière sécurisée. Les exemples de scripts créent pour vous un réseau et des sous-réseaux dédiés dans le réseau Private Service Connect.

Le projet Google Cloud que vous utilisez pour publier votre service à l'aide de l'attachement de service est le producteur de service. Le client du service est Database Migration Service. Pour en savoir plus sur Private Service Connect, sa configuration et son architecture, consultez la documentation Private Service Connect.

Créer la configuration du producteur Private Service Connect

Vous pouvez utiliser les scripts suivants pour créer la configuration Private Service Connect et vous connecter à votre cluster AlloyDB pour PostgreSQL de destination. Si vous rencontrez des problèmes lors de la configuration de la connectivité, consultez les pages de dépannage de la connectivité.

gcloud

Le script bash suivant utilise la Google Cloud CLI pour créer la configuration du producteur Private Service Connect pour la base de données de destination. Notez que certains paramètres par défaut peuvent nécessiter un ajustement, par exemple les plages CIDR du sous-réseau Private Service Connect.

#!bin/bash

# Create the VPC network for the Database Migration Service Private Service Connect.

gcloud compute networks create dms-psc-vpc \
--project=PROJECT_ID \
--subnet-mode=custom

# Create a subnet for the Database Migration Service Private Service Connect.

gcloud compute networks subnets create dms-psc-REGION \
--project=PROJECT_ID \
--range=10.0.0.0/16 --network=dms-psc-vpc \
--region=REGION

# Create a router required for the bastion to be able to install external

# packages (for example, Dante SOCKS server):

gcloud compute routers create ex-router-REGION \
--network dms-psc-vpc \
--project=PROJECT_ID \
--region=REGION

gcloud compute routers nats create ex-nat-REGION \
--router=ex-router-REGION \
--auto-allocate-nat-external-ips \
--nat-all-subnet-ip-ranges \
--enable-logging \
--project=PROJECT_ID \
--region=REGION

# Create the bastion VM.

gcloud compute instances create BASTION \
    --project=PROJECT_ID \
    --zone=ZONE \
    --image-family=debian-11 \
    --image-project=debian-cloud \
    --network-interface subnet=dms-psc-REGION,no-address \
    --network-interface subnet=DB_SUBNETWORK,no-address \
    --metadata=startup-script='#! /bin/bash

# Route the private IP address using the gateway of the database subnetwork.

# To find the gateway for the relevant subnetwork, go to the VPC network page

# in the Google Cloud console. Click VPC networks, and select the database VPC

# to see the details.

ip route add ALLOYDB_INSTANCE_PRIVATE_IP via DB_SUBNETWORK_GATEWAY

# Install Dante SOCKS server.

apt-get install -y dante-server

# Create the Dante configuration file.

touch /etc/danted.conf

# Create a proxy.log file.

touch proxy.log

# Add the following configuration for Dante:

cat > /etc/danted.conf << EOF
logoutput: /proxy.log
user.privileged: proxy
user.unprivileged: nobody

internal: 0.0.0.0 port = PORT
external: ens5

clientmethod: none
socksmethod: none

client pass {
        from: 0.0.0.0/0
        to: 0.0.0.0/0
        log: connect error disconnect
}
client block {
        from: 0.0.0.0/0
        to: 0.0.0.0/0
        log: connect error
}
socks pass {
        from: 0.0.0.0/0
        to: ALLOYDB_INSTANCE_PRIVATE_IP/32
        protocol: tcp
        log: connect error disconnect
}
socks block {
        from: 0.0.0.0/0
        to: 0.0.0.0/0
        log: connect error
}
EOF

# Start the Dante server.

systemctl restart danted

tail -f proxy.log'

# Create the target instance from the created bastion VM.

gcloud compute target-instances create bastion-ti-REGION \
--instance=BASTION \
--project=PROJECT_ID \
--instance-zone=ZONE \
--network=dms-psc-vpc

# Create a forwarding rule for the backend service.

gcloud compute forwarding-rules create dms-psc-forwarder-REGION \
--project=PROJECT_ID \
--region=REGION \
--load-balancing-scheme=internal \
--network=dms-psc-vpc \
--subnet=dms-psc-REGION \
--ip-protocol=TCP \
--ports=all \
--target-instance=bastion-ti-REGION \
--target-instance-zone=ZONE

# Create a TCP NAT subnet.

gcloud compute networks subnets create dms-psc-nat-REGION-tcp \
--network=dms-psc-vpc \
--project=PROJECT_ID \
--region=REGION \
--range=10.1.0.0/16 \
--purpose=private-service-connect

# Create a service attachment.

gcloud compute service-attachments create dms-psc-svc-att-REGION \
--project=PROJECT_ID \
--region=REGION \
--producer-forwarding-rule=dms-psc-forwarder-REGION \
--connection-preference=ACCEPT_MANUAL \
--nat-subnets=dms-psc-nat-REGION-tcp

# Create a firewall rule allowing the Private Service Connect NAT subnet.

# access the Private Service Connect subnet

gcloud compute \
--project=PROJECT_ID firewall-rules create dms-allow-psc-tcp \
--direction=INGRESS \
--priority=1000 \
--network=dms-psc-vpc \
--action=ALLOW \
--rules=all \
--source-ranges=10.1.0.0/16 \
--enable-logging

# Print out the created service attachment.

gcloud compute service-attachments describe dms-psc-svc-att-REGION \
--project=PROJECT_ID \
--region=REGION

Remplacez les éléments suivants :

  • PROJECT_ID: projet dans lequel vous créez la configuration du producteur Private Service Connect.
  • REGION: région dans laquelle vous créez la configuration du producteur Private Service Connect.
  • ZONE: zone de REGION dans laquelle vous créez toutes les ressources zonales (par exemple, la VM bastion).
  • BASTION: VM bastion à créer.
  • DB_SUBNETWORK: sous-réseau auquel le trafic sera transféré. Le sous-réseau doit avoir accès au cluster AlloyDB pour PostgreSQL.
  • DB_SUBNETWORK_GATEWAY: passerelle IPv4 du sous-réseau.
  • PORT: port que le bastion utilisera pour exposer la base de données sous-jacente.
  • ALLOYDB_INSTANCE_PRIVATE_IP: adresse IP privée du cluster AlloyDB pour PostgreSQL.

Terraform

Les fichiers suivants peuvent être utilisés dans un module Terraform pour créer la configuration du producteur Private Service Connect pour la base de données de destination. Vous devrez peut-être ajuster certaines valeurs par défaut, par exemple les plages CIDR du sous-réseau Private Service Connect.

variables.tf :

variable "project_id" {
  type        = string
  description = <<DESC
The Google Cloud project in which the setup is created. This should be the same project as
the one that the AlloyDB for PostgreSQL cluster belongs to.
DESC
}

variable "region" {
  type        = string
  description = "The Google Cloud region in which you create the Private Service Connect
regional resources."
}

variable "zone" {
  type        = string
  description = <<DESC
The Google Cloud zone in which you create the Private Service Connect zonal resources
(should be in the same region as the one specified in the "region" variable).
DESC
}

variable "primary_instance_private_ip" {
  type = string
  description = "The cluster's primary instance private IP"
}

variable "port" {
  type        = string
  description = "The port that the bastion will use to expose the underlying database."
  default     = "5432"
}

variable "alloydb_cluster_network" {
  type        = string
  description = <<DESC
The VPC to which the AlloyDB for PostgreSQL cluster is peered. This is where the bastion will
forward connections to (the destination database needs to be accessible in this VPC).
DESC
}

main.tf :

/* To execute the call:
terraform apply
-var="project_id=PROJECT_ID"
-var="region=REGION"
-var="zone=ZONE"
-var="primary_instance_private_ip=PRIMARY_INSTANCE_PRIVATE_IP"
-var="port=PORT"
-var="alloydb_cluster_network=ALLOYDB_CLUSTER_NETWORK" */

# Needed for getting the IPv4 gateway of the subnetwork for the database.

data "google_compute_subnetwork" "db_network_subnet" {
  name    = var.alloydb_cluster_network
  project = var.project_id
  region  = var.region
}

resource "google_compute_network" "psc_sp_network" {
  name                    = "dms-psc-network"
  project                 = var.project_id
  auto_create_subnetworks = false
}

resource "google_compute_subnetwork" "psc_sp_subnetwork" {
  name    = "dms-psc-subnet"
  region  = var.region
  project = var.project_id

  network = google_compute_network.psc_sp_network.id
  # CIDR range can be lower.

  ip_cidr_range = "10.0.0.0/16"
}

resource "google_compute_subnetwork" "psc_sp_nat" {
  provider = google-beta
  name     = "dms-psc-nat"
  region   = var.region
  project  = var.project_id

  network = google_compute_network.psc_sp_network.id
  purpose = "PRIVATE_SERVICE_CONNECT"
  # CIDR range can be lower.

  ip_cidr_range = "10.1.0.0/16"
}

resource "google_compute_service_attachment" "psc_sp_service_attachment" {
  provider = google-beta
  name     = "dms-psc-svc-att"
  region   = var.region
  project  = var.project_id

  enable_proxy_protocol = false
  connection_preference = "ACCEPT_MANUAL"
  nat_subnets           = [google_compute_subnetwork.psc_sp_nat.id]
  target_service        = google_compute_forwarding_rule.psc_sp_target_direct_rule.id
}

resource "google_compute_forwarding_rule" "psc_sp_target_direct_rule" {
  name       = "dms-psc-fr"
  region     = var.region
  project    = var.project_id
  network    = google_compute_network.psc_sp_network.id
  subnetwork = google_compute_subnetwork.psc_sp_subnetwork.id

  load_balancing_scheme = "INTERNAL"
  ip_protocol           = "TCP"
  all_ports             = true

  target = google_compute_target_instance.psc_sp_target.id

}

resource "google_compute_target_instance" "psc_sp_target" {
  provider = google-beta
  name     = "dms-psc-fr-target"
  zone     = var.zone
  instance = google_compute_instance.psc_sp_bastion.id
  network  = google_compute_network.psc_sp_network.id
}

resource "google_compute_instance" "psc_sp_bastion" {
  name           = "dms-psc-cloud-sql-bastion"
  project        = var.project_id
  machine_type   = "e2-medium"
  zone           = var.zone
  can_ip_forward = true

  boot_disk {
    initialize_params {
      image = "debian-cloud/debian-11"
    }
  }

  # The incoming NIC defines the default gateway which must be the Private Service Connect subnet.

  network_interface {
    network    = google_compute_network.psc_sp_network.id
    subnetwork = google_compute_subnetwork.psc_sp_subnetwork.id
  }

  # The outgoing NIC which is on the same network as the AlloyDB for PostgreSQL cluster.

  network_interface {
    network = data.google_compute_subnetwork.db_network_subnet.network
  }

  metadata_startup_script = <<SCRIPT

#!/bin/bash

# Route the private IP address of the database using the gateway of the database subnetwork.

# To find the gateway for the relevant subnetwork, go to the VPC network page 

# in the Google Cloud console. Click VPC networks, and select the database VPC

# to see the details.

ip route add ${var.primary_instance_private_ip} \
via ${data.google_compute_subnetwork.db_network_subnet.gateway_address}

# Install Dante SOCKS server.

apt-get install -y dante-server

# Create the Dante configuration file.

touch /etc/danted.conf

# Create a proxy.log file.

touch proxy.log

# Add the following configuration for Dante:

cat > /etc/danted.conf << EOF
logoutput: /proxy.log
user.privileged: proxy
user.unprivileged: nobody

internal: 0.0.0.0 port = ${var.port}
external: ens5

clientmethod: none
socksmethod: none

client pass {
        from: 0.0.0.0/0
        to: 0.0.0.0/0
        log: connect error disconnect
}
client block {
        from: 0.0.0.0/0
        to: 0.0.0.0/0
        log: connect error
}
socks pass {
        from: 0.0.0.0/0
        to: ${var.primary_instance_private_ip}/32
        protocol: tcp
        log: connect error disconnect
}
socks block {
        from: 0.0.0.0/0
        to: 0.0.0.0/0
        log: connect error
}
EOF

# Start the Dante server.

systemctl restart danted

tail -f proxy.log

SCRIPT
}

# Required firewall rules:

/* Firewall rule allowing the Private Service Connect NAT subnet to access
the Private Service Connect subnet. */
resource "google_compute_firewall" "psc_sp_in_fw" {
  name    = "dms-psc-ingress-nat-fw"
  project = var.project_id
  network = google_compute_network.psc_sp_network.id

  log_config {
    metadata = "INCLUDE_ALL_METADATA"
  }

  allow {
    protocol = "all"
  }

  priority  = 1000
  direction = "INGRESS"
  source_ranges = [google_compute_subnetwork.psc_sp_nat.ip_cidr_range]
}

/* The router that the bastion VM uses to install external packages
(for example, Dante SOCKS server). */

resource "google_compute_router" "psc_sp_ex_router" {
  name    = "dms-psc-external-router"
  project = var.project_id
  region  = var.region
  network = google_compute_network.psc_sp_network.id
}

resource "google_compute_router_nat" "psc_sp_ex_router_nat" {
  name    = "dms-psc-external-router-nat"
  project = var.project_id
  region  = var.region
  router  = google_compute_router.psc_sp_ex_router.name

  nat_ip_allocate_option             = "AUTO_ONLY"
  source_subnetwork_ip_ranges_to_nat = "ALL_SUBNETWORKS_ALL_IP_RANGES"

  log_config {
    enable = true
    filter = "ERRORS_ONLY"
  }
}

outputs.tf :

# The Private Service Connect service attachment.

output "service_attachment" {
  value = google_compute_service_attachment.psc_sp_service_attachment.id
}