panda's tech note

Linux Network Namespace

Linux namespace (netns)を使うことで,Linux OS上のネットワークリソース(インターフェイスやルーティングテーブル)を名前空間で分離することができます。例えば,下図のような2つのインターフェイス構成のLinuxマシンを仮定すると,2インターフェイス間の通信は内部ルーティング(Internal routing)が優先され,外部リンク(External link)を使用することができませんが,netnsを用いることで,内部ルーティングからインターフェイスを分離することができ,外部リンクを使用できるようになります。iperfなどでNICのパフォーマンスを計測する時に非常に便利です。

+--------------+
| Host      +------+ 192.168.0.1/24
|           | eth0 |<----+
|           +------+     |
|     Internal ^         | External
|      routing |         | link
|              v         |
|           +------+     |
|           | eth1 |<----+
|           +------+ 192.168.0.2/24
+--------------+

2つのインターフェイス間の外部リンクを使った通信をするためには,それぞれのインターフェイスを異なるnamespaceに割り当てます。例えば,下図の通り,eth0eth1をそれぞれnet0net1というnamespaceで分離します。

+--------------+
| Host         |
| +- net0 -----------+
| |         +------+ 192.168.0.1/24
| |         | eth0 |<----+
| |         +------+ |   |
| +------------------+   |
|              |         | External link
| +- net1 -----------+   |
| |         +------+ |   |
| |         | eth1 |<----+
| |         +------+ 192.168.0.2/24
| +------------------+
+--------------+

以下の手順で上図を実現できます。

  1. Namespace net0 および net1 を作成します
# ip netns add net0
# ip netns add net1
  1. インターフェイス eth0 および eth1 をそれぞれ net0 および net1 に割り当てます
# ip link set dev eth0 netns net0
# ip link set dev eth1 netns net1
  1. それぞれのインターフェイスをリンクアップします
# ip netns exec net0 ip link set eth0 up
# ip netns exec net1 ip link set eth1 up
  1. IPアドレスを設定します
# ip netns exec net0 ip a add 192.168.0.1/24 dev eth0
# ip netns exec net1 ip a add 192.168.0.2/24 dev eth1
  1. 最後に,以下のように特定のnamespace上でコマンドを実行することができます。以下のコマンドでは net1 上で 192.168.0.1 への ping を実行しています。このとき 192.168.0.1net1 の名前空間上では同一名前空間にない同一リンクアドレスなので,外部リンクが使用されます。
# ip netns exec net1 ping 192.168.0.1