Azure VM の外部接続方式の違いにおける RTT を測定してみる

こんにちは、アーキテクトのやまぱんです。
補足コメントや質問、<font color="red">**いいね、拡散**</font>、是非お願いします🥺！
間違ってたら<font color="red">**優しく**</font>教えてください！

## きっかけ
以前下記のような記事を書きました

https://qiita.com/aktsmm/items/b33640d83c5d7b26bf85

どれくらいRTTに違いがあるのか気になって実際に測ってみました。

## はじめに ~RTT の測り方~
こちらの [参考記事](https://qiita.com/tokawa-ms/items/bf0784fd00cbe88d8663) に書かれているように、Azure VM の RTT を図るのに Ping を使用すべきではありません！（TCP に最適化されています、ping はICMP ですね)
以前の [OCI - Azure の専用線接続の検証](https://qiita.com/aktsmm/items/0f0f74770bc4196dda80#expressroute---fastconnect-%E7%B5%8C%E7%94%B1-%E3%81%A8-public-ip-%E7%B5%8C%E7%94%B1-%E3%81%AE-rtt-%E6%AF%94%E8%BC%83)では netperf を用いまいたが、今回は SockPerf を使います。

## SockPerf
下記の　MS Learn に記載のある方法で可能です。
参考までに、今回は Ubuntu をAzure Market Place からデプロイして使いました。
> ソース イメージ発行元 :Canonical
> ソース イメージ オファー:0001-com-ubuntu-server-focal
> ソース イメージ プラン:20_04-lts

https://learn.microsoft.com/ja-jp/azure/virtual-network/virtual-network-test-latency?tabs=linux#test-vms-with-latte-or-sockperf

:::note info
注意点としては上記の MS Learn を参考に実施し、autogen.shを実行した後にそのようなディレクトリは見つからないという旨の Error Message (``` ./configure --prefix=
bash: ./configure: No such file or directory ```)が出たので、下記コマンドを実行しました。
```bash:
sudo apt-get install autoconf
```
:::

一応 Ubuntu の場合のインストールコマンド載せておきます。

<details><summary> << Ubuntu の場合のインストールコマンド >></summary><div>
以下の手順でインストール可能


```bash
# VM 側の準備
#Ubuntu - Install Git and other helpful tools
sudo apt-get install autoconf
sudo apt-get install build-essential -y
sudo apt-get install git -y -q
sudo apt-get install -y autotools-dev
sudo apt-get install -y automake
sudo apt-get install -y autoconf
sudo apt-get install -y libtool
sudo apt update
sudo apt upgrade

# SockPerfをコピー、コンパイルおよびインストール
sudo su
#Bash - all distros

#From bash command line (assumes Git is installed)
git clone https://github.com/mellanox/sockperf
cd sockperf/
./autogen.sh
./configure --prefix=

#make is slow, may take several minutes
make

#make install is fast
sudo make install
```

</div>
</details>

ちなみに、SockPerf の開発元 **Mellanox (現在はNVIDIAに買収)** らしいです。
豆知識。

## SockPerf 使い方
+ サーバー側の例) サーバの Private IP が 10.0.0.4 の時
```
#Server/Receiver for IP 10.0.0.4:
sudo sockperf sr --tcp -i 10.0.0.4 -p 12345
```

+ Client 側の例)
```
#Client/Sender for IP 10.0.0.4:
sockperf ping-pong -i 10.0.0.4 --tcp -m 350 -t 101 -p 12345 --full-rtt
```
(Global IP 向けの場合はもちろん Global IP 向けにすること)


## 各接続方式における RTT 比較
+ 今回クライアント側のAzure VM を東日本リージョン(japaneast)、サーバー側のAzure VM を南アフリカのリージョンヨハネスブルク(southafricanorth) に設置しました。
+ Azure VM の SKU はすべて **Standard B2s** です。Azure VM の場合 VM 自体のSKU に通信処理速度が依存するので合わせています。
+ すべて 単体です。Public IP、既定の SNAT はもちろんですが、NATGW を利用している VM も、Azure Firewall も、外部ロードバランサーもすべて一台が利用している状態です。

なお、結果は一部抜粋です。

