VPCにおける異なるサブネットとの通信
次に異なるサブネットとの通信のプロセスを見ていきます。ここでようやくルーターが登場します。
パケットの送信と受信
初めに、送信元ゲストOSは送信先IPアドレスが同一サブネットではないことから、デフォルトゲートウェイ(ルーター)へパケットを送信しようとします。
送信元ゲストOSがデフォルトゲートウェイのIPアドレスに対するARPリクエストを送信するので、ServerはデフォルトゲートウェイのIPアドレスとVPC IDをキーにしてMapping Serviceを検索しMACアドレスを入手、送信元ゲストOSへ返す、というところまでは同一サブネット内の通信と同じです。
MACアドレスを入手した送信元ゲストOSはデフォルトゲートウェイに対し以下のようなパケットを送信します。

Serverはまたすかさずパケットを横取りし、再度Mapping Serviceで、今度は送信先ゲストOSのIPアドレスとVPC IDをキーにして検索を実施、送信先ゲストOSがいるServerのIPアドレスを得ます。そして、ServerはゲストOSからのパケットをVPC IDでカプセル化しそのまま送信先Serverへ送ります。

パケットを受け取った送信先Serverは送信元の確認をした後、同一サブネット内の通信の場合とは異なり、送信元MACと送信先MACをそれぞれ、送信先ゲストのデフォルトゲートウェイと送信先ゲストのものに変更し、以下のようなパケットに仕立てた上で送信先ゲストへと送ります。

実際のパケット
同一サブネット内の通信の場合と違い通常のEthernetとの違いは見られず面白くはありませんが、一応instance1から別セグメントにあるインスタンスinstance3へpingした様子を見てみます。
instance1のIPアドレスが 172.31.24.51/20 で、instance3のIPアドレスが 172.31.2.146/20 なので、確かに別セグメントとなっています。
instance1$ ip addr show dev eth0
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 9001 qdisc pfifo_fast state UP group default qlen 1000
link/ether 06:58:86:91:36:49 brd ff:ff:ff:ff:ff:ff
inet 172.31.24.51/20 brd 172.31.31.255 scope global eth0
instance1$ ip neighbor
172.31.16.1 dev eth0 lladdr 06:f2:97:41:38:48 REACHABLE
instance3$ ip addr show dev eth0
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 9001 qdisc pfifo_fast state UP group default qlen 1000
link/ether 0a:96:bb:d9:32:dd brd ff:ff:ff:ff:ff:ff
inet 172.31.2.146/20 brd 172.31.15.255 scope global eth0
guest3$ ip neighbor
172.31.0.1 dev eth0 lladdr 0a:14:57:86:19:f2 REACHABLE
デフォルトゲートウェイのMACアドレスは通常キャッシュされてるのでARPの発生はなく、そのままpingのリクエスト・リプライがおこなわれてます。
instance1$ sudo tcpdump -etni eth0 icmp or arp tcpdump: verbose output suppressed, use -v or -vv for full protocol dode listening on eth0, link-type EN10MB (Ethernet), capture size 65535 bys 06:58:86:91:36:49 > 06:f2:97:41:38:48, ethertype IPv4 (0x0800), lengt98: 172.31.24.51 > 172.31.2.146: ICMP echo request, id 13145, seq 1, ngth 64 06:f2:97:41:38:48 > 06:58:86:91:36:49, ethertype IPv4 (0x0800), lengt98: 172.31.2.146 > 172.31.24.51: ICMP echo reply, id 13145, seq 1, leth 64 instance3$ sudo tcpdump -etni eth0 arp or icmp tcpdump: verbose output suppressed, use -v or -vv for full protocol dode listening on eth0, link-type EN10MB (Ethernet), capture size 65535 bys 0a:14:57:86:19:f2 > 0a:96:bb:d9:32:dd, ethertype IPv4 (0x0800), lengt98: 172.31.24.51 > 172.31.2.146: ICMP echo request, id 13145, seq 1, ngth 64 0a:96:bb:d9:32:dd > 0a:14:57:86:19:f2, ethertype IPv4 (0x0800), lengt98: 172.31.2.146 > 172.31.24.51: ICMP echo reply, id 13145, seq 1, leth 64
わざわざ見るようなものではなかったですね……。
VPCにおけるルーティング
上述の「VPCにおける異なるサブネットとの通信」に出てきた「ルーター」は「Amazon VPCルーター」と呼ばれ、EC2インスタンスが同一のVPC内にある他のサブネットのEC2インスタンスと通信することを可能としています。これは、VPC FAQにある「Q: Amazon VPC ルーターは何をするのですか?」の「Amazon VPCルーター」であり、「ルートテーブルの基本」に出てくる「暗示的なルーター」のことです。
また、EC2インスタンスはこのVPCルーターを通して、インターネットゲートウェイ、仮想プライベートゲートウェイ、さらにはVPCエンドポイントやVPCピアとも相互に通信しています。
実際には上述の通り、送信元ゲストOSから別サブネットの送信先ゲストOSへのパケットは送信元Serverから送信先Serverへと直接送信されています。しかしながら、VPCにおいてはVPCルーターと「ルートテーブル」によって上記のような裏側の動きを意識することなく、通常のIPネットワークと同じように設計・運用できるようになっています。
