GCP の細かすぎて伝わらないハイブリッドネットワーキング

Seiji Ariga
google-cloud-jp
Published in
31 min readDec 23, 2019

--

この記事は Google Cloud Japan Customer Engineer Advent Calendar 2019 の 17番目の記事です。(本当は「17日目の記事です」って書きたかったんですが…)

ベルギーの St. Ghislain にあるグーグルのデータセンターの冷却塔からの蒸気

こんにちは、Google Cloud Platform (GCP) でネットワークプロダクトを担当しているカスタマーエンジニア有賀です。この記事ではクラウドとオンプレミス環境の間や、クラウドとクラウド間のハイブリッドネットワークを構成する時に便利な GCP のサービスをご紹介したいと思います。

TL;DR (というか目次)

GCP にはオンプレミス環境とクラウドのハイブリッド環境や、他のクラウドとのマルチクラウド環境を、簡単・効率的に作れる色んなサービス・機能があるので、以下のようなサービス・機能をさくっと(?)ご紹介します。

それでは早速それぞれのサービス・機能を紹介していきましょう。

ちなみに以下、リンクされているドキュメントが日本語だったり英語だったりするのは、日本語のドキュメントが少し古かったりといった背景によるものです。🙇🏻‍♂️

Cloud VPN

一般にクラウドに接続するには、インターネット越しに接続、IPsec VPN 経由で接続、専用線で接続、といった方法がありますが、IPsec VPN による接続を実現するのがこの Cloud VPN です。

Google Cloud のブログ記事より引用

なぜここでわざわざ Cloud VPN を取り上げるかというと、実は Cloud VPN は IPsec VPN のクライアントにもなれるんですがあまり知られていないので、ぜひご紹介したいと思ったためです。

一般にクラウドの提供する VPN サービスはオンプレミス環境からのIPsec による接続を受けて VPC (Virtual Private Cloud)へつなぐ役割を担ってます。この場合、Cloud VPN はオンプレミス環境にあるルータからの接続を受けるだけの役割となります。

オンプレミス環境と VPC を IPsec VPN で接続

一方、GCP の Cloud VPN はクライアントにもなれる、つまり外向きに接続に行くこともできるので、Cloud VPN を使って VPC 同士を接続したり、別のクラウドと接続するのにも使うことができるのです。( VPC ピアリング があるのになんで VPC 同士をわざわざ VPN でつなぐ必要があるの?という疑問には、このセクションの最後でお答えします)

他のクラウドへVPN接続
GCP 内で VPC 同士を接続

IPsec VPN の設定に慣れている方なら設定自体は比較的簡単です。ただ、そこそこ手順が煩雑なのは確かなので、Terraform のようなツールを使ってみてもよいでしょう。↓ のページでは Terraform を使って GCP と AWS の間の VPN を構築する方法をご紹介しています。

ちなみに Cloud VPN には Classic VPN と HA VPN の二種類があって、↑ のページでは Classic VPN でつなぐ方法を紹介してます。一方、公式サイトではないですがこちらのページでは Terraform を使って GCP と AWS を HA VPN でつなぐ方法が解説されていますので、ご紹介します。

また、↓ のページでは管理コンソールgcloud コマンドラインツールを使って VPC 同士を VPN でつなぐ方法をご紹介しています。

なお VPC を VPN でつなぐ方法はスクリーンショットがあった方が分かりやすいと思いましたので、別の記事にスクリーンショットを列挙しておきました。

さて「VPC ピアリング があるのになんで VPC 同士をわざわざ VPN でつなぐ必要があるの?」という疑問にお答えします。

それは「VPN でつないでおくと、VPC 間で transitive な通信ができるようになるから」です。(言い方を変えると、VPC をスター型(ハブ & スポーク型)のネットワークトポロジで構成できるようになるから、です)

↑ のような構成の時、VPC1 と VPC2〜4 を VPC ピアリングで接続してしまうと、 VPC ピアリングによくある「推移的ピアリング (Transitive peering)はサポートされていない」という制限により VPC2〜4 はお互いに通信できません。( VPC2〜4 同士も VPC ピアリングでつなげばできますが、設定が煩雑ですよね)

