はじめに
Google またはサードパーティが所有するネットワークとプライベート接続ができる、プライベート サービス アクセスがある
オンプレミスと接続した共有 VPC 構成と、プライベート サービス アクセスを実施したので、設定内容を記載する
また、試しに CloudSQL をプライベートに作成してアクセスするテストも実施したのでその内容も記載する
(情報は、2021.10.31 記載時点)
プライベート サービス アクセス
下記、ドキュメントから抜粋
- Google とサードパーティ(サービス プロデューサー)は、VPC ネットワークでホストされている内部 IP アドレスでサービスを提供できる
- プライベート サービス アクセスを使用すると、これらの内部 IP アドレスにアクセスできる
サービス プロデューサー ネットワーク
- プライベート接続のサービス プロデューサー 側には VPC ネットワークがある
- それぞれのコンシューマー専用に作成され、そこにはコンシューマーのリソースのみが含まれる
プライベート サービス アクセスとオンプレミス接続
- デフォルトではオンプレミスホストはサービス プロデューサー側へ到達できない
- オンプレミスホストから接続するにはカスタムルートのエクスポートをする必要がある
サポート対象のサービス
現状、対応しているサービスは下記のサービス
- Cloud SQL
- Memorystore for Redis
- Memorystore for Memcached
- AI Platform Training
- Cloud Build
構築
実際にプライベートサービスアクセスを構築して試した内容を記載する
構成
今回、下記構成で実施した
- Host Project
- コンシューマー VPC プロジェクト
- Host Project / Service Project の構成で、SharedVPC で構築している
- オンプレミス (Home Lab) とは VPN 接続経由で接続している
- us-west1 に主なリソースを立てている
- カスタムルート(経路)広報としてサービスプロデューサー側にアサインしたアドレスを追加広報する
- 全体の構築例の記事はこちらのリンクを参照
- Google Project (Service producer project for customer)
- プロデューサー VPC
- Google のサービスネットワークとなる
- us-west1 と us-west2 の 2リージョンで試す
- オンプレミスとも通信できるようにカスタムルート(経路)も経路交換する
- アイコンとしては現在対応しているサービスをマップしているが、今回は CloudSQL (MySQL) を構築してアクセス確認のみ実施する
実施環境で利用した変数は下記の通り
- 共有VPC 名: sharedvpc
- 追加サブネット1: 172.20.0.0/24
- 追加サブネット2: 172.20.10.0/24
- ホスト プロジェクト: suzuyu-sharedhost-dev
- サービス プロジェクト: suzuyu-service-dev
以降で、構築を進める
作成方法は、gcloud コマンドと、terraform の 2つの方法で記載する
サブネットアサイン
まず、利用するサブネットをアサインする
ここでアサインするサブネットはリージョン固定できず Google 利用時に自動でアサインとなる
/24が最小単位となり、/16が推奨だが、ここでは最小限(/24) を 2つ用意して、リージョン単位で利用する
(必要に応じて追加する運用を想定)
gcloud
gcloud compute addresses create google-managed-services-us-west1-subnet1 \
--global \
--purpose=VPC_PEERING \
--addresses=172.20.0.0 \
--prefix-length=24 \
--description="peering range for Google us-west1" \
--network=sharedvpc \
--project=suzuyu-sharedhost-dev
gcloud compute addresses create google-managed-services-us-west2-subnet1 \
--global \
--purpose=VPC_PEERING \
--addresses=172.20.10.0 \
--prefix-length=24 \
--description="peering range for Google us-west2" \
--network=sharedvpc \
--project=suzuyu-sharedhost-dev
下記で反映を確認する
gcloud compute addresses list --global --filter="purpose=VPC_PEERING" --project suzuyu-sharedhost-dev
% gcloud compute addresses list --global --filter="purpose=VPC_PEERING" --project suzuyu-sharedhost-dev
NAME ADDRESS/RANGE TYPE PURPOSE NETWORK REGION SUBNET STATUS
google-managed-services-us-west1-subnet1 172.20.0.0/24 INTERNAL VPC_PEERING sharedvpc RESERVED
google-managed-services-us-west2-subnet1 172.20.10.0/24 INTERNAL VPC_PEERING sharedvpc RESERVED
切り戻し
gcloud compute addresses delete google-managed-services-us-west1-subnet1 \
--project=suzuyu-sharedhost-dev \
--global
gcloud compute addresses delete google-managed-services-us-west2-subnet1 \
--project=suzuyu-sharedhost-dev \
--global
Terraform
resource "google_compute_global_address" "google-managed-services-us-west1-subnet1" {
name = "google-managed-services-us-west1-subnet1"
purpose = "VPC_PEERING"
address_type = "INTERNAL"
address = "172.20.0.0"
prefix_length = 24
project = google_project.host_project.name
network = google_compute_network.host_sharedvpc.id
}
resource "google_compute_global_address" "google-managed-services-us-west2-subnet1" {
name = "google-managed-services-us-west2-subnet1"
purpose = "VPC_PEERING"
address_type = "INTERNAL"
address = "172.20.10.0"
prefix_length = 24
project = google_project.host_project.name
network = google_compute_network.host_sharedvpc.id
}
Terraform はコード削除でリソース削除になるので切り戻し手順不要
プライベート接続
API サービスの有効化 (共有 VPC のホストプロジェクトとリソースを構築するサービスプロジェクト両方)
gcloud
gcloud services enable --project=suzuyu-sharedhost-dev servicenetworking.googleapis.com
gcloud services enable --project=suzuyu-service-dev servicenetworking.googleapis.com
terraform
resource "google_project_service" "host_servicenetworking" {
project = google_project.host_project.id
disable_dependent_services = true
service = "servicenetworking.googleapis.com"
}
resource "google_project_service" "service_servicenetworking" {
project = google_project.service_project.id
disable_dependent_services = true
service = "servicenetworking.googleapis.com"
}
サービスプロデューサ側とのピアリングを実施し、サブネットを追加する
gcloud
gcloud services vpc-peerings connect \
--service=servicenetworking.googleapis.com \
--ranges=google-managed-services-us-west1-subnet1 \
--network=sharedvpc \
--project=suzuyu-sharedhost-dev
サブネットを追加する場合は下記のようにアップデートで可能
gcloud services vpc-peerings update \
--service=servicenetworking.googleapis.com \
--ranges=google-managed-services-us-west1-subnet1,google-managed-services-us-west2-subnet1 \
--network=sharedvpc \
--project=suzuyu-sharedhost-dev
terraform
resource "google_service_networking_connection" "google_producer" {
network = google_compute_network.host_sharedvpc.id
service = "servicenetworking.googleapis.com"
reserved_peering_ranges = [
google_compute_global_address.google-managed-services-us-west1-subnet1.name,
google_compute_global_address.google-managed-services-us-west2-subnet1.name,
]
}
追加は、上記のreserved_peering_ranges
リストに追加すればよい
オンプレへの経路広報を update で追加する
gcloud
gcloud compute routers update ha-vpn-router1 \
--region=us-west1 \
--add-advertisement-ranges 172.20.0.0/24,172.20.10.0/24 \
--project=suzuyu-sharedhost-dev
terraform
既存設定へ追加する例 (追加前の全体コード例: 9. HA VPN の作成 (vpn.tf))
resource "google_compute_router" "ha_vpn_router1" {
name = "ha-vpn-router1"
network = google_compute_network.host_sharedvpc.name
project = google_project.host_project.name
region = var.gcp_common.region
bgp {
asn = var.vpn.asn
advertise_mode = "CUSTOM"
advertised_groups = ["ALL_SUBNETS"]
dynamic "advertised_ip_ranges" {
for_each = {
~中略~
+ privateservice1 = "${google_compute_global_address.google-managed-services-us-west1-subnet1.address}/${google_compute_global_address.google-managed-services-us-west1-subnet1.prefix_length}"
+ privateservice2 = "${google_compute_global_address.google-managed-services-us-west2-subnet1.address}/${google_compute_global_address.google-managed-services-us-west2-subnet1.prefix_length}"
}
content {
range = advertised_ip_ranges.value
}
}
}
}
オンプレ側での経路受信結果は下記の通り
ERX01:~$ show ip route
Codes: K - kernel, C - connected, S - static, R - RIP, B - BGP
O - OSPF, IA - OSPF inter area
N1 - OSPF NSSA external type 1, N2 - OSPF NSSA external type 2
E1 - OSPF external type 1, E2 - OSPF external type 2
> - selected route, * - FIB route, p - stale info
IP Route Table for VRF "default"
~中略~
B *> 172.20.0.0/24 [20/100] via 169.254.0.1, vti0, 00:00:35
B *> 172.20.10.0/24 [20/100] via 169.254.0.1, vti0, 00:00:35
下記で反映を確認する
gcloud services vpc-peerings list \
--network=VPC_NETWORK \
--project=PROJECT_ID
下記表示例
% gcloud services vpc-peerings list --network=sharedvpc --project=suzuyu-sharedhost-dev
---
network: projects/xxxxxxxxxx/global/networks/sharedvpc
peering: servicenetworking-googleapis-com
reservedPeeringRanges:
- google-managed-services-us-west1-subnet1
- google-managed-services-us-west2-subnet1
service: services/servicenetworking.googleapis.com
gcloud compute networks peerings update servicenetworking-googleapis-com \
--network=sharedvpc \
--project=suzuyu-sharedhost-dev \
--import-custom-routes \
--export-custom-routes
切り戻し
ピアリング削除する場合は下記コマンド
gcloud services vpc-peerings delete \
--service=servicenetworking.googleapis.com \
--network=sharedvpc \
--project=suzuyu-sharedhost-dev
Cloud Console での状態確認
構築した結果を Cloud Console でも確認したので下記に例として記載する
VPC ネットワーク > プライベート サービス接続
VPC ネットワーク ピアリング
servicenetworking-googleapis-com という名前でピアリングが作成されていることを確認できる
Cloud Router > アドバタイズされた IP 範囲
オンプレミス向けに今回作成したサブネットを広報(アドバタイズ)されていることを確認できる
接続試験
プライベートサービスアクセスを利用した CloudSQL での MySQL 接続を試すため、
インスタンスを作成してテストアクセスを実施する
構築は Cloud Console 上で GUI で実施した
テスト用 CloudSQL MySQL 作成
Cloud Console で SQL
を選択して、「インスタンスを作成」をクリック
MySQL を選択
パラメータを設定する
インスタンス ID
, パスワード
, リージョン
を設定する
インスタンスのカスタマイズにある構成オプションを表示
をクリックする
接続
を開いて、共有ネットワーク
を選択して ネットワーク
で共有 VPC を選択し、割り振られているIP範囲
で今回作成したサブネットを選択する
バックアップ
を開いて、ロケーションを選択しておく (しないとエラーとなったため)
最後にインスタンスの作成
をクリックして作成する
2台目も リージョン
と 割り振られているIP範囲
を変えて構築する
作成完了後にアサインされたアドレスを確認する
mysql 接続試験
下記、オンプレ VM, GCP Service Project 内 VM から実施 (結果はほぼ同じ)
※ IP での接続のため、IP レベルの Firewall Rules で許可がされていれば接続可能
% mysql --host=172.20.0.2 --user=root --password
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 463
Server version: 5.7.34-google-log (Google)
Copyright (c) 2000, 2021, Oracle and/or its affiliates.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql> SELECT Host, User, password_last_changed FROM mysql.user;
+-----------+---------------+-----------------------+
| Host | User | password_last_changed |
+-----------+---------------+-----------------------+
| % | root | 2021-10-31 12:12:16 |
| localhost | mysql.sys | 2021-10-31 12:10:56 |
| localhost | mysql.session | 2021-10-31 12:11:07 |
+-----------+---------------+-----------------------+
3 rows in set (0.13 sec)
mysql> exit
Bye
% mysql --host=172.20.10.2 --user=root --password
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 448
Server version: 5.7.34-google-log (Google)
Copyright (c) 2000, 2021, Oracle and/or its affiliates.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql> SELECT Host, User, password_last_changed FROM mysql.user;
+-----------+---------------+-----------------------+
| Host | User | password_last_changed |
+-----------+---------------+-----------------------+
| % | root | 2021-10-31 12:15:41 |
| localhost | mysql.sys | 2021-10-31 12:14:14 |
| localhost | mysql.session | 2021-10-31 12:14:24 |
+-----------+---------------+-----------------------+
3 rows in set (0.15 sec)
mysql> exit
Bye
以上で作成して疎通確認まで完了
リソース作成後のサブネット作成・ルート反映
サブネットの作成やピアリングしたプロデューサ VPC からルート広報がされるのは、インスタンスを初回作成される時なので、
テストで作成した後に反映されたピアリングからのサブネット状態を確認する
下記、ピアリングのルートとして、サブネットが追加されたことが確認できる
下記、ピアリング接続の情報に指定したリージョンでサブネットが /24 で作成され、インポートされたことが確認できる
まとめ
プライベートサービスアクセスの設定とオンプレミス接続環境での経路交換も実施した
CloudSQL を試験作成してプライベートにアクセスまで確認できた
一度作成して削除したサブネットが、サービスプロデューサ側のルートから消えない状態を確認したので、削除方法を確認など、運用についてはこれから調べていく予定
参照