Configurar o Private Service Connect para um cluster de destino

Esta página descreve como configurar o Database Migration Service para migrar suas cargas de trabalho do Oracle para o AlloyDB para PostgreSQL usando o endereço IP particular do cluster de destino do AlloyDB para PostgreSQL. As conexões particulares permitem que o Database Migration Service acesse serviços sem passar pela Internet ou usar endereços IP externo.

O Database Migration Service usa o Private Service Connect para se conectar ao cluster do AlloyDB para PostgreSQL usando um endereço IP particular. Com o Private Service Connect, você pode expor seu banco de dados de destino a conexões seguras de entrada e controlar quem pode acessar o banco de dados.

Private Service Connect para clusters do AlloyDB para PostgreSQL com PSC ativado

Se você criar a instância de destino do AlloyDB para PostgreSQL com o Private Service Connect ativado, poderá usar a conectividade de IP particular sem nenhuma configuração de rede extra. Ao criar o perfil de conexão do banco de dados de destino, você só precisa garantir o seguinte:

  • Use o registro de DNS do cluster do AlloyDB para PostgreSQL em vez do nome do host do destino.

  • Somente para acesso programático pela Google Cloud CLI ou pela API: especifique explicitamente o anexo de serviço do destino na solicitação. Isso é feito automaticamente pelo Database Migration Service quando você cria perfis de conexão no console do Google Cloud .

Private Service Connect para clusters do AlloyDB para PostgreSQL que não têm o PSC ativado

Para expor um serviço usando o Private Service Connect para clusters do AlloyDB para PostgreSQL, crie um anexo de serviço no seu projeto. Use os exemplos de gcloud e scripts do Terraform na seção Criar a configuração do produtor do Private Service Connect para criar os recursos necessários.

O diagrama a seguir mostra os vários recursos de computação e rede que o Database Migration Service usa para configurar a conectividade particular ao cluster do AlloyDB para PostgreSQL.

Configuração do Private Service Connect

O worker do Database Migration Service é uma unidade de processamento interna responsável pela migração do Database Migration Service. Ele usa uma regra de encaminhamento de saída do Private Service Connect para enviar o tráfego do worker para a rede VPC em que a máquina virtual (VM) de bastião está.

Os principais recursos que os scripts ajudam a criar são:

  • Um anexo de serviço: um recurso que expõe um serviço ao encaminhar o tráfego para o serviço de destino. No diagrama, o serviço de destino é uma regra de encaminhamento de entrada.
  • Uma regra de encaminhamento de entrada: um encaminhador de tráfego que encaminha o tráfego de entrada do anexo de serviço para um destino dedicado (por exemplo, uma VM ou um grupo de instâncias). No diagrama, a regra encaminha o tráfego para uma VM de bastião.
  • Uma VM de bastião: uma VM com dois controladores de interface de rede (NICs), sendo que um deles está anexado à rede dedicada do Private Service Connect e o outro à rede em que o cluster do AlloyDB para PostgreSQL está conectado. O bastião está executando um servidor SOCKS Dante, que é usado para encaminhar as conexões com segurança. Os scripts de exemplo criam uma rede dedicada e sub-redes na rede do Private Service Connect para você.

O projeto Google Cloud que você usa para publicar seu serviço com o anexo de serviço é o produtor de serviços. O consumidor de serviço é o Database Migration Service. Para mais informações sobre o Private Service Connect, a configuração e a arquitetura, consulte a documentação do Private Service Connect.

Criar a configuração do produtor do Private Service Connect

Use os scripts abaixo para criar a configuração do Private Service Connect e se conectar ao cluster de destino do AlloyDB para PostgreSQL. Se você tiver problemas durante a configuração de conectividade, consulte as páginas de solução de problemas de conectividade.

gcloud

O script bash a seguir usa a Google Cloud CLI para criar a configuração do produtor do Private Service Connect para o banco de dados de destino. Talvez seja necessário ajustar alguns padrões, por exemplo, os intervalos de CDIR da sub-rede do 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

Substitua:

  • PROJECT_ID: o projeto em que você cria a configuração do produtor do Private Service Connect.
  • REGION: a região em que você cria a configuração do produtor do Private Service Connect.
  • ZONE: uma zona em REGION em que você cria todos os recursos de zona (por exemplo, a VM de bastião).
  • BASTION: a VM de bastião a ser criada.
  • DB_SUBNETWORK: a sub-rede para a qual o tráfego será encaminhado. A sub-rede precisa ter acesso ao cluster do AlloyDB para PostgreSQL.
  • DB_SUBNETWORK_GATEWAY: o gateway IPv4 da sub-rede.
  • PORT: a porta que o bastião vai usar para expor o banco de dados subjacente.
  • ALLOYDB_INSTANCE_PRIVATE_IP: o endereço IP particular do cluster do AlloyDB para PostgreSQL.

Terraform

Os arquivos a seguir podem ser usados em um módulo do Terraform para criar a configuração do produtor do Private Service Connect para o banco de dados de destino. Talvez seja necessário ajustar alguns padrões, por exemplo, os intervalos de CDIR da sub-rede do 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
}