一方、図のように VPC 同士を VPN で接続しておけば、そのような制限に縛られることはなくなり、クラウド内においてとり得るネットワークアーキテクチャの幅が広がります。(なお、Cloud VPN でつないだ後、(この例だとvpc1から)それぞれの VPC へ適切に経路広告をする設定は必要です)

なお、GCP では基本的にはあまり多くの VPC は作成せずShared VPC を活用することで少数の中央集権的な VPCでシステムを構成する方法をお勧めしています。なので「VPC がたくさんできちゃったから VPN でつなご!」という場合、なんでたくさんできちゃったかを考えてみましょう。

VPC ルーティングモード

VPN がつながったので、次は VPC のルーティングモードについてお話します。

VPC のルーティングモードの設定自体は至極簡単で、以下の様に VPC の設定で “Regional” か “Global” かを選ぶだけです。

動的ルーティングモードの設定

皆さまご存知のように GCP の VPC はグローバルに使える(設定できる)ため、この設定が重要になってきます。たとえば以下のような構成を考えます。(ここでは BGP による動的ルーティングを使ってるものとします)

VPC が一つあってその中で、東京と大阪のリージョンに Google Kubernetes Engine (GKE)のクラスタがあり、オンプレミス環境とは東京でのみ VPN でつながってるとします。

上にリンクした「別の記事」をご覧になった方は VPN gateway を作る時リージョンを選んだ = VPN gateway がリージョナルなリソースであることに気づかれたかもしれません。

この時、VPN のルーティングモードが “Regional” になってると Cloud VPN を通って大阪のクラスタへはアクセスできません。そのためルーティングモードを “Global” へ変更するか、以下のように大阪リージョンにも Cloud VPN を作成して接続する必要があります。

オンプレミス環境から東京と大阪の Cloud VPN へ VPN 接続

ちなみにこの構成でルーティングモードが “Regional” だと、たとえば東京リージョンの VPN が落ちた時、(遠回りになりますが)大阪を経由して東京リージョンの GKE に接続する、といったことができずにもったいないので、このような構成の時は “Global” にしておくことをおすすめします。

なお、動的ルーティングモードの注意書き「グローバル動的ルーティングによって予期しない問題が生じる可能性があります」とあるように、内部ロードバランサー (Internal Load Balancing — ILB) を使ってる場合は気をつける必要がありましたが、最近 ILB にもグローバルにアクセスできるようになった (Beta) ので、今後はあまり気にしなくてよくなっていくかもしれません。

VPC ピアリング カスタム経路 import export

さてだんだん長くなってきましたが、まだ3つ目のトピックです。

VPC ピアリングカスタム経路 import export」はタイトル「細かすぎて伝わらない」に違わず、中々地味ですが非常に重要な機能です。

まず設定自体は各 VPC ピアリング内の設定でチェックボックスにチェックを入れるだけです。

VPC ピアリングの設定変更画面

この機能はたとえば以下のような構成の時に役に立ちます。

↑ の構成の時、デフォルトでは VPC3 の GCE (Google Compute Engine) はオンプレミス環境にアクセスできません。これは Cloud VPN の項でも出てきた「推移的ピアリング (Transitive peering)はサポートされていない」という制限(の類型)によるものです。

VPC3 から見ると VPC2 を経由して 2 ホップしてオンプレミス環境に接続することになるため、”transitive” 相当の通信になります。

この制限は具体的には以下のような形で現れます。

  • VPC3 にオンプレミス環境への経路が無い
    (= VPC2 の Cloud VPN / VPC ピアリングがオンプレミス環境の経路を VPC3 へ広告しない)
  • オンプレミス環境に VPC3 への経路が無い
    (= VPC2 の Cloud VPN が VPC3 の経路をオンプレミス環境へ広告しない)

正確には「Cloud VPN が」じゃなくて「Cloud Router が」ですが簡単のため Cloud VPN のままとします。

逆に言うとそこが解決されれば VPC3 とオンプレミス環境で通信できそうです。そこで本題の「カスタム経路 import export」です。

カスタムルート (custom routes)とは VPC のサブネット自体の経路以外の、ユーザーが静的に設定した経路や、Cloud VPN・Cloud Interconnect 等で使う BGP により動的に広告された経路を指します。

