第3回では、DVR環境でのパケット処理を解析してみます。少しだけ難しいですが、興味深い挙動がわかるので、最後までおつきあいください。
解析のためのコマンド
第2回で構築した手順では、NeutronのML2 pluginとしてOVS(Open vSwitch)を選択しています。この場合、仮想ルータの実態はNamespace(Linux Namespace)、iptables、OVSの組み合わせで構成されています。これを前提に、今回の解析で使うコマンドを以下に示します。なお出力結果は大量となるので、必要な箇所以外は適宜省略しています。
パケットキャプチャ方法
1 | # tcpdump -i <インタフェース名> -n |
ルーティング情報確認
2 | # ip route show table <テーブル名> |
OVSのフローテーブル確認
1 | # ovs-ofctl dump-flows <ブリッジ名> |
Namespace内でのコマンド実行
1 | # ip netns exec <Namespace> <コマンド> |
ネットワークの状態を把握する
パケット処理解析の前に、現在のOpenStack内部のネットワークがどのようになっているかを把握します。各テナントで、それぞれインスタンス(VM)を起動します。ネットワークトポロジー上では図1のようになっています。
図1:ネットワークトポロジー
最初にインタフェースやブリッジ等のネットワーク周りの状態を確認します。まずは、Controller + Network Serverの状態を確認します。
インタフェース名、ブリッジ名は、以下の手順で確認します。
インタフェース、ブリッジ名確認
02 | 2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> |
03 | 3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> |
04 | inet 192.168.10.101/24 brd 192.168.10.255 scope global eth1 |
05 | 4: eth2: <BROADCAST,MULTICAST,UP,LOWER_UP> |
06 | inet 192.168.20.101/24 brd 192.168.20.255 scope global eth2 |
07 | 6: ovs-system: <BROADCAST,MULTICAST> |
08 | 7: br-ex: <BROADCAST,MULTICAST,UP,LOWER_UP> |
09 | 8: br-int: <BROADCAST,MULTICAST> |
10 | 10: br-tun: <BROADCAST,MULTICAST> |
次にNamespaceと、Namespace内のインタフェースを確認します。
Namespace確認
2 | snat-dc03bb5f-7a0e-4132-8b78-0fa2d35ca39f |
3 | qrouter-dc03bb5f-7a0e-4132-8b78-0fa2d35ca39f |
SNAT用Namespace内のインタフェース確認
1 | # ip netns exec snat-dc03bb5f-7a0e-4132-8b78-0fa2d35ca39f ip addr |
2 | 11: qg-e74ea6e5-c8: <BROADCAST,MULTICAST,UP,LOWER_UP> |
3 | inet 10.0.0.10/24 brd 10.0.0.255 scope global qg-e74ea6e5-c8 |
4 | 13: sg-cab3bcca-30: <BROADCAST,MULTICAST,UP,LOWER_UP> |
5 | inet 192.168.210.10/24 brd 192.168.210.255 scope global sg-cab3bcca-30 |
6 | 15: sg-7d59c9a4-4d: <BROADCAST,MULTICAST,UP,LOWER_UP> |
7 | inet 192.168.220.10/24 brd 192.168.220.255 scope global sg-7d59c9a4-4d |
仮想ルータ用Namespace内のインタフェース確認
1 | # ip netns exec qrouter-dc03bb5f-7a0e-4132-8b78-0fa2d35ca39f ip addr |
2 | 12: qr-bdc3d5ac-e6: <BROADCAST,MULTICAST,UP,LOWER_UP> |
3 | inet 192.168.210.1/24 brd 192.168.210.255 scope global qr-bdc3d5ac-e6 |
4 | 14: qr-84e871c6-a4: <BROADCAST,MULTICAST,UP,LOWER_UP> |
5 | inet 192.168.220.1/24 brd 192.168.220.255 scope global qr-84e871c6-a4 |
続いて、OVSの構成確認をします。
04 | options: {(略) remote_ip="192.168.20.102"} |
06 | options: {peer=patch-tun} |
09 | options: {(略) remote_ip="192.168.20.103"} |
21 | options: {peer=patch-int} |
以上の結果から判明したインタフェース、ブリッジ、IPアドレスを関連付けて図示すると、図2のようになります。
図2:Controller + Network Serverの状態
同様に、Compute Server1、2も調査します。今回の検証環境では、図3のようになっていることを確認しました(図が複雑なので、Management Network用のeth1は省略しています)。注目していただきたいのは、仮想ルータ用Namespaceをすべてのノードが同じ名前、同じインタフェース、同じIPアドレスで有している点です(図3の赤い点線部分)。
図3:全体の状態
これで、現在の状態がわかりました。それでは、実際にパケット処理を解析します。「別テナント上のインスタンス向けパケット」、「FIP(Floating IP)なしでのPublic Network向けパケット」、「FIPありでのPublic Network向けパケット」の順で解析していきます。
別テナント(セグメント)上のインスタンス向けパケット処理
非DVR環境では、別テナント向けの通信も、Network Server上の仮想ルータを経由していました。では、DVR環境下ではどうなっているのでしょうか。
Compute Server1上のインスタンスtest220-1(IPアドレス192.168.220.11、DFG 192.168.220.1)から、Compute Server2上のインスタンスtest210-1(IPアドレス192.168.210.14、DFG 192.168.210.1)へpingを実行します。パケット処理の大まかなあたりをつけるため、各サーバのTenant Networkのインタフェースでパケットをキャプチャします。
Controller + Networkのeth2でのパケットキャプチャ
Compute1のeth2でのパケットキャプチャ
2 | IP 192.168.20.102 > 192.168.20.103: GREv0, key=0xb, length 106: IP 192.168.220.11 > 192.168.210.14: ICMP echo request, id 15364, seq 1, length 64 |
3 | IP 192.168.20.103 > 192.168.20.102: GREv0, key=0xc, length 106: IP 192.168.210.14 > 192.168.220.11: ICMP echo reply, id 15364, seq 1, length 64 |
Compute2でのeth2でのパケットキャプチャ
2 | IP 192.168.20.102 > 192.168.20.103: GREv0, key=0xb, length 106: IP 192.168.220.11 > 192.168.210.14: ICMP echo request, id 15364, seq 1, length 64 |
3 | IP 192.168.20.103 > 192.168.20.102: GREv0, key=0xc, length 106: IP 192.168.210.14 > 192.168.220.11: ICMP echo reply, id 15364, seq 1, length 64 |
Controller + Network Serverでは処理が行われず、Compute Server1、2だけで完結しています。Compute Server1、2は、それぞれ一つずつ仮想ルータを有しており、両テナント用のインタフェースを有しています。どの仮想ルータのインタフェースで処理されているかを確認するため、今度は仮想ルータ用Namespace内でパケットキャプチャをします。
Compute Server1の仮想ルータ用Namespace内で、送信側インタフェース(192.168.220.1)でのパケットキャプチャ
1 | # ip netns exec qrouter-dc03bb5f-7a0e-4132-8b78-0fa2d35ca39f tcpdump -i qr-84e871c6-a4 -n |
2 | IP 192.168.220.11 > 192.168.210.14: ICMP echo request, id 19204, seq 1, length 64 |
Compute Server1の仮想ルータ用Namespace内で、受信側インタフェース(192.168.210.1)でのパケットキャプチャ
1 | # ip netns exec qrouter-dc03bb5f-7a0e-4132-8b78-0fa2d35ca39f tcpdump -i qr-bdc3d5ac-e6 -n |
2 | IP 192.168.220.11 > 192.168.210.14: ICMP echo request, id 19204, seq 1, length 64 |
Compute Server2の仮想ルータ用Namespace内で、送信側インタフェース(192.168.220.1)でのパケットキャプチャ
1 | # ip netns exec qrouter-dc03bb5f-7a0e-4132-8b78-0fa2d35ca39f tcpdump -i qr-84e871c6-a4 -n |
2 | IP 192.168.210.14 > 192.168.220.11: ICMP echo reply, id 19204, seq 1, length 64 |
Compute Server2の仮想ルータ用Namespace内で、受信側インタフェース(192.168.210.1)でのパケットキャプチャ
1 | # ip netns exec qrouter-dc03bb5f-7a0e-4132-8b78-0fa2d35ca39f tcpdump -i qr-bdc3d5ac-e6 -n |
2 | IP 192.168.210.14 > 192.168.220.11: ICMP echo reply, id 19204, seq 1, length 64 |
ICMP echo requestはCompute Server1だけで、replyはCompute Server2だけで処理されていることがわかります。これを図示すると、図4のようになります。
図4:別テナント上のインスタンス向け通信
このようにDVR環境下では、別テナント上のインスタンス向け通信は、それぞれのインスタンスが動作しているCompute Server上の仮想ルータのみで処理されていることがわかります。