🍕

サブネットピアリング を Hub-Spoke 構成で使うときの注意 (UDRを適切に)

に公開

サブネットピアリング

Subnet Peering は、仮想ネットワーク全体をピアリングするのではなく、ピアリングに参加するサブネットを指定してピアリングを構成できる機能です。
サブネット同士を直接ピアリングするものではなく、ピアリングする際に相手側VNetへ広報するアドレス空間を制限する機能、と理解するのが現時点の実装を理解しやすいのではないかと思います。

主な目的としては、ピアリングする必要のないサブネットのアドレス空間を広報しないようにして、セキュリティ要件に対応したり、IPv4 アドレス空間を節約したり、オンプレミス側へ公開する範囲を制限したりするといった使い方があります。

Subnet Peering には制限事項もあり、ドキュメントに記載されているのですが、その中で Hub-Spoke 構成の場合に割とよくありそうで注意が必要かなというものがあったので、念のため本記事で記載しておきます。

Hub-spoke 構成での注意 : UDR の設定に注意

広いアドレス空間を指定した UDR で Hub 経由で spoke 間の通信を実現している場合に spoke 間で subnet peering を構成すると、相互通信不可となる spoke subnet が出る可能性があります。
まとめると、UDR をきちんと設定してくださいね、ということなのですが、まぁ具体的にどういうことか記載していきます。

サンプルとして以下のような構成を考えてみます。

検証 Hub-Spoke 構成

  • Hub には Azure Firewall があり、Spoke の Vnet1 と Vnet2 はそれぞれ Hub と VNet Peering で接続されています。
  • vnet 1 には subnet 1 と subnet 2 、 vnet 2 には subnet 3 と subnet 4 があります。
  • 現時点では、Spoke の 4つの subnet は全て、Hub にある Azure Firewall を介して間が疎通できるよう UDR が構成されています。
  • UDR は、デフォルトルート(0.0.0.0/0)のような広いアドレス範囲を指定して、Azure Firewall を next hop に指定するような形で構成されています。デフォルトルートは極端な例としても、例えば相手先 VNet 全体(10.0.0.0/16 や 10.1.0.0/16)を指定するような形で UDR が構成されている場合も同様です。

この構成で subnet 1 と subnet 3 を Subnet Peering で接続するように構成し、それ以外の経路は変わらないようにしたいとします。

該当する制限事項 : 指定していない Subnet もルートを学習する

ドキュメント に 4. として記載の部分が、注意が必要かと思われる個所です。

  1. In the present release (feature remains behind subscription flag), forward route from non-peered subnet to peered subnet exists - In the current scenario virtual network A and virtual network B peering, even though Subnet 2 from virtual network A side isn't peered, but it will still have route for Subnet 1 and Subnet 2 in virtual network B.

現時点では、vnet-1 の全ての subnet が subnet 3 へのルーティングを学習し、同様に Vnet-2 全ての Subnet が subnet 1 へのルーティング を学習するという挙動になります。
つまり、subnet peering で接続されていない subnet2 も、subnet 3 へのルートを学習してしまう、ということです。

Subnet Peering 構成前後での ルート を記載しておきます。
Subnet Peering の対象としていない subnet 2 や subnet 4 でも、10.1.1.0/24 や 10.2.1.0/24 といったルートを学習していることがわかります。

Azure Cloud Shell - Subnet Peering 構成のコマンド(Subnet 1 と 3 のみ指定)
$ az network vnet peering create --name vnet-1_to_vnet-2 \
                               --resource-group test-rg \
                               --vnet-name vnet-1 \
                               --remote-vnet vnet-2 \
                               --allow-forwarded-traffic \
                               --allow-gateway-transit \
                               --allow-vnet-access \
                               --peer-complete-vnet false \
                               --local-subnet-names subnet-1 \
                               --remote-subnet-names subnet-3

$ az network vnet peering create --name vnet-2_to_vnet-1 \
                               --resource-group test-rg \
                               --vnet-name vnet-2 \
                               --remote-vnet vnet-1 \
                               --allow-forwarded-traffic \
                               --allow-gateway-transit \
                               --allow-vnet-access \
                               --peer-complete-vnet false \
                               --local-subnet-names subnet-3 \
                               --remote-subnet-names subnet-1
Azure Cloud Shell - Subnet Peering 構成前
$ az network nic show-effective-route-table -g test-rg -n test01472 -o table
$ az network nic show-effective-route-table -g test-rg -n test0280 -o table
$ az network nic show-effective-route-table -g test-rg -n test03370 -o table
$ az network nic show-effective-route-table -g test-rg -n test04819 -o table