例中の VPC2 にあるカスタムルート(= オンプレミス環境の経路)を VPC3 へ広告できれば、まずは VPC3 にオンプレミス環境への経路が無い問題は解決できそうです。

そのためには、VPC2 側で “Export” を、VPC3 側で “Import” をそれぞれ有効にすればオッケーです。

左が VPC2、右が VPC3

しかし、これだけだと問題の半分しか解決していません。もう一方のオンプレミス環境に VPC3 への経路がない問題は実は Cloud Router の設定で解決する必要があります。

Cloud Router にはカスタム経路広告という機能があり、これを使うと(BGPの)通信相手に任意の経路を広告することができます。そこで、VPC3 の経路を広告するよう設定することで、無事 VPC3 とオンプレミス環境は相互に通信できるようになるのです。

Cloud Router のカスタム経路広告の設定画面

ちなみに「そもそもこんな構成にしないから気にしなくていいや!」と思うなかれ。実は GCP ではユーザーが普段意識してないところでこのような構成になっている例があるのです。

たとえばプライベート IP 接続時の Cloud SQL や、GKE のプライベートクラスタ(限定公開クラスタ)におけるクラスタマスターがこのような構成でつながっています。

Cloud SQL のプライベート IP 接続利用時の構成

そのため、オンプレミス環境から Cloud SQL や、限定公開の GKE のマスターに直接アクセスしたい場合は VPC ピアリング カスタム経路 import export (と Cloud Router のカスタム経路広告)が必須になるのです。

ぜひ覚えておいていただけると嬉しいです。

Private Google Access for オンプレミスホスト

さて、スクロールバーを見るとだいたい半分くらいでしょうか。

次は、オンプレミス環境から Cloud SQL や GKE のクラスタマスターに直接接続できるようになったので、どうせなら BigQuery とか Spanner とかの API サービスにもオンプレミス環境から直接アクセスしたいですよね?分かります。

そんな時に役に立つのが「Private Google Access for オンプレミスホスト」という機能です。この機能を使うと Google の提供するほぼすべての API (エンドポイントの名前が .googleapis.com で終わる API)に Cloud VPN や Cloud Interconnect による閉域接続経由で直接アクセスできるようになります。

オンプレミス環境から API サービスへ直接接続

設定自体は簡単で…と言いたいところですが、実際には多少面倒です。そこで設定方法は別の記事にまとめました

Cloud VPN や Cloud Interconnect で GCP とオンプレミス環境を接続しても、そのままでは VPC 内のリソースにしかアクセスできず片手落ちです。

「Private Google Access for オンプレミスホスト」を設定することで GCP の提供する豊富な API サービスにも、オンプレミス環境から直接アクセスできるようになり、より効率的なハイブリッドクラウド環境を実現いただくことが可能となります。

なお、「for オンプレミスホスト」と銘打ってはいますが、もちろん他のクラウドと接続した際に、そのクラウドから GCP の API に直接アクセスするためにお使いいただくこともできます。

DNS 転送 (Outbound/Inbound)

さてお次は DNS 転送です。

Cloud DNS の紹介

さて、Cloud VPN や Cloud Interconnect で GCP とオンプレミス環境をつないだら早速 GCP からオンプレミス環境へアクセスしたり、逆にオンプレミス環境から GCP へアクセスしたりすると思います。

その際、アクセス先はどのように指定するでしょうか? IP アドレス?ホスト名?やはり普通はホスト名でしょうか。

そこで内部的なホスト名を設定するのに使うのが Cloud DNS (のプライベートゾーン)になります。Cloud DNS を使うと VPC 内の IP アドレス(GCEインスタンス等)に内部的なホスト名を付与することができます。

プライベートゾーンの例

DNS 転送 — Inbound

そうして、作ったプライベートゾーンへオンプレミス環境からクエリを送るために使われるのが DNS 転送 (Inbound) になります。(GCP の視点だと DNS のクエリが「入ってくる」ので「Inbound」ですね)

と言っても機能自体は単純で、オンプレミス環境からクエリを送る先となる (VPC内の) IP アドレスが生成されるだけです。

DNS 転送 (Inbound) を有効にすると IP アドレスが割り当てられる

設定も簡単で、名前を付けて、どの VPC で使うかを選ぶだけです。

