「AWS VPCを使ってよくやるネットワーク構成」。実際に「よくやる(やられてる)」のかどうかは、正直、僕の狭い観測範囲内でのことなので自信は持てないけど、それはこんなん↓だ(手書きでゴメン)。
こんな構成を GCP で再現したかったのだけど。GCP にも、AWS VPC っぽい Network
、サブネットっぽい subnet
があるので、楽勝でできるかなと思ったけど、そうは問屋が卸してくれなかったのだ。
AWS でいう VPC やルートテーブルが GCP(GCE) のどれと対応してるか、というのがわかりやすいの、ないかなぁ。 private な subnet を持つ AWS VPC と同じようなかんじの構成を GCP でやる場合はどうすればいいんだろ。わからん。
— a-know (@a_know) 2016年4月1日
AWS と GCP のネットワークの考え方には、微妙な違いが...
ドキュメントを読んだり、AWS 側の設定項目とにらめっこしてみたり、もしくは手当たり次第に試してみたりしてようやく見えてきたのが、以下の様な両者間の違い。
- ルート(ルートテーブル)の持ち方
- サブネットまわりの扱い
上記のような特性のため、AWS と同じ感覚でサブネットを作成しちゃうと、目的のことはできない感じになる。
NAT ゲートウェイを持つネットワークを構築してみる
このことに気づいたあと、「じゃあ、"AWS VPCを使ってよくやるネットワーク構成" を GCP でも再現しようとしたら、どのようにするのがいいのかなあ」といろいろ調べてみたら、GCP のドキュメント内に GCP で NAT ゲートウェイを構築する手順(Virtual Private Cloud (VPC) Network Overview | VPC | Google Cloud)について記述されている項目を見つけた。
This example shows setting up the gateway in a legacy network.
と書かれていて、"AWS VPCを使ってよくやるネットワーク構成" がレガシー、という意味なのか、はたまたそうではないのかもよくわからなかったんだけど、NAT が出てくるってことは "よくやるネットワーク構成" になるはずだって思ったので、まずは、このドキュメントに示されている gcloud コマンドをそっくりそのまま愚直に叩き、その通りの構成に仕上げてみた。
$ gcloud compute networks create gce-network --range 10.240.0.0/16 $ gcloud compute firewall-rules create gce-network-allow-ssh \ --allow tcp:22 --network gce-network $ gcloud compute firewall-rules create gce-network-allow-internal \ --allow tcp:1-65535;udp:1-65535;icmp \ --source-ranges 10.240.0.0/16 --network gce-network $ gcloud compute instances create nat-gateway --network gce-network --can-ip-forward \ --zone asia-east1-b \ --image centos-7 \ --tags nat $ gcloud compute instances create example-instance --network gce-network --no-address \ --zone asia-east1-b --image centos-7 --tags no-ip $ gcloud compute routes create no-ip-internet-route --network gce-network \ --destination-range 0.0.0.0/0 \ --next-hop-instance nat-gateway \ --next-hop-instance-zone asia-east1-b \ --tags no-ip --priority 800 a-know@nat-gateway:~$ sudo sh -c "echo 1 > /proc/sys/net/ipv4/ip_forward" a-know@nat-gateway:~$ sudo iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
(ちなみに tcp:1-65535;udp:1-65535;icmp
ここの部分はドキュメントではセミコロン区切りではなくてカンマ区切りになってるのだけど、gcloud コマンドはセミコロン区切りでよこせと怒ってくる)
(2016/09/10 追記:やはりカンマが正しいようす。この記事のコメント欄も参照してください。)
これらのコマンドにより、下の図のような構成のネットワークが作成できた。
このネットワークについて、整理する。
- ネットワーク内のインスタンス同士のルーティング(自身のネットワークに対するルーティング)
- ネットワーク作成時に自動で作られる、デフォルトのルートが該当。
- dest
10.240.0.0/16
, priority1000
- ネットワーク内からネットワーク外への通信ルーティング
- ネットワーク内インスタンスへの外部からのアクセス
nat-gateway
への ssh- global ip address が割り振られている為、可能。
example-instance
への(外部からの直接的な)ssh- global ip address が割り振られてない為、不可能。
うん、いいかんじ。作られたネットワークにはサブネットが無いけれど、だいぶ近い気がする。
サブネットの有無に後ろ髪を引かれる
とはいえ、GCP でのサブネットは、そのネットワークを作成する時点でサブネットを一つも作成していない場合、あとからそのネットワークにサブネットを作成することはできない?様子(GCPでサブネットが使えるようになった。 - 14Room)。なので、今々では必要がないにしても、少なくとも1つのサブネットは作っておいたほうがよさそうな気がしてきた。
ということで、gcloud コマンド群を若干見直し、改めて構築しなおしてみた。各種名称は自分の目的のものっぽいものにしているので、適宜読み替えて欲しい。
$ gcloud compute --project "a-know-home" networks create "a-know-home-network" \ --mode "custom" $ gcloud compute --project "a-know-home" networks subnets create "home-subnet" \ --network "a-know-home-network" \ --region "asia-east1" \ --range "10.240.0.0/16" $ gcloud compute firewall-rules create allow-ssh \ --allow tcp:22 \ --network a-know-home-network $ gcloud compute firewall-rules create allow-internal \ --allow tcp:1-65535;udp:1-65535;icmp \ --source-ranges 10.240.0.0/16 \ --network a-know-home-network $ gcloud compute --project "a-know-home" instances create "nat-gateway" \ --zone "asia-east1-a" \ --machine-type "f1-micro" \ --subnet "home-subnet" \ --metadata "ssh-keys=xxx" \ --can-ip-forward \ --maintenance-policy "MIGRATE" \ --image "/centos-cloud/centos-7-v20160329" \ --boot-disk-size "10" \ --boot-disk-type "pd-standard" \ --boot-disk-device-name "nat-gateway" \ --no-scopes $ gcloud compute --project "a-know-home" instances create "web" \ --zone "asia-east1-a" \ --machine-type "f1-micro" \ --subnet "home-subnet" \ --no-address \ --metadata "ssh-keys=xxx" \ --maintenance-policy "MIGRATE" \ --tags "no-ip" \ --image "/centos-cloud/centos-7-v20160329" \ --boot-disk-size "10" \ --boot-disk-type "pd-standard" \ --boot-disk-device-name "web" \ --no-scopes $ gcloud compute routes create no-ip-internet-route --network a-know-home-network \ --destination-range 0.0.0.0/0 \ --next-hop-instance nat-gateway \ --next-hop-instance-zone asia-east1-a \ --tags no-ip --priority 800 a-know@nat-gateway:~$ sudo sh -c "echo 1 > /proc/sys/net/ipv4/ip_forward" a-know@nat-gateway:~$ sudo iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
このコマンド群で構築できるネットワークは、下の図のような構成になっている。と思う。
先ほどの図と比べてみても微妙な違いだけど、サブネットの有無を表現してみた。「AWS VPCを使ってよくやるネットワーク構成」が再現できているのかどうかは微妙かもしれないけれど、いったんはこれで僕は満足した。
まとめ
長々と書いたけど、ポイントをまとめるとすれば下記になるだろうか。
- GCP でも、ネットワーク内にサブネットを複数設定可能だけど、下記のような点が AWS VPC と異なっているのでアタマの切り替えが必要
- AWS VPC でいうプライベートサブネットに相当する構成にしたい場合は、
...と、まとめてみたけども、先日基礎の見直しを始めたばかりの人間が言っていることなので、何かアドバイスをもらえるなら非常に嬉しいっす!
参考リンク
- 書評 〜 「さわって学ぶクラウドインフラ Amazon Web Services 基礎からのネットワーク&サーバー構築」を読んで - 日常メモ
- 【AWS 再入門】VPC 環境に踏み台サーバーを構築して SSH 接続してみよう – PSYENCE:MEDIA
- 【2015年版】AWS ユーザが Google Cloud Platform に15分で入門する!
- Virtual Private Cloud (VPC) Network Overview | VPC | Google Cloud