IoTシステムの開発において、避けて通れないのが「数千台規模の同時接続テスト」です。
ただ、実際に数千台のデバイスを用意したり、VMを大量に並べたりするのはコストも管理工数もかかりすぎます。
そこで今回は、Azure VM わずか1台(+サーバー1台)で、1,000個の独立したプライベートIPを使ってサーバーへ同時接続する、格安かつ強力なシミュレーター環境を構築してみました。
1. アーキテクチャ構成
今回は1台のVMに複数のNICを装着し、各NICに大量のセカンダリIPを割り当てる構成にしています。
(4つのNICに250個ずつIPを分散させます)
使用リソース一覧
管理をシンプルにするため、同一のリソースグループ(rg-iot-sim)内に全リソースを集約します。

2. ネットワーク設計
1,000個のIPを効率よく管理するため、4つのサブネットに分散させます。
・VNet アドレス空間 :10.0.0.0/16
・snet-iot-0 (NIC-0 & Server) :10.0.0.0/24(Client: 10.0.0.4〜.253 / Server: .254)
・snet-iot-1 (NIC-1) 10.0.1.0/24:(Client: 10.0.1.4〜.253)
・snet-iot-2 (NIC-2) 10.0.2.0/24:(Client: 10.0.2.4〜.253)
・snet-iot-3 (NIC-3) 10.0.3.0/24:(Client: 10.0.3.4〜.253)
3. 構築ステップ
構築は大きく分けて4つのフェーズで進めます。
【STEP 1】インフラ基盤の作成(Azure CLI)
まずは土台となるネットワークとVMを作成します。(前述の使用リソース一覧参照)
• VNet/Subnet作成: 4つのサブネットを用意します。
• NSG作成: SSHおよびサーバー通信用ポート(待ち受けるポート例:8888)を許可します。
• VM作成: クライアント用にはNICを4枚装着可能な Standard_D8als_v6 を選択。サーバー用には Standard_D2s_v3 を用意します。(OSは今回どちらもUbuntu 22.04を使用)
o 参考:Dals v6 シリーズのネットワーク仕様(Microsoft Learn)
【STEP 2】1,000個のIPをAzure側に自動追加
各NICに対し、セカンダリIPを250個ずつ追加していきます。Azure APIの制限(スロットリング)を回避するため、–no-wait オプションと適度な sleep を組み合わせて実行します。
|
1 2 3 4 5 6 |
# 例:NIC-0に対して250個のIP構成を順次追加 for j in {5..253}; do az network nic ip-config create -g rg-iot-sim --nic-name nic-client-0 \ --name ip-0-$j --private-ip-address 10.0.0.$j --no-wait if (( $j % 25 == 0 )); then sleep 2; fi done |
※ 同様の処理を nic-client-1 ~ nic-client-3 に対しても行います。.4はNIC作成段階で割り当て指定済のため追加で{5..253}の範囲の設定を行う(以降も同様)。
実行に多少時間がかかりますが、以下のAzureポータル画面を更新して見ると追加されていくことが確認できます。

【STEP 3】Ubuntu側のネットワーク設定(Policy Based Routing)
Azure側でIPを付与しただけではOSは認識しないため、ここからはクライアント側のVMにログインして、Policy Based Routing(ポリシーベースルーティング / PBR)の設定を行います。
1. Netplanの設定
Netplanは、Ubuntuでネットワーク設定を抽象化して管理するツールです。今回は、追加した3つのNIC(eth1-3)が勝手にデフォルトルートを作って通信を混乱させないよう制御します。
|
1 2 3 4 5 6 7 8 |
# /etc/netplan/99-iot-multi-nic.yaml の例 network: version: 2 ethernets: eth0: {dhcp4: true} eth1: {dhcp4: true, dhcp4-overrides: {use-routes: false}} eth2: {dhcp4: true, dhcp4-overrides: {use-routes: false}} eth3: {dhcp4: true, dhcp4-overrides: {use-routes: false}} |
2. IPアドレスの有効化
Azure側で定義したセカンダリIPをOSのインターフェースに紐付けます。
|
1 2 3 4 5 |
# 例:NIC-1 (eth1) に 250個のIPを一括登録 i=1 for j in {5..253}; do sudo ip addr add 10.0.$i.$j/24 dev eth$i done |
※ 同様の処理を eth2 ~ eth3 に対しても行います。
3. PBR(ポリシーベースルーティング)の設定
通常のルーティングでは、パケットは「宛先」だけを見て出口を決めます。しかしマルチNIC構成では「どのIPから送るか(送信元)」に基づいて出口のNICを固定しないと、通信のやり取り(コネクション)が成立しなくなります。これを実現するのがPBRです。
|
1 2 3 4 5 6 7 8 9 10 |
# 例:NIC-1 (eth1) 用のPBR設定(i=2, 3も同様に設定) i=1 # ルーティングテーブルのID(101)と名前(rt1)を紐付けて管理ファイルに登録 sudo bash -c "echo '10$i rt$i' >> /etc/iproute2/rt_tables" # 登録した名前「rt1」のテーブルに、このNIC専用のデフォルトゲートウェイを登録 sudo ip route add default via 10.0.$i.1 dev eth$i table rt$i # 送信元が 10.0.1.0/24 のパケットは、必ず rt1 テーブルを参照させるルールを追加 sudo ip rule add from 10.0.$i.0/24 table rt$i |
※ 同様の処理を eth2 ~ eth3 に対しても行います。
設定を確認

【STEP 4】システム制限の解除
デフォルトのOS設定では、1,000以上の同時接続(ソケットオープン)を維持しようとすると「Too many open files」エラーが発生します。ファイルディスクリプタの上限を引き上げましょう。
|
1 2 3 4 5 6 7 8 |
# OS制限の引き上げ(永続化設定) sudo bash -c 'cat << EOF >> /etc/security/limits.conf * soft nofile 65535 * hard nofile 65535 EOF' # 現在のセッションにも適用 ulimit -n 65535 |
4. 動作検証:1,000接続の確認
準備ができたら、サーバー側プログラムを立ち上げ、いよいよ実際にシミュレータープログラムを動かします。
動作概要
• クライアント側: 1,000個のローカルIPアドレスそれぞれに対して socket.bind() を行い、明示的に送信元IPを指定してサーバーへ接続。

• サーバー側: 指定ポート(8888)で待ち受け、接続元IPアドレスをログ出力しながら総接続数をカウントするプログラム。

・・・

「1台のVMから、1,000の異なる送信元IPで同時接続する」という、擬似デバイスシミュレーターとしての挙動を確認できました!
5. まとめ
今回の手法を使えば、わずか1時間100円程度(VM、パブリックIP、ディスク利用料の合計)という低コストで、1,000台規模のデバイス負荷試験環境が手に入ります。
今回の構築における重要なポイントを整理すると、以下の3点に集約されます。
• プライベートIPは無料というクラウドの利点を活かす。
• マルチNICとPBRを組み合わせ、OSレベルで通信を制御する。
• CLIによる実行で構築の手間を大幅に省く。
1,000台のVMを個別に立てるコストと比較すれば、手軽で効率的です。
IoT開発の現場で、予算を気にせず「まずは1,000台で叩いてみる」という文化を作るための第一歩として、ぜひ活用してみてください!
エコモットでは、ともに未来の常識を創る仲間を募集しています。
IoTに少しでも興味がある方はぜひ下記の採用ページをご覧ください!