“Inbound query forwarding” の設定

ポリシーができたら割り当てられた IP アドレスを確認して、その IP アドレスへクエリを送るようオンプレミス環境の DNS サーバーを設定すれば完了です。

DNS 転送 (Inbound) 用に割り当てられた IP アドレス

たとえばDNSキャッシュサーバー(リゾルバサーバー)として unbound を使ってる場合は、以下のような設定をすることで example.com ゾーンへのクエリを、上で設定した Cloud DNS へ送ることができます。

$ cat /etc/unbound/unbound.conf.d/example-com-forward-zone.conf
forward-zone:
name: "example.com."
forward-addr: 192.168.0.4
forward-addr: 192.168.1.4
$ dig @127.0.0.1 www.internal.example.com +short
192.168.0.2

なお余談ですが、unbound は(バージョンやどうインストールしたかによるものの)デフォルトで DNSSEC の検証をおこない、かつ例にあげた example.com は DNSSEC で署名されてるので、そのままだとエラー(SERVFAIL)になります。

$ dig example.com ds +short
31589 8 1 3490A6806D47F17A34C29E2CE80E8A999FFBE4BE
31589 8 2 CDE0D742D6998AA554A92D890F8184C698CFAC8A26FA59875A990C03 E576343C
43547 8 1 B6225AB2CC613E0DCA7962BDC2342EA4F1B56083
43547 8 2 615A64233543F66F44D68933625B17497C89A70E858ED76A2145997E DF96A918
31406 8 1 189968811E6EBA862DD6C209F75623D8D9ED9142
31406 8 2 F78CF3344F72137235098ECBBD08947C2C9001C7F6A085A17F518B5D 8F6B916D
$ dig @127.0.0.1 www.internal.example.com

; <<>> DiG 9.10.3-P4-Debian <<>> @127.0.0.1 www.internal.example.com
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: SERVFAIL, id: 21589
;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;www.internal.example.com. IN A

;; Query time: 0 msec
;; SERVER: 127.0.0.1#53(127.0.0.1)
;; WHEN: Fri Dec 20 03:53:13 UTC 2019
;; MSG SIZE rcvd: 53

そのため、自分の環境では unbound による DNSSEC の検証を無効にしてから試す必要がありました。

$ cat /etc/debian_version
9.11
$ sudo mv /etc/unbound/unbound.conf.d/root-auto-trust-anchor-file.conf{,-}$ sudo systemctl restart unbound

DNS 転送 — Outbound

さて、オンプレミス環境から(Cloud DNS による) GCP 内の名前解決ができるようになったので、次は当然逆に GCP 環境からオンプレミス環境の名前解決をしたくなると思います。

そのための機能も当然用意されていて、予想がつくと思いますが DNS 転送 (Outbound) という機能になります。

DNS 転送 (Outbound)

そして以下両方とも Cloud DNS 内の設定なのでちょっとややこしいんですが、DNS 転送(Outbound)を使いたい場合、用途によって2つの設定の仕方があります。

前者の「代替ネームサーバー」を使うと VPC 内のすべての名前解決がそこで設定されたサーバーへ送られることになりますので、クラウド内の名前もすべてオンプレミス環境で管理したい、といった場合はこちらの設定を使うことになります。

DNS サーバーポリシー内の代替ネームサーバーの設定

なお「すべての名前解決」が対象になるので、結果として GCE の内部名や、Cloud DNS のプライベート(限定公開)ゾーンも使われなくなります。

しかし上記の通り「代替ネームサーバー」を使う方法は少々柔軟性に欠けるので、通常は後者の「DNS 転送ゾーン」を使う方法が適当かと思います。

「DNS 転送ゾーン」では、設定されたゾーン(ドメインと読み替えてもほぼ間違いないです)への DNS クエリだけが転送先(オンプレミス環境とか)へと送られることになります。

DNS 転送ゾーンの設定

ちなみにご覧の通り、「代替ネームサーバー」の方は DNS サーバーポリシーによる実装であり、「DNS 転送ゾーン」の方はそのまま DNS ゾーンによる実装になってて、実現方法も根本的に違ったりします。

