Google Cloudとのハイブリッドクラウド構成で固定IP宛の通信をリージョン冗長・負荷分散させる方法

この記事は BBSakura Networks Advent Calendar 2025 の 5 日目の記事です。

こんにちは。BBSakura Networks CTO の日下部(@higebu)です。

今回は、オンプレミスから Google Cloud に接続する際、「固定のIPアドレス宛にパケットを送りたい、かつリージョン冗長と負荷分散も実現したい」 という要件に対し、検証と調査の末にたどり着いた構成について紹介します。

トンネル終端など、「何らかの事情で宛先IPアドレスが固定されている」というシチュエーションが世の中にはあります。

こういったケースで、Google Cloud の仕様上の制約を回避しつつ、どうすれば堅牢な構成を作ることができるのか、失敗談(検討過程)も含めて共有します。

前提となる環境と要件

今回想定する環境は以下のとおりです。

  • オンプレミス: 東西 2 拠点
  • Google Cloud: asia-northeast1 (東京) / asia-northeast2 (大阪)
  • 通信の要件:
    • オンプレミスから Google Cloud 上のサーバーへ通信する。
    • オンプレミス方面からのパケットの宛先は「単一のIPアドレス (VIP)」に固定されている。
    • 例:トンネル通信や、宛先IPがハードコードされた機器からの通信など。
  • 可用性・拡張性の要件:
    • 通常時は東京・大阪の両リージョンでトラフィックを分散させたい。
    • リージョン障害時には、IPアドレス設定を変更することなく、自動的にもう一方のリージョンでサービスを継続したい。

内部パススルーネットワークロードバランサを使った構成

最初に検討した構成:内部パススルーネットワークロードバランサをネクストホップにする

Google Cloud でプライベートIPへの高スループットな通信を受ける場合、まず思い浮かぶのが 内部パススルーネットワークロードバランサ (Internal Passthrough Network Load Balancer / L4 ILB) です。

当初、私は以下のような構成を考えました。

  1. 東京と大阪の各リージョンに L4 ILB を作成する。
  2. カスタム静的ルートを作成し、オンプレから見える「宛先VIP」へのネクストホップとして、各リージョンの L4 ILB を指定する。
  3. 同じ宛先IP範囲に対し、優先度を同じにして ECMP (Equal-Cost Multi-Path) で分散させる。

非常にシンプルで、Google Cloud の定石のように見えます。

この構成が使えなかった理由

しかし、検証とドキュメント確認を進めると、この構成には 「リージョン冗長・負荷分散ができない」 という致命的な制約があることがわかりました。

Google Cloud のドキュメント「内部パススルー ネットワーク ロードバランサをネクストホップとして使用する」には、以下の仕様が明記されています。

すべてのバックエンドが異常な場合 内部パススルー ネットワーク ロードバランサのすべてのバックエンドでヘルスチェックに失敗した場合でも、そのロードバランサのネクストホップを使用したルートは引き続き有効です。

つまり、あるリージョンのバックエンドが全滅しても静的ルートは消えません。 そのリージョンに向かったパケットはブラックホール行き(破棄)となり、自動的に別リージョンへフェイルオーバーされないのです。これではリージョン冗長の要件を満たせません。

同じ宛先と優先度の複数のルートがあり、ネクストホップの内部パススルー ネットワーク ロードバランサが異なる場合 Google Cloud は ECMP を使用して 2 つ以上のネクストホップ内部パススルー ネットワーク ロードバランサ間でトラフィックを分散することはありません。代わりに、Google Cloud は決定論的な内部アルゴリズムを使用して、ネクストホップ内部パススルー ネットワーク ロードバランサを 1 つだけ選択します。

こちらは負荷分散に関する制約です。東京の ILB と大阪の ILB を並べても、ECMP でパケットが分散されることはなく、どちらか一方に偏ってしまいます。 これを回避するにはルートごとに一意のネットワークタグが必要になりますが、今回の要件(不特定多数の拠点からの透過的なアクセス)では現実的ではありません。

もう少し詳しく言うと、2つの静的ルートはどちらも有効に見えるのですが、実際にはどちらか1つだけ有効な状態になっており、東西どちらのオンプレからのパケットも、どれか1つのリージョンにしかルーティングされないことになります。

