LoginSignup
0

posted at

updated at

Organization

Ubuntuを使いネットワークエミュレータの作成をする

はじめに

この記事は、私、大阪国際工科専門職大学 、情報工学科、2年のuroketa(本名は伏せます)が、大学のカリキュラムで、iPresence合同会社 の企業内で実習に臨まさせて頂いた時に作成したものです。
今回は、展示会場などの不安定なインターネット回線を再現するために、Ubuntuをネットワークエミュレータ代わりにし、ネットワークエミュレータを介してtemi(テレプレゼンスロボット)(今回はRICOH THETAもドッキング)に信号を送るエミュレートを行いました。
スクリーンショット (235).png

☆注意!

今回ネットワークエミュレータとして使っているUbuntuのバージョンは、Ubuntu18.04です。
また、使用するUbuntuのLANポートが1つの場合、USB変換端子が必要になります。
そして、WiFi➁はブリッジモードで起動してください!

☆Ubuntuにネットワークエミュレータの機能を設定

➀UbuntuとWindowsPCをSSH接続し、LINUXにログインする。

teratarmなどのソフトを使い、WindowsPCからSSH接続でLINUXと接続、Ubuntuにログインし、コマンドを打ち込むための準備をします。(キーボードなどをUbuntuに接続できる場合はSSH接続せずに直接コマンドを打ち込むことも可能ですが。)

➁Ubuntuにブリッジを作成するためのツールをインストールする

LINUX機をネットワークエミュレータ代わりにするには、Ubuntuをブリッジ化(スイッチングハブのような役割)にする必要があります。そのために、まず、aptコマンドで、

sudo apt install bridge-utils

と入力し、ブリッジを作成するためのツール (bridge-utils) をインストールします。
ここで注意してほしいのが、先頭の「sudo」というコマンドです。この「sudo」は、スーパーユーザー(管理者、rootユーザー)」の権限が必要なコマンドを実行することが出来るコマンドで、今後、先頭に「sudo」と書かれたコマンドが出てきますが、それらは全てスーパーユーザーの権限が必要なコマンドだということを理解しておいてください。

➂IPアドレスを削除、固定IPを追加etc..する処理を書くための場所を作成する

Ubuntuブリッジ化するためには、難しい話になりますが、ネットワークインタフェース(以下LANポート)のIPアドレスを削除し、ブリッジに固定IPを追加した後にブリッジ、LANポートを起動する必要があります。(理由は置いておいて)
ここで登場! するのが「shell script(シェルスクリプト)」です。作成したshell scriptファイルを実行することで、shellscriptファイル内に記述された処理が実行されます。

shellscriptファイルを新規作成したい時は、

sudo vi ~/.ファイル名.sh

と入力して下さい。また作成したファイルを編集したい時は、

sudo vi ファイル名.sh

と入力すればOKです。(間違えて別ファイルを新規作成しないように!)
そして、編集したshellscriptファイルを保存&編集画面から抜け出したい時は、

:wq

と入力すればOKです。また、編集画面は開いたが、編集はしなかった時などは、

:q!

と入力すれば、保存せずに終了も出来ます。そして、作成したshellscriptファイルは、

sudo ファイル名.sh

で実行できます。(ややこしい!)

➃shellscript内の処理を記述

shellscript内には、LANポートのIPアドレスを削除し、ブリッジに固定IPアドレスを設定する処理、更にLANポートとブリッジをを起動し、使用可能状態にする処理を記述します。以下をshellscript内に記述します。

#shellscript上でbridge-utilsツールを使用可能にする
BRCTL=/sbin/brctl 

#shellscript上でIPツールを使用可能にする
IP=/sbin/ip

#ブリッジの変数を作成
BRIDGE=ブリッジ名

#ブリッジに設定したい固定IPアドレスの変数を作成
IP_ADD=○○○.○○○.○.○/24

#for文用にLANポート名をに文字列で記述する変数を作成
NICS="LANポート名➀ LANポート名➁" 

#ブリッジに固定IPアドレスを設定
$IP addr add $IP_ADD dev $BRIDGE

#ループ処理($NICにLANポート名を割り振る)
for NIC in $NICS;
do
    $IP addr flush dev $NIC            #LANポートのIPアドレスを削除
    $BRCTL addif $BRIDG $NIC           #ブリッジにLANポートを認識させる
    $IP link set dev $NIC promisc on   #LANポートをプロミスキャスモードで起動
    $IP link set dev $NIC up           #LANポートを起動
