NutaNice Xperience

主にNutanix製品を検証したり触ったりした結果をつづっています。※このブログの内容は個人の見識や見解をもとに作成しています。参考にされる場合は自己責任でご活用ください。実際に製品を使用される場合は、メーカードキュメントの手順に従い実施してください。

Flow Virtual NetworkingでNAT通信の仕組みを確認してみる【AOS 7.0 AHV 10.0/pc.2024.3】

※この記事は「AOS 7.0 AHV10.0 Prism Central pc.2024.3」時点の情報をもとに作成しています。その後の機能アップデートについてはメーカーの公開情報をご確認ください。

NutanixのFlow Virtual Networkingの連載については以下の記事にリンクをまとめています。ほかの記事にもこちらからアクセス可能です。

tomomartin.hateblo.jp

前回の記事では、FVNのVPCでオーバーレイネットワーク上に接続された仮想マシン間の通信を確認しました。今回は、オーバーレイネットワークに接続した仮想マシンが、SNATで送信元IPを変換して外部ネットワークへアクセスする仕組みを確認してみます。

目次

1.今回の環境

3ノードAHVクラスタ
AOS: 7.0.1
AHV: 10.0.1
Prism Central: pc.2024.3.1.1
仮想マシン: Windows Server 2022

環境は一般的なNutanixの3ノードクラスタです。Prism CentralはFVNで推奨となる3台構成としています。

▽Flow Virtual Networkingによる仮想プライベートクラウドのざっくりしたイメージ図は以下の通りです。クラスター上に独立した空間を作成して、そこにオーバーレイネットワークを作成する機能を指します。

2. NAT通信の仕組み

▽今回の環境は以下の通りで、先に答えをお見せします。VPCのオーバーレイネットワークに接続したVMが外部ネットワークへ接続する際は、brAtlasブリッジ内で送信元VMのIPがSNATでexternal subnet上のIPに変換され、パッチポートを通過してアップリンクから外部へ抜けていきます。

パッチポートを持たないAHV03については、「ovn-xx」ポートからgeneveトンネル通信で別のAHVを経由して外部ネットワークへ接続することになります。

ノード間のgeneve通信についてはリンク先で解説しています。

3. external subnetとSNAT IPの確認

▽以前の記事で、VPCを作成する際に、VPCからの出入口となる外部ネットワークとして「external subnet (nat)」を作成しました。

VPCにexternal subnetを接続すると、定義したIPプールの中からSNAT用のIPアドレスが自動or手動で設定できます。▽今回の環境のexternal sunbetとSNAT IPは以下の通りです。

▽これをイメージ図で表現すると以下のようになります。

仮想マシンからVPCの外部宛にアクセスする場合は、このSNAT IPを送信元IPに変換して通信します。

この図からもわかるように、NATを使用する場合は、external subnetおよびNATゲートウェイとして機能するのは2つのAHVホストとなるようです。ノード数やPrism Centralの台数によって増減するかはわかりませんが、今回の環境ではこうなりました。

なお、SNAT IPを使用する場合は、仮想マシンから外部への通信しかできない仕組みになっています。外部からNATでVPC内の仮想マシン宛に通信したい場合は、external subnet内から「Floating IP」を仮想マシンアサインする必要があります。これはまた別の記事で紹介します。

4. SNAT変換と外部への出力

external subnet上のSNAT IPへの変換は、brAtlasブリッジのFlowテーブルによって実行されています。Flowテーブルの内容をすべて把握するのは大変なので、関係のありそうな部分をピックアップして流れを紹介します。

VPCのオーバーレイネットワークに接続した仮想マシンの「tap」からの入力はOpenFlowのtable=0で確認できます。(AHV01で確認&抜粋)

[root@ahv-01 ~]# ovs-ofctl dump-flows brAtlas
cookie=0xded6f111, duration=546957.422s, table=0, n_packets=1503868, n_bytes=133529118, priority=100,in_port=tap2 actions=load:0x10->NXM_NX_REG13[0..15],load:0xf->NXM_NX_REG9,load:0x2712->OXM_OF_METADATA,load:0x2->NXM_NX_REG14,load:0->NXM_NX_REG13[16..31],resubmit(,8)