これらの制約により、「L4 ILB をネクストホップにした静的ルート」案は不採用となりました。

結論:NCC と Router Appliance による BGP Anycast 構成

そこでたどり着いたのが、Network Connectivity Center (NCC) を活用し、GCE インスタンスを Router Appliance として扱う構成です。

NCCを使ってBGP Anycastする構成

構成の概要

  1. GCE インスタンスをルーターとして構成: 各リージョン(東京・大阪)の GCE インスタンス内で BGP デーモン(FRRoutingGoBGP など)を動作させます。
  2. NCC スポークとして登録: これらのインスタンスを NCC の「Router Appliance スポーク」として登録し、Cloud Router と BGP セッションを確立します。
  3. BGP Anycast : 東京・大阪のすべてのインスタンスから、オンプレミスが宛先とする「固定IP (VIP)」/32 の経路として Cloud Router に広報します。

なぜこれで解決するのか?

この構成には以下のメリットがあり、先ほどの課題をすべて解決できます。

  • リージョン障害への耐性: BGP を使用しているため、インスタンスやリージョンに障害が発生して BGP セッションが切れると、自動的にその経路(VIPへのパス)は Cloud Router から削除されます。 これにより、静的ルートの時のように「死んだ経路にパケットが吸い込まれる」ことがなくなり、生きているリージョンへトラフィックが流れます。

  • ECMP による負荷分散: Cloud Router は、複数のネクストホップ(この場合は各 GCE インスタンス)から同じプレフィックスを受け取ると、ECMP によってトラフィックを分散します。 これにより、リージョン内のインスタンスへの負荷分散が可能になります。

  • スケールアウトが容易: 処理能力が不足した場合は、同じ設定を入れた GCE インスタンスを追加し、同じ VIP を広報させるだけで、自動的に負荷分散の対象に追加されます。

設定例(GoBGP)

例として、GoBGP での設定を載せておきます。

[global.config]
  as = 65001
  router-id = "10.146.0.10"

[[neighbors]]
  [neighbors.config]
    neighbor-address = "10.146.0.100"
    peer-as = 16550
  [[neighbors.afi-safis]]
    [neighbors.afi-safis.config]
      afi-safi-name = "ipv4-unicast"

[[neighbors]]
  [neighbors.config]
    neighbor-address = "10.146.0.101"
    peer-as = 16550
  [[neighbors.afi-safis]]
    [neighbors.afi-safis.config]
      afi-safi-name = "ipv4-unicast"

経路広報については systemd を使っている場合、サーバで動かしたいサービスの unit ファイルで、下記のように ExecStartPost / ExecStop で add / del すると良いと思います。サービスの起動・停止と合わせて、経路広報を開始・停止できます。

ExecStartPost=/usr/local/bin/gobgp global rib add -a ipv4 192.0.2.1/32
ExecStop=/usr/local/bin/gobgp global rib del -a ipv4 192.0.2.1/32

オンプレミスとの接続には OCX を利用

さて、この構成を組むためには、オンプレミスと Google Cloud を高品質かつ低遅延につなぐ必要があります。ここで活躍するのが、BBSakura Networks が開発し、BBIXが提供している OCX です。

ここまでの図に特に断りなく登場していましたが、OCX の Cloud Connection 機能を使えば、オンプレミスの拠点から Google Cloud の Interconnect (Partner Interconnect) までを、オンデマンドで簡単に接続できます。

今回の構成では、東西のオンプレ拠点から OCX 経由で Google Cloud に入り、そこから BGP Anycast で最適な(または生きている)リージョンのサーバーに着弾するという、非常に堅牢なネットワークを構築することが可能です。

まとめ

「固定IPアドレス宛に通信したい」という要件に対し、Google Cloud でリージョン冗長と負荷分散を両立させるには、以下の点がポイントでした。

  • L4 ILB ネクストホップの静的ルートは使わない: バックエンド全断時の経路残留と、リージョン冗長不可の制約があるため。
  • NCC + Router Appliance (BGP Anycast) を採用する: BGP の動的な経路制御により、障害時の自動切り離しとリージョン冗長が実現できる。

「クラウドならロードバランサでなんとかなる」と思わずに、公式ドキュメントの制約事項や考慮事項をよく読むことの大切さを改めて痛感しました。

同じような構成を検討されている方の参考になれば幸いです。