Cloud Intelligence™Cloud Intelligence™

Cloud Intelligence™

GCPの重複ネットワーク間でサービスにプライベート接続

By Chimbu ChinnaduraiMay 16, 20235 min read

このページはEnglishDeutschEspañolFrançaisItalianoPortuguêsでもご覧いただけます。

Google Cloud Platform(GCP)では、Compute Engine APIを有効化すると、無効化しない限り新規プロジェクトごとにデフォルトのVPCネットワークが自動で作成されます。

この仕組みのおかげで、カスタムVPCやサブネットを用意しなくてもすぐにGCPを使い始められます。一方で、自動生成されるサブネットはすべて10.128.0.0/9のCIDRブロックに収まる事前定義済みのIPv4範囲を使うため、デフォルトネットワーク特有の問題が生じます。

ネットワーク範囲が重複してしまうと、プロジェクト間でのプライベートな内部通信は行えません。この制限はVPCピアリングとCloud VPNの両方に当てはまります。

本記事では、Private Service Connectを利用して、ネットワークが重複するVMやGKEクラスター上のサービスへプライベートにアクセスする方法を解説します。同一GCP組織内でも、異なるGCP組織間でも、重複するネットワークに対して同じ手法が使えます。

リファレンスアーキテクチャ

Private Service Connectの構成イメージ

Project Bはサービス提供側(プロデューサー)のプロジェクトで、マネージドインスタンスグループ上にサンプルのnginxサービスをデプロイしています。

Project Aはサービス利用側(コンシューマー)のプロジェクトで、Project Bのサービスにプライベート接続する必要があります。両プロジェクトのインスタンスには外部IPを割り当てていません。

  • リソースのリージョンはus-west4
  • Project AとProject Bでcompute.googleapis.com APIを有効化
  • 外部IPを持たないインスタンスからパッケージをダウンロードできるようCloud NATを設定

サンプルサービスとテスト用インスタンスのデプロイ

以下のコマンド内の変数は環境に合わせて書き換えてください。

  • Project Bでインスタンステンプレートを作成します。
gcloud compute instance-templates create nginx-service-instance-template \
--machine-type=e2-medium \
--network-interface=network=default,no-address \
--metadata=startup-script=\ \#\!\ /bin/bash$'\n'yum\ install\ epel-release$'\n'yum\ -y\ install\ nginx$'\n'systemctl\ start\ nginx \
--maintenance-policy=MIGRATE \
--provisioning-model=STANDARD \
--scopes=https://www.googleapis.com/auth/cloud-platform \
--create-disk=auto-delete=yes,boot=yes,device-name=nginx-service-instance-template,image=projects/centos-cloud/global/images/centos-7-v20230411,mode=rw,size=20,type=pd-balanced \
--no-shielded-secure-boot \
--shielded-vtpm \
--shielded-integrity-monitoring \
--reservation-affinity=any \
--project=$PROJECT_B

  • Project Bでマネージドインスタンスグループを作成します。
gcloud beta compute instance-groups managed create nginx-service-instance-group \
--base-instance-name=nginx-service \
--size=1 \
--template=nginx-service-instance-template \
--zone=us-west4-a \
--list-managed-instances-results=PAGELESS \
--no-force-update-on-repair \
--project=$PROJECT_B

作成が完了すると、マネージドインスタンスグループが指定ゾーンでインスタンスを起動します。

インスタンスにSSHでログインし、nginxサービスが正常に動作しているか確認します。

  • Project Aで接続テスト用のインスタンスを作成します。
gcloud compute instances create instance-1 \
    --zone=us-west4-b \
    --machine-type=e2-medium \
    --network-interface=stack-type=IPV4_ONLY,subnet=default,no-address \
    --maintenance-policy=MIGRATE \
    --provisioning-model=STANDARD \
    --scopes=https://www.googleapis.com/auth/cloud-platform \
    --create-disk=auto-delete=yes,boot=yes,device-name=instance-2,image=projects/centos-cloud/global/images/centos-7-v20230411,mode=rw,size=20,type=projects/project-a-385206/zones/us-west4-b/diskTypes/pd-balanced \
    --no-shielded-secure-boot \
    --shielded-vtpm \
    --shielded-integrity-monitoring \
    --labels=ec-src=vm_add-gcloud \
    --reservation-affinity=any \
    --project=$PROJECT_A

Project AとProject Bのネットワークは内部接続を持たないため、Project AのインスタンスからProject Bのサービスには到達できません。

また、デフォルトネットワークのIP範囲が重複しているため、VPCピアリングも利用できません。

内部ロードバランサーのセットアップ

Private Service Connectでサービスアタッチメントを介してサービスを公開するには、内部ロードバランサーが必要です。ここではProject Bに内部TCPロードバランサーを構築します。

  • VMのポート80に対するHTTP接続を確認するため、リージョナルHTTPヘルスチェックを新規作成します。
gcloud compute health-checks create http nginx-service-health-check \
    --region=us-west4 \
    --port=80 \
    --project=$PROJECT_B
  • HTTPトラフィック用のバックエンドサービスを作成します。