### 既定のSNAT
+ 実行前の Public IP 確認 ```curl https://inet-ip.info ```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2982508/6110e4d3-211c-406e-0f68-4e9b2a5b1b1d.png)
+ Azure Portal でも確認
既定の SNAT の IPアドレスは Azure Portal からは確認できないため Azure Portal の画面ショットはなし。
 なお、[既定のSNATは廃止予定](https://jpaztech.github.io/blog/network/default-outbound-access-for-vms-will-be-retired/)です。

```
sockperf: [Valid Duration] RunTime=100.085 sec; SentMessages=261; ReceivedMessages=261
sockperf: ====> avg-rtt=383460.308 (std-dev=659.343, mean-ad=379.382, median-ad=318.029, siqr=233.741, cv=0.002, std-error=40.812, 99.0% ci=[383355.182, 383565.434])
sockperf: # dropped messages = 0; # duplicated messages = 0; # out-of-order messages = 0
sockperf: Summary: Round trip is 383460.308 usec
sockperf: Total 261 observations; each percentile contains 2.61 observations
sockperf: ---> <MAX> observation = 390394.628
sockperf: ---> percentile 99.900 = 390394.628
sockperf: ---> percentile 99.000 = 385171.272
sockperf: ---> percentile 90.000 = 383977.743
sockperf: ---> percentile 75.000 = 383582.147
sockperf: ---> percentile 50.000 = 383300.799
sockperf: ---> percentile 25.000 = 383114.665
sockperf: ---> <MIN> observation = 382767.135
```

### Public IP 
+ 実行前の Public IP 確認 ```curl https://inet-ip.info ```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2982508/ea6df535-9335-aecb-559f-26131ff6b320.png)
+ Azure Portal でも確認
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2982508/5423c6c3-d6fd-d52a-6e4c-add08ba9ce6e.png)

```
sockperf: [Valid Duration] RunTime=99.880 sec; SentMessages=261; ReceivedMessages=261
sockperf: ====> avg-rtt=382677.430 (std-dev=621.476, mean-ad=393.833, median-ad=347.297, siqr=248.766, cv=0.002, std-error=38.468, 99.0% ci=[382578.342, 382776.518])
sockperf: # dropped messages = 0; # duplicated messages = 0; # out-of-order messages = 0
sockperf: Summary: Round trip is 382677.430 usec
sockperf: Total 261 observations; each percentile contains 2.61 observations
sockperf: ---> <MAX> observation = 386769.649
sockperf: ---> percentile 99.900 = 386769.649
sockperf: ---> percentile 99.000 = 385135.128
sockperf: ---> percentile 90.000 = 383291.989
sockperf: ---> percentile 75.000 = 382803.959
sockperf: ---> percentile 50.000 = 382525.008
sockperf: ---> percentile 25.000 = 382306.426
sockperf: ---> <MIN> observation = 381988.746

```


### 外部ロードバランサーの送信規則
+ 実行前の Public IP 確認 ```curl https://inet-ip.info ```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2982508/5a75a24c-de65-76b7-2935-eddd6ec55a78.png)

+ Azure Portal でも確認
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2982508/422266cd-919c-7943-aa00-f59289cfa407.png)

```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2982508/c3dca9ae-3b52-88eb-9c75-30ef6f8f5ec6.png)
sockperf: [Valid Duration] RunTime=99.915 sec; SentMessages=259; ReceivedMessages=259
sockperf: ====> avg-rtt=385770.944 (std-dev=593.303, mean-ad=329.455, median-ad=279.072, siqr=194.790, cv=0.002, std-error=36.866, 99.0% ci=[385675.983, 385865.905])
sockperf: # dropped messages = 0; # duplicated messages = 0; # out-of-order messages = 0
sockperf: Summary: Round trip is 385770.944 usec
sockperf: Total 259 observations; each percentile contains 2.59 observations
sockperf: ---> <MAX> observation = 392620.433
sockperf: ---> percentile 99.900 = 392620.433
sockperf: ---> percentile 99.000 = 387222.430
sockperf: ---> percentile 90.000 = 386284.741
sockperf: ---> percentile 75.000 = 385862.065
sockperf: ---> percentile 50.000 = 385642.328
sockperf: ---> percentile 25.000 = 385472.483
sockperf: ---> <MIN> observation = 385127.088

```

### NATGW
+ 実行前の Public IP 確認 ```curl https://inet-ip.info ```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2982508/c41c84a6-97f2-74b3-2e75-dad89b78ae8a.png)

+ Azure Portal でも確認
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2982508/b8f29796-63cc-8cf9-6c4d-097154ba2319.png)

```
sockperf: [Valid Duration] RunTime=100.108 sec; SentMessages=260; ReceivedMessages=260
sockperf: ====> avg-rtt=385027.305 (std-dev=976.902, mean-ad=385.414, median-ad=318.453, siqr=214.823, cv=0.003, std-error=60.585, 99.0% ci=[384871.248, 385183.362])
sockperf: # dropped messages = 0; # duplicated messages = 0; # out-of-order messages = 0
sockperf: Summary: Round trip is 385027.305 usec
sockperf: Total 260 observations; each percentile contains 2.60 observations
sockperf: ---> <MAX> observation = 398506.853
sockperf: ---> percentile 99.900 = 398506.853
sockperf: ---> percentile 99.000 = 386800.495
sockperf: ---> percentile 90.000 = 385466.217
sockperf: ---> percentile 75.000 = 385108.863
sockperf: ---> percentile 50.000 = 384864.144
sockperf: ---> percentile 25.000 = 384679.216
sockperf: ---> <MIN> observation = 384332.180
```