▽「tap」からの入力された外部宛の通信は、table=46でNAT変換されていることが確認できます。

  • ソース: 192.168.10.0/24 → 172.22.7.27へNAT変換

途中のルールは飛ばしていますが、最終的にtable=65でVLAN ID 2207が設定されてパッチポートから出力されるようです。(AHV01で確認&抜粋)

[root@ahv-01 ~]# ovs-ofctl dump-flows brAtlas
 cookie=0xe070fd17, duration=554898.558s, table=45, n_packets=0, n_bytes=0, idle_age=65534, hard_age=65534, priority=153,ct_state=-trk,ip,reg15=0x2,metadata=0x3,nw_src=192.168.10.0/24 actions=ct(commit,table=46,zone=NXM_NX_REG12[0..15],nat(src=172.22.7.27))
 cookie=0xe070fd17, duration=554898.558s, table=45, n_packets=14317, n_bytes=7174010, idle_age=14, hard_age=65534, priority=153,ct_state=-rpl+trk,ip,reg15=0x2,metadata=0x3,nw_src=192.168.10.0/24 actions=ct(commit,table=46,zone=NXM_NX_REG12[0..15],nat(src=172.22.7.27))
~~~中略~~~
 cookie=0x8505267a, duration=865834.403s, table=65, n_packets=790622, n_bytes=80049428, idle_age=86, hard_age=65534, priority=100,reg15=0x1,metadata=0x2710 actions=mod_vlan_vid:2207,output:"patch-brAtlas-t",strip_vlan

このtable=65で、VLAN IDを設定して「output」後の「strip_vlan」は何か意味があるのか、記述ミスなのかよくわかりませんでした。

なお、「brAtlasブリッジ」からパッチポートを経由して「br0ブリッジ」へ出力された後は、Flowテーブルで通常の動作(action=NORMAL)が適用され、br0ブリッジのMACアドレステーブルを参照してアップリンクに通信を送信します。

▽br0のMACアドレステーブルは以下のコマンドで確認可能です。「port:10」は今回の環境でのofportsの番号で、アップリンクの「eth0やeth1」のインターフェースを指します。(VLANとMACアドレスは適当)

[root@ahv-01 ~]# ovs-appctl fdb/show br0
 port  VLAN  MAC                Age
   10  100  b6:ff:ad:1f:22:46  294
   10  101  7c:c2:55:5c:73:69  285
     5     0  52:54:00:f5:03:a3    0            ←CVM (vnet0)
   10  110  00:50:56:9f:ae:36  281
   10  200  c4:cb:e1:ec:0b:7c  281
LOCAL   0  00:62:0b:22:ef:40    0          ←AHV (br0)
   10  150  00:50:56:93:8a:63  274
   10     0  f8:0b:cb:1d:d6:5c  270
   10     1  00:50:56:90:64:95  266
   10     1  00:50:56:a0:47:6f  266
   10    50  00:50:56:b0:be:e6  264

このような流れで、VPCのオーバーレイネットワークに接続した仮想マシンからの外部向け通信はSNAT変換されています。

なお、AHVホストのアップリンクポート(eth0やeth1)でtcpdumpコマンドを使用して、通信をキャプチャしてみると、VPCの192.168.10.0/24にIPを持つ仮想マシンからの通信が、SNAT IPの172.22.7.27に変換されていることも確認できます。

本当はpatchポートに対してtcpdumpをしたかったのですが、どうもOVSブリッジのpatchポートまではtcpdumpでみれなそうでした。別のinternalポートを作成して、ミラーリングなどもできそうではありますが、AHVの内部ブリッジ構造に手を加えるのはタブーな気がしますのでやめておきます。

データパスフローでのNAT変換の確認

実は、OVSのFlowテーブルをもとに処理された通信のキャッシュ(的な?)を確認することもできます。ここでNAT変換されている様子も確認できます。

「e0:19:95:ad:56:d0」は、172.22.7.27のMACアドレスです。