# VNet1 - Subnet1
Source    State    Address Prefix    Next Hop Type     Next Hop IP
--------  -------  ----------------  ----------------  -------------
Default   Active   10.0.0.0/16       VnetLocal
Default   Active   10.10.0.0/16      VNetPeering
Default   Invalid  0.0.0.0/0         Internet
User      Active   0.0.0.0/0         VirtualAppliance  10.10.1.4

# VNet1 - Subnet2
Source    State    Address Prefix    Next Hop Type     Next Hop IP
--------  -------  ----------------  ----------------  -------------
Default   Active   10.0.3.0/24       VnetLocal
Default   Active   10.0.0.0/16       VnetLocal
Default   Active   10.10.0.0/16      VNetPeering
Default   Invalid  0.0.0.0/0         Internet
User      Active   0.0.0.0/0         VirtualAppliance  10.10.1.4

# VNet2 - Subnet3
Source    State    Address Prefix    Next Hop Type     Next Hop IP
--------  -------  ----------------  ----------------  -------------
Default   Active   10.1.0.0/16       VnetLocal
Default   Active   10.10.0.0/16      VNetPeering
Default   Invalid  0.0.0.0/0         Internet
User      Active   0.0.0.0/0         VirtualAppliance  10.10.1.4

# VNet2 - Subnet4
Source    State    Address Prefix    Next Hop Type     Next Hop IP
--------  -------  ----------------  ----------------  -------------
Default   Active   10.1.0.0/16       VnetLocal
Default   Active   10.10.0.0/16      VNetPeering
Default   Invalid  0.0.0.0/0         Internet
User      Active   0.0.0.0/0         VirtualAppliance  10.10.1.4
Azure Cloud Shell - Subnet Peering 構成後
$ az network nic show-effective-route-table -g test-rg -n test01472 -o table
$ az network nic show-effective-route-table -g test-rg -n test0280 -o table
$ az network nic show-effective-route-table -g test-rg -n test03370 -o table
$ az network nic show-effective-route-table -g test-rg -n test04819 -o table

# VNet1 - Subnet1
Source    State    Address Prefix    Next Hop Type     Next Hop IP
--------  -------  ----------------  ----------------  -------------
Default   Active   10.0.0.0/16       VnetLocal
Default   Active   10.10.0.0/16      VNetPeering
Default   Active   10.1.1.0/24       VNetPeering
Default   Invalid  0.0.0.0/0         Internet
User      Active   0.0.0.0/0         VirtualAppliance  10.10.1.4

# VNet1 - Subnet2
Source    State    Address Prefix    Next Hop Type     Next Hop IP
--------  -------  ----------------  ----------------  -------------
Default   Active   10.0.0.0/16       VnetLocal
Default   Active   10.10.0.0/16      VNetPeering
Default   Active   10.1.1.0/24       VNetPeering
Default   Invalid  0.0.0.0/0         Internet
User      Active   0.0.0.0/0         VirtualAppliance  10.10.1.4

# VNet2 - Subnet3
Source    State    Address Prefix    Next Hop Type     Next Hop IP
--------  -------  ----------------  ----------------  -------------
Default   Active   10.1.0.0/16       VnetLocal
Default   Active   10.10.0.0/16      VNetPeering
Default   Invalid  10.0.1.0/24       VNetPeering
Default   Invalid  0.0.0.0/0         Internet
User      Active   0.0.0.0/0         VirtualAppliance  10.10.1.4

# VNet2 - Subnet4
Source    State    Address Prefix    Next Hop Type     Next Hop IP
--------  -------  ----------------  ----------------  -------------
Default   Active   10.1.0.0/16       VnetLocal
Default   Active   10.10.0.0/16      VNetPeering
Default   Invalid  10.0.1.0/24       VNetPeering
Default   Invalid  0.0.0.0/0         Internet
User      Active   0.0.0.0/0         VirtualAppliance  10.10.1.4

影響 : 非対称ルーティングにより通信不可となる Subnet が出る可能性

この結果、非対称なルーティングとなって subnet 2 から subnet 3 への通信が不通になる可能性があります。
subnet 2 から subnet 3 への通信は、最長一致(longest match)により、UDR よりも具体的な subnet peering によって学習したルートが選択されます。
一方 subnet 3 は subnet 2 への経路を同様には学習していないため、 UDR に従って Azure Firewall 経由でのルートが選択されます。

実際に試した結果は以下ですが、疎通できていません。

vm02 から vm03 への ping
# subnet peering 構成前 vm02(subnet2) から vm03(subnet3) ping
vm02:~$ ping 10.1.1.4
PING 10.1.1.4 (10.1.1.4) 56(84) bytes of data.
64 bytes from 10.1.1.4: icmp_seq=1 ttl=63 time=3.46 ms
64 bytes from 10.1.1.4: icmp_seq=2 ttl=63 time=3.09 ms
64 bytes from 10.1.1.4: icmp_seq=3 ttl=63 time=3.55 ms
^C
--- 10.1.1.4 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2003ms
rtt min/avg/max/mdev = 3.089/3.363/3.545/0.197 ms

