このページでは、宛先の AlloyDB for PostgreSQL クラスタのプライベート IP アドレスを使用して Oracle から AlloyDB for PostgreSQL ワークロードに移行するように Database Migration Service を設定する方法について説明します。プライベート接続を使用すると、Database Migration Service はインターネットを経由せず、外部 IP アドレスを使用せずにサービスにアクセスできます。
Database Migration Service は、Private Service Connect を使用して、プライベート IP アドレスを使用して AlloyDB for PostgreSQL クラスタに接続します。Private Service Connect を使用すると、転送先データベースを受信側の安全な接続に公開し、データベースにアクセスできるユーザーを制御できます。
PSC 対応の AlloyDB for PostgreSQL クラスタ用の Private Service Connect
Private Service Connect を有効にして AlloyDB for PostgreSQL の移行先インスタンスを作成すると、追加のネットワーク設定なしでプライベート IP 接続を使用できます。宛先データベース接続プロファイルを作成するときに、次の点を確認する必要があります。
宛先のホスト名ではなく、AlloyDB for PostgreSQL クラスタの DNS レコードを使用します。
Google Cloud CLI または API を介したプログラムによるアクセスの場合のみ: リクエストで宛先のサービス アタッチメントを明示的に指定します(これは、 Google Cloud コンソールで接続プロファイルを作成するときに、Database Migration Service によって自動的に実行されます)。
PSC が有効でない AlloyDB for PostgreSQL クラスタの Private Service Connect
AlloyDB for PostgreSQL クラスタに Private Service Connect を使用してサービスを公開するには、プロジェクトにサービス アタッチメントを作成します。Private Service Connect プロデューサーの設定を作成するセクションの gcloud
の例と Terraform スクリプトを使用して、必要なリソースを作成できます。
次の図は、Database Migration Service が AlloyDB for PostgreSQL クラスタへのプライベート接続の設定に使用するさまざまなコンピューティング リソースとネットワーキング リソースを示しています。
Database Migration Service ワーカーは、Database Migration Service の移行を担当する内部処理ユニットです。アウトバウンド Private Service Connect 転送ルールを使用して、ワーカーから踏み台仮想マシン(VM)が存在する VPC ネットワークにトラフィックを送信します。
スクリプトによって作成される主なリソースは次のとおりです。
- サービス アタッチメント: トラフィックをターゲット サービスに転送してサービスを公開するリソース。この図では、ターゲット サービスは受信転送ルールです。
- 受信転送ルール: サービス アタッチメントから受信トラフィックを専用のターゲット(VM やインスタンス グループなど)に転送するトラフィック転送元。この図では、ルールはトラフィックを踏み台 VM に転送します。
- 踏み台 VM: 2 つのネットワーク インターフェース コントローラ(NIC)を備えた VM。1 つは専用の Private Service Connect ネットワークに接続され、もう 1 つは AlloyDB for PostgreSQL クラスタがピアリングされているネットワークに接続されます。踏み台は Dante SOCKS サーバーを実行しています。これは、接続を安全に転送するために使用されます。サンプル スクリプトでは、Private Service Connect ネットワークに専用のネットワークとサブネットが作成されます。
サービス アタッチメントを使用してサービスを公開するために使用する Google Cloud プロジェクトがサービス プロデューサーです。サービス コンシューマは Database Migration Service です。Private Service Connect、その設定、アーキテクチャの詳細については、Private Service Connect のドキュメントをご覧ください。
Private Service Connect プロデューサーの設定を作成する
次のスクリプトを使用して Private Service Connect の設定を作成し、宛先の AlloyDB for PostgreSQL クラスタに接続できます。接続の設定中に問題が発生した場合は、接続のトラブルシューティング ページをご覧ください。
gcloud
次の Bash スクリプトは、Google Cloud CLI を使用して、宛先データベースの Private Service Connect プロデューサー設定を作成します。Private Service Connect サブネットの CIDR 範囲など、一部のデフォルトは調整が必要になる場合があります。
#!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
次のように置き換えます。
- PROJECT_ID: Private Service Connect プロデューサー設定を作成するプロジェクト。
- REGION: Private Service Connect プロデューサー設定を作成するリージョン。
- ZONE: すべてのゾーンリソース(踏み台 VM など)を作成する REGION 内のゾーン。
- BASTION: 作成する踏み台 VM。
- DB_SUBNETWORK: トラフィックを転送するサブネットワーク。サブネットワークは AlloyDB for PostgreSQL クラスタにアクセスできる必要があります。
- DB_SUBNETWORK_GATEWAY: サブネットワークの IPv4 ゲートウェイ。
- PORT: 踏み台が基盤となるデータベースを公開するために使用するポート。
- ALLOYDB_INSTANCE_PRIVATE_IP: AlloyDB for PostgreSQL クラスタのプライベート IP アドレス。
Terraform
次のファイルを Terraform モジュールで使用して、宛先データベースの Private Service Connect プロデューサー設定を作成できます。Private Service Connect サブネットの CIDR 範囲など、一部のデフォルトは調整が必要になる場合があります。
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
}