DNS 転送ゾーンをご利用いただくにあたっては、いくつか細かい要件がありますのでお気をつけください。

  • (当たり前ですが)転送先 DNS サーバーへの到達性があること (たとえば上の例では転送元 VPC のインスタンスから dig @10.0.0.2 www.onprem.example.jp などと実行して応答があることを確認してください)
  • (ここが直感的じゃないのですが)転送先 DNS サーバーへのクエリのソースアドレスは転送元 VPC のアドレスではなく、35.199.192.0/19の範囲の IP アドレスになります。そのため 35.199.192.0/19 がソースアドレスのパケットが転送先 DNS サーバへ届くようオンプレミス環境環境のファイアウォール及び転送先 DNS サーバーの ACL 等を確認してください
  • オンプレミス環境から35.199.192.0/19への返りの通信がインターネット経由ではなく、Cloud VPN や Cloud Interconnect 経由になるよう設定してください。( Cloud Router を使ってる場合は上にも出てきたカスタム経路広告35.199.192.0/19を広告するのが簡単です) インターネット経由では到達できません。
  • GCP 内の VPC 同士を VPN でつないでも DNS 転送 (Outbound)は使えません。そのため、テストをする時はオンプレミス環境として GCP 以外の環境をご用意ください。

また、以下のような構成で “vpc2” からの DNS 転送も動作しません。(ネットワーク的に “vpc2” からオンプレミス環境へ接続性があってもダメです) このような場合は次に説明する DNS ピアリング(“vpc2” → “vpc1”)を使います。

うまく動作しない場合は公式ドキュメントに詳細なトラブシューティングガイドがありますのでご参照ください。

DNS ピアリング

こちらは 2019年12月現在、Beta でのご提供となります。→ 2020年1月7に Generally Available となりました。

DNS 関連の最後の機能として DNS ピアリングをご紹介します。(名前は似ていますが、VPC ピアリングと直接の関係ありません)

“vpc1” から “vpc4” への DNS ピアリング

DNS ピアリングを使うと別の VPC に設定されている名前を解決できるようになります。

DNS ピアリングの設定

↑ の例では、”Networks” で選択されている VPC (たとえば “vpc1”)から、”vpc4" 内の “example.com” ゾーンに設定されてる名前を解決できるようになります。

なお、”vpc1" から “vpc4” 内のゾーンの名前解決はできますが、逆方向(“vpc4” から “vpc1”)の名前解決はできません。DNS ピアリングはあくまで片方向の関係です。(逆方向が必要であれば、もう一つ DNS ピアリングの設定をしてください)

また、この時 “vpc1” と “vpc4” は(VPN や VPC ピアリングなどで)接続してる必要はありません。が、それだと名前解決できても通信できません。:-)

実は同じプロジェクト内なら一つのプライベートゾーンを複数の VPC で共有できるので DNS ピアリングを使わなくてもいいですが、異なるプロジェクト間で名前解決したい場合は DNS ピアリングが必要になります。

DNS ピアリングと DNS 転送 (Outbound) の組み合わせ

ここまで説明した内容はよくある DNS ピアリングの使い方ですが、一方 DNS 転送 (Outbound) との組み合わせで DNS ピアリングが必要になる場面があります。

上にも書きましたが DNS 転送 (Outbound) はクエリのソース IP アドレスとして35.199.192.0/19を使います。

複数の VPC から同じ宛先に DNS 転送

すると複数の VPC から同じ宛先に同じソース IP アドレス(35.199.192.0/19)で通信することになるため、オンプレミス環境からどっちの VPC へ返せばいいか分からなくなるため正常に動作しません

そこで DNS ピアリングと DNS 転送を組み合わせて、次のような構成に変更することで動作するようになります。

DNS 転送と DNS ピアリングの組み合わせ

DNS 転送の設定は “vpc1” だけにおこない、”vpc2" は “vpc1” に対して DNS ピアリングの設定します。こうすることでexample.jpへのクエリは “vpc1” からのみになり、”vpc2" は “vpc1” 経由で名前解決する感じになります。

DNS Best practices

公式ドキュメントに DNS Best practices というドキュメントがあり、DNS を運用する上での(必ずしも GCP の Cloud DNS を使うことに限っていない)ベストプラクティスをご紹介しておりますので、ぜひご参照いただければと思います。

