Linux Network Namespace (netns) を使って手軽に VXLAN の P2P 通信を試す

# 環境
以下のような VXLAN ネットワークを作ります．

```
Underlay: 192.168.10.0/24
Overlay:  10.0.1.0/24
    ___________________       ___________________
   |  host1            |     |  host2            |
   |    ___________    |     |    ___________    |
   |   | netns1    |   |     |   | netns2    |   |
   |   |           |   |     |   |           |   |
   |   |   _____   |   |     |   |   _____   |   |
   |   |__|VXLAN|__|   |     |   |__|VXLAN|__|   |
   |      |_____|      |     |      |_____|      |
   | 10.0.1.1:   ____  |     | 10.0.1.2:   ____  | 
   |_________:__|p1p1|_|     |_________:__|p1p1|_|
             :  |____|192.168.10.7     :  |____|192.168.10.8
  ___________:_____|___________________:_____|_______________
             :.........................:
```

# koko
https://github.com/redhat-nfvpe/koko
P2P のコンテナ間接続を簡単に構築してくれる便利なツールです．
Linux Network Namespace (netns) または Docker コンテナを，veth / VXLAN / VLAN / macvlan で接続することができます．
同じ環境を ip コマンド等で構築するのもそこまで難しくないですが，今回は koko を使用しました．

## インストール
koko は go でインストールできます．
golang が入っていない人は [公式サイト](https://golang.org/doc/install) からダウンロードしましょう．

```
# golang (例)
$ wget https://dl.google.com/go/go1.11.linux-amd64.tar.gz
$ sudo tar -C /usr/local -xzf go1.11.linux-amd64.tar.gz
$ echo 'export GOPATH=$HOME/.golang' >> $HOME/.profile
$ echo 'export PATH=$PATH:$GOPATH/bin:/usr/local/go/bin' >> $HOME/.profile

# koko
$ go get github.com/redhat-nfvpe/koko
```

# 構築
では構築していきましょう．2 台の物理マシンそれぞれでコマンドを入力します．

## host1
`ip netns` で Network Namespace を作成した後，koko のコマンドを叩きます．
VXLAN ID は 10 としました．

```
$ sudo ip netns add netns1
$ sudo ip netns exec netns1 ip link set lo up
$ sudo $GOPATH/bin/koko -n netns1,veth0,10.0.1.1/24 -x p1p1,192.168.10.8,10
Create vxlan veth0
```

すると netns 内にインタフェースが作成されました．

```
$ sudo ip netns exec netns1 ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
16: veth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1450 qdisc noqueue state UNKNOWN group default qlen 1000
    link/ether 76:7e:ed:83:91:a4 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 10.0.1.1/24 brd 10.0.1.255 scope global veth0
       valid_lft forever preferred_lft forever
    inet6 fe80::747e:edff:fe83:91a4/64 scope link
       valid_lft forever preferred_lft forever
```

## host2
もう一方のマシンでも同様のコマンドを実行します．

```
$ sudo ip netns add netns2
$ sudo ip netns exec netns2 ip link set lo up
$ sudo $GOPATH/bin/koko -n netns2,veth0,10.0.1.2/24 -x p1p1,192.168.10.7,10
Create vxlan veth0
```

# 検証
netns1 から netns2 に ICMP パケットを送信してみると，確かに疎通しました．

```
$ sudo ip netns exec netns1 ping -c 3 10.0.1.2
Enter [gordon]'s Password:
PING 10.0.1.2 (10.0.1.2) 56(84) bytes of data.
64 bytes from 10.0.1.2: icmp_seq=1 ttl=64 time=0.260 ms
64 bytes from 10.0.1.2: icmp_seq=2 ttl=64 time=0.305 ms
64 bytes from 10.0.1.2: icmp_seq=3 ttl=64 time=0.383 ms

--- 10.0.1.2 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2038ms
rtt min/avg/max/mdev = 0.260/0.316/0.383/0.050 ms
```

# まとめ
koko というツールを使うと，すごく簡単に VXLAN で遊べます．