【実務・中級編】 Shared VPC(共有VPC)のホストプロジェクトとサービスプロジェクトの設計 – クラウドインフラと仮想化ネットワーク実践ガイド

共有VPC(Shared VPC)の「正解」を掴む:大規模組織におけるネットワーク境界の設計論

クラウドエンジニアの皆さん、こんにちは。現場で「VPCを分けるべきか、それともプロジェクトを分けるべきか」という問いに頭を抱えたことはありませんか?

プロジェクトが増えれば増えるほど、各チームにバラバラのネットワークを作らせるのは悪夢の始まりです。管理が分散し、ファイアウォールルールはスパゲッティ化し、しまいには「どこから誰がアクセスしているのか分からない」というセキュリティのブラックボックスが生まれます。

そんな泥沼を避けるための銀の弾丸こそが、Google Cloudの 「共有VPC(Shared VPC)」 です。今回は、単なる用語解説ではなく、トラブルシューティングで汗をかいたエンジニアの実感とともに、この設計の要諦を紐解いていきます。

—

1. 共有VPCのアーキテクチャ:境界線を見極める

共有VPCの設計思想は極めてシンプルです。「ネットワークの管理権限(ホスト)」と「リソースの利用権限(サービス)」を明確に分離することです。

  • ホストプロジェクト: ネットワークの「司令塔」。VPC、サブネット、ルート、ファイアウォールルールを一元管理します。
  • サービスプロジェクト: リソースの「居住区」。Compute Engine、GKE、Cloud SQLなどが配置されます。

この分離により、ネットワークエンジニアは「ガードレール」を敷き、開発者はその中で自由にアプリケーションをデプロイするという、理想的な責務分担が可能になります。

—

2. なぜ「共有VPC」を使うのか?:実務の現場から

なぜ単一プロジェクトに押し込めず、わざわざ共有VPCという手間をかけるのか。理由は明確です。

1. IPアドレスの枯渇と枯渇防止: サブネットを一括管理することで、CIDRブロックを効率よく払い出し、CIDR重複の悲劇を防げます。
2. ファイアウォールの一元管理: 各プロジェクトで「お行儀の悪い」ルールが作られるのを防ぎます。
3. セキュリティ境界の確立: ネットワークの変更権限をネットワークチームに集中させ、開発チームはアプリケーションのデプロイに集中させることで、ガバナンスと生産性を両立できます。

—

3. 実践:共有VPCの設定フロー

共有VPCを構築する際、最も重要なのは「権限委譲」のプロセスです。これを忘れると、サービスプロジェクトからホスト側のサブネットが見えず、一日中デバッグすることになります。

手順1: ホストプロジェクトの有効化(gcloud)

まずはホストプロジェクトを定義します。

# ホストプロジェクトとして有効化する
gcloud compute shared-vpc enable [HOST_PROJECT_ID]

手順2: サービスプロジェクトをアタッチする

次に、サービスプロジェクトをホストに「招待」します。

# サービスプロジェクトをホストプロジェクトに関連付ける
gcloud compute shared-vpc associated-projects add [SERVICE_PROJECT_ID] \
    --host-project [HOST_PROJECT_ID]

手順3: 権限(IAM)の付与:ここが肝!

ここが最もハマりやすいポイントです。サービスプロジェクトのGKEノードやVMがサブネットを使うには、プロジェクトのIAMロールではなく、「サブネット単位」で権限を付与する必要があります。

# サービスプロジェクトのGKEサービスアカウントにサブネット利用権限を付与
gcloud compute networks subnets add-iam-policy-binding [SUBNET_NAME] \
    --project [HOST_PROJECT_ID] \
    --region [REGION] \
    --member "serviceAccount:[PROJECT_NUMBER]@container-engine-robot.iam.gserviceaccount.com" \
    --role "roles/compute.networkUser"

—

4. Web API通信のデバッグ:パケットはどこを流れるか

共有VPC環境下で、サービスA(サービスプロジェクト1)からサービスB(サービスプロジェクト2)へのAPI呼び出しを行う際、何が起きているのでしょうか。

PythonによるAPIリクエスト例

import requests

# 共有VPC内の別サービスへの内部通信
# ホストプロジェクトで定義されたプライベートIP(例: 10.0.1.5)に対してリクエスト
url = "http://10.0.1.5:8080/v1/resource"

try:
    response = requests.get(url, timeout=5)
    # レスポンスの確認
    print(f"Status Code: {response.status_code}")
except requests.exceptions.ConnectionError:
    # 接続失敗時はファイアウォールの設定を確認すること!
    print("接続不可:ホストプロジェクトのFirewallルールを見直してください")

シニアSREからのアドバイス:
もし接続エラー(ConnectionError)が発生したら、まず疑うべきは「サービスプロジェクトのプロジェクトIDではなく、ホストプロジェクトのファイアウォール設定」です。ホストプロジェクトで tag や serviceAccount を用いた ingress ルールが正しく設定されているかを確認してください。

—

5. 運用上のTips:トラブルシューティングの作法

現場で共有VPCを運用する際、以下の3点は「お守り」として持っておいてください。

  • VPC Service Controlsとの併用: 共有VPCは強力ですが、データ持ち出しを防ぐには VPC Service Controls を重ね掛けするのが今の時代のスタンダードです。
  • ファイアウォールの階層管理: ホストプロジェクトのファイアウォールルールには、「誰が、どのポートを、どのサービスに対して許可したか」を説明する description を必ず記述する文化を作りましょう。
  • ログの可視化: 通信の断絶を追うには、VPC Flow Logs を対象サブネットで有効化しておくのが鉄則です。Cloud Loggingで「どのIP間での通信がDROPされたか」が即座に分かります。

まとめ:ネットワークは「見えないインフラ」ではない

共有VPCは、単なるネットワークの共有機能ではありません。それは組織の権限構造をネットワークレイヤーに投影したものです。

最初は少し複雑に感じるかもしれませんが、大規模なプロダクトになればなるほど、この「分離」の恩恵を痛感するはずです。まずは小さなプロジェクトから、サブネットの管理権限を切り出すところから始めてみてください。

「ネットワーク設定を触るのが怖い」というフェーズを脱却し、「意図した通りにパケットを制御できている」という確信を持てるエンジニアが増えることを願っています。

何か詰まったら、まずは gcloud compute networks subnets get-iam-policy で権限を再確認すること。それがトラブル解決の最短ルートです。

コメント

タイトルとURLをコピーしました