### Azure Firewall の SNAT
+ 実行前の Public IP 確認 ```curl https://inet-ip.info ```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2982508/e1a45f35-82c3-2ab4-c749-5652aa176815.png)

+ Azure Portal でも確認
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2982508/b03d49b8-5f78-60d9-20de-cb7d4ecb6221.png)

```
sockperf: [Valid Duration] RunTime=100.081 sec; SentMessages=258; ReceivedMessages=258
sockperf: ====> avg-rtt=387909.824 (std-dev=37282.025, mean-ad=5646.802, median-ad=583.452, siqr=440.960, cv=0.096, std-error=2321.077, 99.0% ci=[381931.116, 393888.532])
sockperf: # dropped messages = 0; # duplicated messages = 0; # out-of-order messages = 0
sockperf: Summary: Round trip is 387909.824 usec
sockperf: Total 258 observations; each percentile contains 2.58 observations
sockperf: ---> <MAX> observation = 975994.156
sockperf: ---> percentile 99.900 = 975994.156
sockperf: ---> percentile 99.000 = 400546.401
sockperf: ---> percentile 90.000 = 385879.797
sockperf: ---> percentile 75.000 = 385403.430
sockperf: ---> percentile 50.000 = 384849.965
sockperf: ---> percentile 25.000 = 384521.510
sockperf: ---> <MIN> observation = 383961.904
```

## 結果 サマリ表
### 各接続方式におけるRTT計測結果 サマリ表

| 接続方式                | 平均RTT (μs)    | 最大RTT (μs)      | 最小RTT (μs)      | 99パーセンタイル (μs)  |
|-------------------------|-----------------|-------------------|-------------------|-----------------------|
| 既定のSNAT             | 383,460.308     | 390,394.628       | 382,767.135       | 385,171.272           |
| Public IP              | 382,677.430     | 386,769.649       | 381,988.746       | 385,135.128           |
| 外部ロードバランサー    | 385,770.944     | 392,620.433       | 385,127.088       | 387,222.430           |
| NATGW                  | 385,027.305     | 398,506.853       | 384,332.180       | 386,800.495           |
| Azure FirewallのSNAT   | 387,909.824     | 975,994.156       | 383,961.904       | 400,546.401           |

### 評価
結果、平均 RTT はほとんど変わらなかったが Azure Firewall は一部遅い通信が混じったため最大 RTT が目立った。

**下記はGPT が 作成したもの** なので、あくまで参考程度にしてください😯

>- **既定のSNAT:**
> 平均RTTは中程度であり、比較的安定したパフォーマンスを示しています。
>
>- **Public IP:**
> 平均RTTが最も低く、RTTのばらつきも少ないため、効率的で安定した接続方式と言えます。
>
>- **外部ロードバランサーの送信規則:**
> 平均RTTはやや高めですが、非常に安定したパフォーマンスを提供します。>
>
>- **NATGW:**
> 平均RTTは他の方式と比較してやや高めで、パフォーマンスのばらつきが見られます。
>
>- **Azure FirewallのSNAT:**
>平均RTTは他の方式より高めですが、特定の状況で大きな遅延が発生する場合があるものの、全体的な安定性には大きな影響は見られません。
> Azure Firewallは、特定のセキュリティ要件を満たすために多機能であり、有用な選択肢です。特定の用途や環境に構成に応じて、各方式を適切に選択することが重要です。
>

## おわりに
あくまで今回の環境下で実施した場合の一例です。
 Azure はそもそもマルチテナント型のサービスなので、単独のユーザーが条件を完全に合わせることはできないです。他のユーザーやワークロード、アップデートなどの影響を受けてパフォーマンスは微妙にだけど常に変化しているからです。

あくまで参考程度にしていただければと思います。


+ 条件 （再掲)
> + イメージ再掲
> ソース イメージ発行元 :Canonical
> ソース イメージ オファー:0001-com-ubuntu-server-focal
> ソース イメージ プラン:20_04-lts
> + 今回クライアント側のAzure VM を東日本リージョン(japaneast)、サーバー側のAzure VM を南アフリカのリージョンヨハネスブルク(southafricanorth) に設置しました。
> + Azure VM の SKU はすべて **Standard B2s** です。Azure VM の場合 VM 自体のSKU に通信処理速度が依存するので合わせています。
> + すべて 単体です。Public IP、既定の SNAT はもちろんですが、NATGW を利用している VM も、Azure Firewall も、外部ロードバランサーもすべて一台が利用している状態です。

## 参考

https://qiita.com/tokawa-ms/items/bf0784fd00cbe88d8663

https://jpaztech.github.io/blog/network/default-outbound-access-for-vms-will-be-retired/

https://learn.microsoft.com/ja-jp/azure/virtual-network/virtual-network-test-latency?tabs=linux#test-vms-with-latte-or-sockperf