# subnet peering 構成後 vm02(subnet2) から vm03(subnet3) ping
vm02:~$ ping 10.1.1.4
PING 10.1.1.4 (10.1.1.4) 56(84) bytes of data.
^C
--- 10.1.1.4 ping statistics ---
11 packets transmitted, 0 received, 100% packet loss, time 10270ms

対応策 : UDR の調整

そのため Subnet 2 に紐づく UDR を調整し、subnet 3 を明示する形で通信を Azure Firewall 経由とするように構成する必要があります。
これにより、
subnet 1 と subnet 3 間の通信は、subnet peering 経由で実施され、
subnet 2 から subnet 3 への通信は、Azure Firewall 経由で通信する
といった構成になります。
同様に subnet 4 も、subnet 1 への通信を Azure Firewall 経由とするように UDR を調整する必要があります。

subnet2 の UDR を調整して ping 再試行
# subnet2 UDR 調整後、 vm02(subnet2) から vm03(subnet3) ping
vm02:~$ ping 10.1.1.4
PING 10.1.1.4 (10.1.1.4) 56(84) bytes of data.
64 bytes from 10.1.1.4: icmp_seq=1 ttl=63 time=5.25 ms
64 bytes from 10.1.1.4: icmp_seq=2 ttl=63 time=19.6 ms
64 bytes from 10.1.1.4: icmp_seq=3 ttl=63 time=2.88 ms
64 bytes from 10.1.1.4: icmp_seq=4 ttl=63 time=2.30 ms
^C
--- 10.1.1.4 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3004ms
rtt min/avg/max/mdev = 2.303/7.517/19.633/7.082 ms
vm02:~$ 

まとめ

VNet単位 や デフォルトルート などの広いアドレス空間を指定する形の UDR で Hub 経由の spoke 間通信を実現している場合、spoke 間での subnet peering を構成すると、通信不可となる subnet が出る可能性があることを記載しました。
subnet peering を設定することで、指定した Subnet 同士のみが相互疎通できる、というのは間違いないのですが、併せてピアリングされていない Subnet にはどういった影響があるのか意識しないとマズイこともある、という一例として注意いただければと思います。

なお、今回の内容は、 プレビュー機能 特有の制限である可能性があります。
GA 後には不要となる可能性もありますので、 GA 後にもこの注意点が残っているかは、改めて確認したいと思います。

参考: 今回の制限に該当せずとも、複数 Subnet で peering したい場合には同様に UDR の調整が必要かも

今回の例では、お互いのVNetから 1つずつ選んでピアリングしましたが、より多くの Subnet がある場合に、1:1 ではなく Subnet を 複数:複数 選んでピアリングも可能です。
ただし、Subnet 1 と Subnet 3 でのピアリング、Subnet 2 と Subnet 4 でのピアリング、といった構成にはなりません。指定した 複数:複数 が、相互に通信可能となります。
zukako さんの記事で紹介されている通りです。

そのため、もし Subnet 1 と Subnet 3、 Subnet 2 と Subnet 4 を通信させたいが、それ以外の Subnet は従来通り Hub 経由にしたい/または疎通させたくないといった場合には、今回ご紹介した UDR による制御や、NSGでの制御が必要になります。

他制限

今回は UDR を適切に、という部分を取り上げましたが、他にも以下のような制限があり、公式ドキュメントブログIsato-Hiyama さんの記事 など で紹介されています。

  • subnet peering に参加する サブネットは、固有である必要がある。つまり、相手先の VNet の サブネットと同じアドレス空間や、相手VNet が別VNet から学習済みの同一アドレス空間を持つサブネットを、 subnet peering することはできない。
  • 仮想ネットワーク間に存在できるピアリング リンクは 1 つだけ。 VNet peering と同時に利用することはできない。 Subnet peering を 2つ作るといったこともできない。
  • ピアリング リンクの一部にできるサブネットの数は、400 以下である必要がある (ローカル側とリモート側の各 200 の制限)
  • Hub - Spoke 間のピアリングを subnet peering とする場合、Gateway Subnet も含めて subnet peering しなければオンプレミス側と接続できない("Use remote gateway" を使う場合、GatewaySubnet を含めてピアリングする必要あり)

link

https://learn.microsoft.com/ja-jp/azure/virtual-network/how-to-configure-subnet-peering

https://blog.cloudtrooper.net/2024/10/01/azure-subnet-peering/?blogid=113559092&blogsub=confirming#subscribe-blog

https://qiita.com/Isato-Hiyama/items/29532de103892b433f74

https://zenn.dev/microsoft/articles/20241006-subnetpeering

Microsoft (有志)

Discussion