また、クラウドとオンプレミス環境のハイブリッドな環境で DNS を設定する際の参考となるアーキテクチャも、クラウド内のネットワークの構成に合わせて複数例示されています。こちらもあわせて参考にしていただけるかと思います。

サブネット共有

最後に、GCPのサービスではないんですが、おまけとしてクラウドとオンプレミス環境の間、もしくはクラウドとクラウド間でサブネットを簡単に共有する方法をご紹介します。

マイグレーションの途中で、クラウドとオンプレミス環境の間や、クラウドとクラウドの間で、一時的に同一の IP アドレスを使いいつつ、お互い通信できる状態を保ちたい場合があると思います。(たとえば、サブネット内のホストを 1 台だけ移行しつつ、OS・アプリケーション的には変更しないで済むように、とか)

VMware を使っている場合はたとえば 「NSX-T Data Center の複数サイトの展開」などで実現できますが、もう少しお手軽に試してみたいと思い、ちょっと実験をしてみました。

  1. GCP とオンプレミス環境(VMware の環境)の間
  2. GCP と AWS の間

この 2 つで試してみました。

基本的な方針は GCP、オンプレミス環境、AWS のいずれでも同じで、まずは環境間をつなぐ「ゲートウェイ」となるインスタンスを両環境に作り IPIP トンネルでつなぎます。

余談ですが GCP では GRE が通りません。 (2021–04–05 EDIT: 最近は GRE もサポートされています。)

そして、(共有の対象となる)対向側の環境にあるホスト宛てのパケットをなんとかゲートウェイインスタンスで吸い込み、IPIP トンネルで対向側へ送ります。

対向のゲートウェイまで着いちゃえば、普通に宛先のインスタンスへパケットを送り届けられます。返りも同じ要領でパケットを戻します。

なんとなくできそうですね。

では、具体的な方法の一例をご紹介します。(念の為ですが、同じことを実現するには色々な方法があります。ここではとりあえず簡単に実現することに主眼を置いてます。)

GCP とオンプレミス環境の間でサブネットを共有

図中の 192.168.103.252 (左)と 192.168.103.250 (右)の間をつなぎます。
環境間は VPN で接続されています。

GCP 側のゲートウェイの設定 (vpc1/2 にまたがるインスタンス)

NIC を 2 つ設定し、1 つ目を vpc1 に、2 つ目を vpc2 に設定します。その上で 2 つ目の NIC (vpc2 のNIC)に、Alias IP としてオンプレミス環境にある共有されるインスタンスの IP アドレス(例だと 192.168.103.250)を設定します。インスタンスを起動したら OS で ↓ の設定をします。

ip route add 192.168.103.251/32 via 10.142.0.1 dev eth0
ip tunnel add tun0 mode ipip remote 192.168.103.251 local⏎ 10.142.0.220 dev eth0
ip link set tun0 up
sysctl -w net.ipv4.ip_forward=1
ip route change 192.168.103.250 dev tun0 table local scope host

Alias IP を使うのはクラウド環境では ARP が実質動作してないからです。下の AWS の例でセカンダリプライベート IP アドレスを使うのも同じ理由です。

また最後の ip route change は、Alias IP が Linux のルーティングテーブルで実現されているのを変更したいからです。

オンプレミス環境側の VM の設定 (下側の VM)

ゲートウェイ用の VM を、共有する VM と同じサブネットに立ち上げ、OS で ↓ の設定をします。オンプレミス環境では Proxy ARP が使えるので Alias IP 的な設定は不要で、経路設定( ip route add )だけすればオッケーです。

ip tunnel add tun0 mode ipip remote 10.142.0.220 local⏎ 192.168.103.251 dev eth0
ip link set tun0 up
sysctl -w net.ipv4.ip_forward=1
ip route add 192.168.103.252 dev tun0 table local scope host
echo 1 > /proc/sys/net/ipv4/conf/eth0/proxy_arp

ここまで設定すると192.168.103.252192.168.103.250 の間で通信ができます。

GCP と AWS の間でサブネットを共有

図中の 172.31.254.100/101 (左)と 172.31.254.100/101 (右)をつなぎます。
環境間は VPN で接続されています。