gcloud compute backend-services create nginx-service-internal-lb-backend \
    --load-balancing-scheme=internal \
    --protocol=tcp \
    --region=us-west4 \
    --health-checks=nginx-service-health-check \
    --health-checks-region=us-west4 \
    --project=$PROJECT_B
  • nginxサービスのインスタンスグループをバックエンドサービスに追加します。
gcloud compute backend-services add-backend nginx-service-internal-lb-backend \
    --region=us-west4 \
    --instance-group=nginx-service-instance-group \
    --instance-group-zone=us-west4-a \
    --project=$PROJECT_B
  • バックエンドサービスに紐付く転送ルールを作成します。
gcloud compute forwarding-rules create nginx-service-internal-fr \
    --region=us-west4 \
    --load-balancing-scheme=internal \
    --network=default \
    --subnet=default \
    --ip-protocol=TCP \
    --ports=80 \
    --backend-service=nginx-service-internal-lb-backend \
    --backend-service-region=us-west4 \
    --project=$PROJECT_B
  • ロードバランサーのヘルスチェックを許可するファイアウォールルールを設定します。
gcloud compute firewall-rules create allow-internal-lb-health-check \
--direction=INGRESS \
--priority=1000 \
--network=default \
--action=ALLOW \
--rules=tcp:80 \
--source-ranges=35.191.0.0/16,130.211.0.0/22
--project=$PROJECT_B

プロデューサープロジェクトでのサービス公開

サービス提供側であるProject Bでサービスを公開し、別のVPCネットワーク上のコンシューマーがプライベートかつセキュアに接続できるようにします。

  • Private Service Connect用のサブネットを予約します。デフォルトネットワークと範囲が重複しないように注意してください。
gcloud compute networks subnets create private-service-connect \
--network default \
--region us-west4 \
--range 10.0.1.0/24 \
--purpose=PRIVATE_SERVICE_CONNECT \
--project=$PROJECT_B
  • 明示的なプロジェクト承認方式で、nginxサービスをProject Aに公開します。
gcloud compute service-attachments create nginx-service \
    --region=us-west4 \
    --producer-forwarding-rule=nginx-service-internal-fr  \
    --connection-preference=ACCEPT_MANUAL \
    --nat-subnets=private-service-connect \
    --consumer-accept-list=$PROJECT_A=10 \
    --project=$PROJECT_B

公開サービスにアクセスできるコンシューマーは、自動承認または手動承認のいずれかで管理できます。詳しくはPrivate Service Connectを使ったサービス公開を参照してください。

  • Private Service Connectから対象インスタンスへのアクセスを許可するファイアウォールルールを設定します。
gcloud compute firewall-rules create allow-private-service-connect \
--direction=INGRESS \
--priority=1000 \
--network=default \
--action=ALLOW \
--rules=tcp:80 \
--source-ranges=10.0.1.0/24
--project=$PROJECT_B

コンシューマープロジェクトでのエンドポイント設定

コンシューマープロジェクト側のエンドポイントは、Private Service Connectの転送ルールを介してプロデューサーVPCネットワーク上のサービスへ接続します。

エンドポイントを作成すると、指定した名前空間(または既定のgoog-psc-default)を使って自動的にService Directoryに登録されます。

エンドポイントを複数リージョンから利用できるようにするには、グローバルアクセスを有効にします。グローバルアクセスは現在Preview段階です。

  • エンドポイントに割り当てる内部IPアドレスを予約します。
gcloud compute addresses create private-service-connect-endpoint \
    --region=us-west4 \
    --subnet=default \
    --project=$PROJECT_A
  • エンドポイントをProject Bのサービスアタッチメントに接続する転送ルールを作成します。
PSC_SERVICE_ATTACHMENT=$(gcloud compute service-attachments describe nginx-service \
   --region=us-west4 \
   --project=$PROJECT_B \
   --format="value(selfLink.scope(projects))")

gcloud compute forwarding-rules create nginx-service \
  --region=us-west4 \
  --network=default \
  --address=private-service-connect-endpoint \
  --target-service-attachment="projects/$PSC_SERVICE_ATTACHMENT" \
  --project=$PROJECT_A

コンシューマープロジェクトからの接続テスト

これでProject AとProject Bの両方でPrivate Service Connectのコンポーネントが整いました。Project AのエンドポイントIP宛にアクセスして、Project Bのnginxサービスへ接続できるか試してみましょう。

このテストにより、ネットワーク範囲が重複するインスタンス同士でも、Private Service Connectのエンドポイント経由でプライベートに通信できることが確認できます。

本記事では、Private Service Connectを使って、ネットワークが重複する環境でもサービスを安全に公開・利用する方法を紹介しました。

トラフィックはGoogle Cloud内で完結し、コンシューマーとプロデューサーの間でサービス指向のアクセスを確保しながら、アクセス制御もきめ細かく行えます。

Private Service Connectの詳細は、製品ページをご覧ください。