done

#ブリッジを起動
$IP link set dev $BRIDG up

ここで注意! してほしいのが、「$」という記号です。変数の前に$と書くことで、その位置に、変数の中の数字が反映されます。(なので、上のコードで言うと、ブリッジ名がbr0だとすると、$BRIDGEとbr0は同じ意味になります。)

これで、作成したshellscriptを実行することで、➃の題名の下に書いた処理が実行され、いつでも遅延やパケロス、帯域制限をかけることができる状態になりました!

➄bashrcを使い、各種通信制限を加える処理を関数化して保存する場所を作成する。

➄の題名に書いているような遅延、パケロス、帯域制限の処理を (➃内のコードも含めて)1行1行コマンドを入力していってもいいのですが、それだとかなりの時間を使ってしまいます。なので、今回は、各種通信制限(遅延、パケロス、帯域制限)を発生させる処理をそれぞれ関数化し、それらを呼び出して引数を渡すだけで実行できるようにしました。
ここで登場! するのが「bashrc」です。bashrcはshellscriptと違い、PCが起動すると同時にbashrc内の処理を実行させることが出来ます。(なので起動後には既に作成した関数を呼び出せる状況になっています)

bashrcファイルを新規作成(初回)&編集したい時は、

sudo vi ~/.bashrc

と入力すればOKです。編集したbashrcファイルを保存&bashrc編集画面から抜け出したい時は、

:wq

と入力してください。こちらも、保存せずに終了したい時は、shellscriptと同じように、

:q!

と入力すればOKです。また、編集後、PCを再起動すれば編集した内容が反映されるのですが、毎回毎回編集後に再起動するのはかなりの時間ロス!....... そんな時は:wqでbashrcを保存&終了した後に、

bash

と入力しましょう。編集した内容が反映され、編集後のコードが使用可能な状態になります。

➅bashrc内の処理を記述

ここで、遂にbashrc内で遅延、パケロス、帯域制限の機能を関数化して記述する時がやってきました。また、ネットワークエミュレータの機能だけでなく、各通信制限をかけたLANポートの制限状態を解除する処理、それぞれインタフェースの状態を確認できる処理を関数化しておくと便利なので追加しておくことにします。
以下がbashrc内に記述したコードになります。

 #遅延処理
 #$1→遅延を加えたいLANポート名
 #$2→遅延をかけたい時間(s)(1000s=1秒)

tc_delay(){
sudo tc qdisc add dev $1 root netem delay $2
}

 #帯域制限処理
 #$1→帯域制限をかけたいLANポート名(Kb→bはByte!bitではない)
 #$2→データキューのサイズ(Kb)
 #$3→バケツのサイズ(Kb)
 #$4→トークン補充速度(帯域幅)(Kb)

tc_thpt(){
sudo tc qdisc add dev $1 root tbf limit $2 buffer $3 rate $4
}

 #パケロス処理
 #$1→パケロスを発生させたいLANポート名
 #$2→何%パケロスさせるか(%)を

tc_pkloss(){
sudo tc qdisc add dev $1 root netem loss $2
}

 #通信制限解除処理
 #$1→制限を解除したいLANポート名

tc_delete(){
sudo tc qdisc del dev $1 root
}

 #LANポート名の状態確認処理
 #$1→状態を確認したいLANポート名

tc_show(){
sudo ts -s qdisc show dev $1
}

これで、やっと全てのコードの記述が終わりました。(お疲れ様です!)
これからは、前にも書いた通り関数を呼び出して引数を決めればすぐに実行できるので楽です。
ここで注意! 関数を呼び出す前に、必ず作ったshellscriptを実行してください。

さらに注意! 通信の方向によって、制限をかけるLANポートは変わります。
今回の実験の場合だと、temi→PCへの信号に制限をかけたい場合はLANポート➀、PC→temiへの信号に制限をかけたい場合はLANポート➁を引数として与えました。

例えば、LANポート➀に3秒の遅延(temi→PCへの通信に3秒の遅延)を加えたい場合は、

tc_delay LANポート➀ 3000s 

と入力します。その他関数も引数に当てはまる値を与えて呼び出すことで実行できます。

☆検証内容