GCP 側のゲートウェイの設定 (vpc1/2 にまたがるインスタンス)

NIC を 2 つ設定し、1 つ目を vpc1 に、2 つ目を vpc2 に設定します。(アドレスはなんでもいいです) その上で 2 つ目の NIC (vpc2 のNIC)に、Alias IP として AWS 側の subnet2 にある共有されるインスタンスの IP アドレス(例だと 172.31.254.200.201 )を設定します。インスタンスを起動したら OS で ↓ の設定をします。

ip tunnel add tun0 mode ipip remote 172.30.1.99 local 10.0.0.4 dev⏎ eth0
ip link set tun0 up
sysctl -w net.ipv4.ip_forward=1
ip route change 172.31.254.200 dev tun0 table local scope host
ip route change 172.31.254.201 dev tun0 table local scope host

AWS 側のゲートウェイの設定 (subnet1/2 にまたがるインスタンス)

NIC を 2 つ設定し、1 つ目を subnet1 に、2 つ目(というか追加の NIC)を subnet2 に設定します。その上で 2 つ目の NIC に、セカンダリプライベート IP アドレスとして GCP 側の vpc2 にある共有されるインスタンスの IP アドレス(例だと 172.31.254.100.101 )を設定します。インスタンスを起動したら OS で ↓ の設定をします。

コンソールからこのように起動するとパブリック IP アドレスが付与されませんが、Elastic IP を割り当てれば直接アクセスできるようになります。

sed -i -e 's/^EC2SYNC=yes/EC2SYNC=no/' /etc/sysconfig/network-scripts/ifcfg-eth1
reboot
ip tunnel add tun0 mode ipip remote 10.0.0.4 local 172.30.1.99 dev⏎ eth0
ip link set tun0 up
sysctl -w net.ipv4.ip_forward=1
ip route add 172.31.254.100/32 dev tun0 scope host
ip route add 172.31.254.101/32 dev tun0 scope host
echo 0 > /proc/sys/net/ipv4/conf/all/rp_filter

上記のようにEC2SYNCno にしておかないと DHCP のタイミングで再度セカンダリプライベート IP アドレスが設定されてしまいます

具体的には /etc/dhcp/dhclient.d/ec2dhcp.sh から呼ばれる rewrite_aliases() で設定されます。 rewrite_aliases()/etc/sysconfig/network-scripts/ec2net-functions で定義されてます。

rp_filter (uRPF)の設定は OS によって必要だったり必要じゃなかったりするかもしれません。(試したのは Amazon Linux AMI release 2018.03で、設定を変更しないと通信できませんでした。)

以上の設定により、GCP↔オンプレミス環境、GCP↔AWS のいずれでも、共有の対象となったインスタンス自体には何も特別な設定をすることなく、お互いあたかも同じサブネットにいるかのように通信できることを確認いただけるかと思います。( ping でも実行しながらゲートウェイインスタンスで tun0tcpdump すればトラフィックが経由してる様子が見られます。)

注意書き

ここでの手順はあくまで「とりあえず動く」といった程度のものであり、パフォーマンスへの影響はもとより、冗長性についても何ら考慮されてません。(ブリッジとなってるインスタンスは状態(ステート)を持たないので、冗長構成にするのはそんなに難しくないんじゃないかとは思いますが)

したがいまして、本構成はすぐに本番環境に使えるようなものでは一切ありませんが、一方、そんなに複雑なことをしなくてもクラウドとオンプレミス環境間、クラウド間でサブネット (L2) を共有できるというのは面白いなと思いました。

まとめ

というわけで無駄に長くなってしまいましたが、ハイブリッド環境、マルチクラウド環境を作るのに使える色々なサービスをご紹介しました。いずれも簡単にお試しいただくことができますので、お休みの間にでも実際に設定してみていただけると嬉しいです。

もし動作しないといったことがあれば、コメントを残していただければできるだけ回答させていただきたいと思っています。

というわけで、(すでに数日前に掲載されてますが)次の記事は Koichi さんによる「Skaffold + Cloud Build で Test にパフォーマンス測定を加えた CI を回す」です。

--

--

Seiji Ariga
google-cloud-jp

Customer Engineer, Network Specialist, Google Cloud (All views and opinions are my own.)