[root@ahv-01 ~]# ovs-dpctl dump-flows | grep 172.22.7.27
recirc_id(0),in_port(3),skb_mark(0),ct_state(-new-rpl-trk),eth(src=f8:0b:cb:1d:d6:7f,dst=e0:19:95:ad:56:d0),eth_type(0x8100),vlan(vid=2207,pcp=0),encap(eth_type(0x0800),ipv4(src=128.0.0.0/224.0.0.0,dst=172.22.7.27,proto=17,ttl=56,frag=no),udp(dst=32768/0x8000)), packets:14, bytes:8628, used:6.829s, actions:pop_vlan,ct(zone=9,nat),recirc(0x322d)
recirc_id(0x322b),in_port(17),ct_state(-rpl+trk),eth(),eth_type(0x0800),ipv4(src=192.168.10.0/255.255.255.0,frag=no), packets:1, bytes:121, used:6.945s, actions:ct(commit,zone=9,nat(src=172.22.7.27)),recirc(0x322c)

 

5. 戻りの通信の流れ

▽eth0やeth1から戻ってきた172.22.7.27宛の通信は、「br0ブリッジ」でFlowテーブルに従い「action: NORMAL」で通常の処理が適用され、br0のMACアドレステーブルを参照します。

なお、MACアドレステーブルを確認すると「172.22.7.27」に紐づいているMACアドレスが、brAtlasブリッジと接続されているpatchポート(ofports:14番)を指していることが分かります。

[root@ahv-01 ~]# ovs-appctl fdb/show br0 | grep 2207
   10  2207  00:50:56:b0:42:b2  115
   14  2207  e0:19:95:ad:56:d0  104
   10  2207  f8:0b:cb:1d:d6:7f  104
   10  2207  00:42:5a:f2:a5:80   58
   10  2207  00:50:56:b0:d4:ed   4

この情報に従い、172.22.7.27宛のパケットは「patch」ポートに送られます。

▽そしてbrAtlasの「patch」ポートから入力してきた通信のルールが、brAtlasのFlowテーブルのtable-0で確認できます。(AHV01で確認&抜粋)

[root@ahv-01 ~]# ovs-ofctl dump-flows brAtlas
cookie=0xae04b038, duration=858253.532s, table=0, n_packets=0, n_bytes=0, priority=180,conj_id=100,in_port="patch-brAtlas-t",dl_vlan=2207 actions=strip_vlan,load:0x1->NXM_NX_REG13[0..15],load:0x2->NXM_NX_REG9,load:0x2710->OXM_OF_METADATA,load:0x1->NXM_NX_REG14,load:0->NXM_NX_REG13[16..31],mod_dl_src:e0:19:95:ad:56:d0,resubmit(,8)
cookie=0xae04b038, duration=858253.532s, table=0, n_packets=0, n_bytes=0, priority=180,dl_vlan=2207 actions=conjunction(100,2/2)
cookie=0x8505267a, duration=858253.532s, table=0, n_packets=1145077, n_bytes=1587856890, priority=150,in_port="patch-brAtlas-t",dl_vlan=2207 actions=strip_vlan,load:0x1->NXM_NX_REG13[0..15],load:0x2->NXM_NX_REG9,load:0x2710->OXM_OF_METADATA,load:0x1->NXM_NX_REG14[],load:0->NXM_NX_REG13[16..31],resubmit(,8)

「in_port="patch-bratlas-t"」でexternal subnetのvlanである「2207」の受信規則が書かれています。

▽戻りのNAT変換ですが、table=13に記載のものが、おそらく該当されると思われます。(AHV01で確認&抜粋)

[root@ahv-01 ~]# ovs-ofctl dump-flows brAtlas
cookie=0xb0f56809, duration=563219.467s, table=13, n_packets=1144683, n_bytes=1606631520, idle_age=72, hard_age=65534, priority=100,ip,reg14=0x2,metadata=0x3,nw_dst=172.22.7.27 actions=ct(table=14,zone=NXM_NX_REG12[0..15],nat)

仮想マシンの「tap」への出力のルールもありますので、最終的にはここのテーブルにて仮想マシンに通信が戻ってきているようです。

[root@ahv-01 ~]# ovs-ofctl dump-flows brAtlas
 cookie=0xded6f111, duration=562031.237s, table=65, n_packets=1906863, n_bytes=1491508947, idle_age=75, hard_age=65534, priority=100,reg15=0x2,metadata=0x2712 actions=output: tap2

次回は、外部からVPC内の仮想マシン宛にNATで通信する際に必要な「Floating IP」について調べてみたいと思います。

以上です。