まーぽんって誰がつけたの?

iOS→Scala→インフラなおじさん技術メモ

【AWSしかやったことない人向け】AWSとGCPのネットワークの違いを理解してみよう

背景

  • AWSでVPC作ったりしたことあるけど、GCPやったことないって人は色々違いに戸惑う
  • アカウントの関係性、ネットワークの概念の違いなどを理解したのでまとめた

AWSとGCPのアカウントの考え方の違い

AWSの場合、ある人間に対して色々なAWSアカウントが付与される。

(人間)  ->  個人で発行されたアカウント
        ->  会社で発行されたアカウント

GCPの場合、ある人間は色々なプロジェクトというものに属することができる。 そして、その人間が使うアカウントはGmailとかで使ってるようなGoogleアカウントである。

(人間 with Googleアカウント)  ->  プロジェクト 会社のやつ
                           ->  プロジェクト 何の関係もない個人のやつ

GCPの方が始めるのはすごく簡単な気がする。アカウント管理もGoogleアカウントさえやっときゃいいみたいな感じなので、Googleにロックインされる感はある。

まずはAWSのネットワークについて説明するよ

VPCとsubnetについて

AWSではこの2つが基本となる考え方。VPCは各region内における仮想的なネットワークで、subnetはそれらをさらに分割した論理的な単位。 VPCはregionをまたぐことはできず、regionごとに作ることしかできない。region内で複数VPCを作ることは可能。

subnetはVPCに属しているのでVPCで決めたネットワーク範囲内(下の図だと172.16.0.0/16)の範囲でのみ作成できる。

f:id:masato47744:20170422015409j:plain

この上の図は、AWSでインフラ作るときに、ごく一般的な構成を図示している。各regionごとに、VPCを作り物理的にはavailability-zoneで分かれていてその中にsubnetを作っていくみたいなやつ。 subnetをpublic subnetprivate subnetと便宜的に呼び、public subnetには、NAT GatewayとpublicなIPアドレスを持ったインスタンスを置く。private subnetにはpublicなIPアドレスを持たないインスタンスをおいておく。 private subnetが外部と通信する場合は、NAT Gateway経由で外に出て行き、private subnet内のインスタンスに接続するには、public subnetにある踏み台インスタンスなど経由で接続をする。

security groupについて

AWSでは、各インスタンスの通信の制限を基本的にsecurity groupで行う。ACLもあるけどね

security groupの考え方は、特定のインスタンスや、特定のIPアドレスからの特定のプロトコルを受け付けるというものを作成して、それをインスタンスに付与していく。

f:id:masato47744:20170422015425p:plain

上の図でいえば、例としてsg-1とsg-2、sg-3が作成されている。

sg-1はpublic subnetにあるi-01のインスタンスからのみsshを受けるというルールで、private subnet内にあるi-02とi-03にルールを付与するというやり方をとる。俗に言う踏み台とかbastionと呼ばれるインスタンスのやり方。 こうすると、private subnet内のインスタンスは踏み台経由でないとsshログインできないということになる。

sg-2も同様に別のavailability zoneにおける踏み台のsecurity groupを表現している。 sg-3は、i-01とi-04のインスタンスへ外部からsshアクセスできるということ。

こんな風にまずは、セキュリティグループを作り、それを各インスタンスにつけていくという流れをとるのがAWS流の基本的なやり方。

ここまでを踏まえて、次でGCPのネットワークについて説明します。

GCPのネットワーク

ネットワークサブネットワークという概念

GCPにおいて、各プロジェクトはネットワークというものを複数作成することができる。さらに、ネットワークは複数のサブネットワークを持つことができる。

まず、ネットワークという単位には、CIDRはない。なんとなくVPCと対比で考えるとCIDRがあって欲しいところだけどない。あくまでも論理的なオブジェクトでしかない。

このネットワークに対して、サブネットワークというものを切ることができる。このサブネットワークはCIDRを持っている。ここがポイント。

この辺を図で説明してみる。

f:id:masato47744:20170422015716j:plain

この図はGCPにおけるネットワーク構成。AWSのVPC的なネットワーク構成とだいぶ異なっている。なおこの図では、プロジェクトを作ると必ず作成されるデフォルトネットワークと呼ばれるものを示している。

デフォルトネットワークだと、必ずリージョンごとにサブネットワークが一つ作成される。GCPだと、AWSのVPCのようにregionごとのネットワークではなく、なんと、最初から全リージョンをまたいだネットワークが作成されてるのだ。つまり、全リージョンまたいだインスタンスそれぞれに内部IPアドレスでアクセスできるということを示している。

じゃあ、なんでサブネットワークなんてものがあるのかというと、単に名前をつけたいというぐらいのものであると思って欲しい。 たとえば、全世界のリージョンにインスタンスがあるけれど、sshをするのは日本のリージョンだけとしたいみたいなときに、CIDRをつけられるサブネットワークがないと、日本のインスタンスたちが属するIPアドレスの範囲が分からず、IPアドレスガチャ状態になってしまう。