PC→temiはその場回転の信号を送ってからのtemiの反応やtemiに映るPCカメラの映像、temi→PCの場合はPCに映るtemiカメラの映像を観察しました。また、結果を数値的にも確認するため、遅延はpingを使ってPC⇔temi間の発信から返信までの時間、パケロスはpingを使い、PC→temiはそのまま、temi→PCへの通信は、結果を計測するためにWiFi➁に繋いだPC➁を用意し、temi代わりとして損失を計測、帯域制限も同じくWiFi➁と接続したPC➁を用意し、temi代わりとして、iperf3を使用して確認しました。また、それぞれの検証を終えるたびに、通信制限を解除し、次の検証に進みました。

何故temi代わりのPCを用意するのか?

temi側からpingを送る手段がないので、temi→PCの通信の結果を数値で表す手段がないから。

☆エミュレート結果

まず、何も通信制限をかけなかった時のPC→temiのping通信は

192.168.3.75 の ping 統計:
  パケット数: 送信 = 4、受信 = 4、損失 = 0 (0% の損失)、
ラウンド トリップの概算時間 (ミリ秒):
  最小 = 43ms、最大 = 970ms、平均 = 427ms

となりました。そして、temi代わりのPC➁(WiFi➁に接続)→PCのping通信は、

192.168.3.41 の ping 統計:
  パケット数: 送信 = 4、受信 = 4、損失 = 0 (0% の損失)、
ラウンド トリップの概算時間 (ミリ秒):
  最小 = 4ms、最大 = 270ms、平均 = 71ms    

となりました。

➀遅延の確認

tc_deley LANポート名➀ 1000ms
tc_deley LANポート名➁ 1000ms

と入力し、pingによる測定結果は、

 192.168.3.75 の ping 統計:
  パケット数: 送信 = 4、受信 = 4、損失 = 0 (0% の損失)、
ラウンド トリップの概算時間 (ミリ秒):
  最小 = 2003ms、最大 = 2421ms、平均 = 2138ms

となりました。また、その他にも
・その場回転の指示をtemiに送ってからtemiが回転するまでの時間に遅延が発生
・temiカメラの前で手をグーからパーにしてから約PCに映像が反映されるまでの時間に遅延が発生
といった結果が得られました。

➁パケロスの確認

tc_pkloss LANポート名➀ 50%
tc_pkloss LANポート名➁ 50%

と入力し、pingによる測定結果は、

192.168.3.75 の ping 統計:(PC→temiの通信)
  パケット数: 送信 = 4、受信 = 2、損失 = 2 (50% の損失)、
ラウンド トリップの概算時間 (ミリ秒):
  最小 = 3ms、最大 = 457ms、平均 = 230ms

192.168.3.41 の ping 統計:(tmmi代わりのPC➁→PC)
  パケット数: 送信 = 4、受信 = 2、損失 = 2 (50% の損失)、
ラウンド トリップの概算時間 (ミリ秒):
  最小 = 8ms、最大 = 8ms、平均 = 8ms

となりました。また、その他にも、
・画質がかなり悪くなる
・コマ送りのような映像になる
・PC⇔temi間の通信で遅延は確認されなかった
といった結果が得られました。

➂帯域制限(throughput)の確認

tc_thpt ポート名➀ 10Mbit 5Mbit 10Mbit 
tc_thpt ポート名➁ 10Mbit 5Mbit 10Mbit

と入力し、iPerfによる測定結果(PC間)は、

通常
[ ID] Interval           Transfer     Bandwidth
[  5]   0.00-10.09  sec  0.00 Bytes  0.00 bits/sec            sender
[  5]   0.00-10.09  sec  40.9 MBytes  34.0 Mbits/sec        receiver 

帯域制限を掛けた結果([5]がPC側から通信、[4]がtemi代わりのPCから通信)
[ ID] Interval           Transfer     Bandwidth
[  5]   0.00-10.20  sec  0.00 Bytes  0.00 bits/sec            sender
[  5]   0.00-10.20  sec  12.1 MBytes  9.94 Mbits/sec        receiver

[ ID] Interval           Transfer     Bandwidth
[  4]   0.00-10.01  sec  11.5 MBytes  9.64 Mbits/sec          sender
[  4]   0.00-10.01  sec  11.4 MBytes  9.52 Mbits/sec        receiver

となりました。また、その他にも、
・PC⇔temi間の通信で遅延が発生
・PCに表示されるtemiカメラの映像、temiお互いの映像の画質が荒くなる
といった結果が得られました。

さいごに

上の記事は同じ実習仲間が作成した同じ内容の記事です。この記事より簡略化されて書かれているのでこの記事が分かりずらかったら上の記事を参考にしてみてください笑。

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
What you can do with signing up
0