Nat Gatewayなんてものは基本的にない

GCPはとても男らしくて、基本的に全インスタンスに外部IPをつけようとする。 で、外部IPがつけられたインスタンスが外部に通信しにいくときは、そのインスタンスにつけられた外部IPをsourceIPとして接続しにいく。 逆に外部からそのインスタンスに通信しにいくときもこの外部IPを使って接続しにいく。

GCPの場合、sshなどもGoogleアカウントと統合されてるので基本的に自分で.ssh/authorized_keysに書き込んだりはしない。Googleアカウント側を2段階認証などで守ればそれでOKみたいという考えだろうか。まぁどんな環境だろうと必ずどこかは穴を開けないといけないので同じっちゃ同じ。

もちろん、外部IPをなしにすることもできる。その場合、このインスタンスは外部への通信も外部からの通信も受けることができない。ただ、内部IPはあるので、ネットワーク内のインスタンスであれば通信することは可能である。

どうしても、NAT Gatewayのようなことがやりたければ、通常のインスタンスをたててNATの役割をさせて、すべてのインスタンスの外部IPをなくして、ルートテーブルを修正して、NATインスタンス経由で外に出て行くようにすればいい。 NATの役割をする場合は、インスタンスを作成するときにルーティング可能にできるオプションを選択するだけでよい。

Firewall

GCPにはFirewallと呼ばれるAWSのSecurityGroup相当のものがある。このFirewallという機能がGCPとAWSで随分と違う部分。 GCPの場合は、各インスタンスにタグと呼ばれるものを好きなだけ貼ることができる。このタグをベースにネットワークの制限をつけていく。

ここで再びさっきの上の図を詳しく見ていく。

f:id:masato47744:20170422020010p:plain

firewallルールのrule2を見ると、3.4.5.6からのTag:aへのHTTP接続を受け付けるというルールを作成してある。この場合、Tag:aがついているすべてのインスタンスは、外部からhttp接続できるということである。

rule3を見ると、10.146.0.0/20からTag:bへのHTTP接続を受け付けるというルールを作成してある。この場合、tokyo regionのサブネットワーク内にあるVMインスタンスすべて(VM1,2,3)からus regionにあるTag:bがついているインスタンスはHTTP接続を受け付けるということである。

さらに、rule1で、すべてのインスタンスは10.0.0.0/8からのSSH接続を受け付けるというルールを設定しておく。そうすると、このネットワーク内のインスタンスは10.0.0.0/8に属する(10.0.0.1 ~ 10.255.255.254)ので、お互いにssh接続ができるという仕組み。このように特定のタグではなく、すべてのターゲットという指定もできる。

Firewallのソースフィルタ

rule1のような、特定のIPアドレス範囲から受け付けるという部分をソースフィルタという。これも結構変わった考え方で面白い。どういうことかというと、CIDRで例えばクラスBとクラスCのアドレス同士でも設定できるということ。

ここで出てくるのがさっき説明したサブネットワークだが、デフォルトネットワーク以外であれば、サブネットワークには好きなCIDRをつけられる。

|サブネットワークA| 172.20.0.0/20

                |インスタンス A1| 172.20.10.5   <------  
                                                                               |
|サブネットワークB| 192.168.100.0/24                |  HTTP
                                                                               |
                |インスタンス B1| 192.168.100.99 -----         

とした場合、通常は別ネットワークとなるがFirewallのソースフィルタでは単なる名前でしかないので関係なく指定することができる。 サブネットワークAにインスタンスA1、サブネットワークBにインスタンスB1がいたとして、Firewallとしてはソースフィルタに、192.168.100.0/24を指定してhttpを許可したとしてタグを作成して、そのタグをA1につければ、A1はB1からhttp接続を受け付けられるようになる。

これはAWSにはなかった概念だと思う。

まとめ

AWSとGCPの違いを人に説明しようと思ってみたけど説明しようとすると自分でもよくわかってない部分にぶちあたるという感じになった。

GCPも調べてみると色々利点があり、(安い、全世界またがったネットワークが強い、googleアカウントとの統合がうまい、LBの温め不要)ちょっと好きになってきた

両者の違いをかなり個人的な感想だけどこんなイメージ。

  • AWSさんはベーシックなネットワーク構成をクラウド上に再現して顧客のためにどんどん使いやすいようにがんばってくれる優等生
  • GCPはVPC作って、subnet作ってとかそういうのめんどくさいから、もうVMインスタンス主役でちゃっちゃとグーグルアカウントでやっちゃおうぜ、あ、俺らが使ってるplatformそのまま貸してあげるけど俺らの新しい概念についてきてね!

みたいなスタンスの差を感じた。