OpenVNetをいろいろと弄ってみた

今回は、前々から気になっていたOpenVNetをいろいろと弄ってみます。
なお、このエントリは、Wakame Users Group Advent Calendar 2013の12/22分の記事となっています。


OpenVNetって何?

OpenVNetはエッジオーバレイ型の仮想ネットワークを作るOSSです。
主な構成要素は下記の4つです。

  • vna
  • vnmgr
  • vnapi(webapi)
  • vncli

詳しくは、あくしゅの山崎さんのSlideShareを見るとよくわかります。


とりあえずインストールしてみる

まずは、何はともあれインストール。
つい先日公開されたInstallGuideの”Let’s try 1Box OpenVNet”を参考に、下記の環境にインストールしました。

# uname -a
Linux openvnet 2.6.32-358.el6.x86_64 #1 SMP Fri Feb 22 00:31:26 UTC 2013 x86_64 x86_64 x86_64 GNU/Linux
# cat /etc/redhat-release
CentOS release 6.4 (Final)

トラブルシューティング

initctl startでOpenVNetの各コンポーネント(vnmgr、vna、webapi)を既に起動しているにも関わらず、テストデータのdb.sh実行中に先に進まない状態となってしまいました。

# ./db.sh
+ webapi_host=localhost
+ port=9090
+ ip_node1=172.16.20.41
+ mysqladmin -f -uroot drop vnet
Database "vnet" dropped
+ mysqladmin -uroot create vnet
+ cd /opt/axsh/wakame-vnet/vnet
+ bundle exec rake db:init
+ curl -s -X POST --data-urlencode uuid=nw-public --data-urlencode display_name=public --data-urlencode ipv4_network=172.16.20.0 --data-urlencode ipv4_prefix=24 --data-urlencode domain_name=public --data-urlencode network_mode=physical http://localhost:9090/api/networks

OpenVNetの各ログ(/var/log/wakame-vnet/配下)をみてみると、下記のようなログが出力されていました。

/opt/axsh/wakame-vnet/vnet/vendor/bundle/ruby/2.0.0/gems/redis-3.0.5/lib/redis/client.rb:278:in `rescue in establish_connection': Error connecting to Redis on 127.0.0.1:6379 (ECONNREFUSED) (Redis::CannotConnectError)
        from /opt/axsh/wakame-vnet/vnet/vendor/bundle/ruby/2.0.0/gems/redis-3.0.5/lib/redis/client.rb:273:in `establish_connection'
        from /opt/axsh/wakame-vnet/vnet/vendor/bundle/ruby/2.0.0/gems/redis-3.0.5/lib/redis/client.rb:69:in `connect'
        from /opt/axsh/wakame-vnet/vnet/vendor/bundle/ruby/2.0.0/gems/redis-3.0.5/lib/redis/client.rb:292:in `ensure_connected'
        from /opt/axsh/wakame-vnet/vnet/vendor/bundle/ruby/2.0.0/gems/redis-3.0.5/lib/redis/client.rb:179:in `block in process'
        from /opt/axsh/wakame-vnet/vnet/vendor/bundle/ruby/2.0.0/gems/redis-3.0.5/lib/redis/client.rb:258:in `logging'
        from /opt/axsh/wakame-vnet/vnet/vendor/bundle/ruby/2.0.0/gems/redis-3.0.5/lib/redis/client.rb:178:in `process'
        from /opt/axsh/wakame-vnet/vnet/vendor/bundle/ruby/2.0.0/gems/redis-3.0.5/lib/redis/client.rb:84:in `call'
        from /opt/axsh/wakame-vnet/vnet/vendor/bundle/ruby/2.0.0/gems/redis-3.0.5/lib/redis.rb:1795:in `block in hset'
        from /opt/axsh/wakame-vnet/vnet/vendor/bundle/ruby/2.0.0/gems/redis-3.0.5/lib/redis.rb:36:in `block in synchronize'
        from /opt/axsh/wakame-vnet/ruby/lib/ruby/2.0.0/monitor.rb:211:in `mon_synchronize'
        from /opt/axsh/wakame-vnet/vnet/vendor/bundle/ruby/2.0.0/gems/redis-3.0.5/lib/redis.rb:36:in `synchronize'
        from /opt/axsh/wakame-vnet/vnet/vendor/bundle/ruby/2.0.0/gems/redis-3.0.5/lib/redis.rb:1794:in `hset'
        from /opt/axsh/wakame-vnet/vnet/vendor/bundle/ruby/2.0.0/gems/redis-namespace-1.3.1/lib/redis/namespace.rb:317:in `method_missing'
        from /opt/axsh/wakame-vnet/vnet/vendor/bundle/ruby/2.0.0/gems/dcell-0.15.0/lib/dcell/registries/redis_adapter.rb:40:in `set'
        from /opt/axsh/wakame-vnet/vnet/vendor/bundle/ruby/2.0.0/gems/dcell-0.15.0/lib/dcell/registries/redis_adapter.rb:53:in `set_node'
        from /opt/axsh/wakame-vnet/vnet/vendor/bundle/ruby/2.0.0/gems/dcell-0.15.0/lib/dcell/directory.rb:14:in `set'
        from /opt/axsh/wakame-vnet/vnet/vendor/bundle/ruby/2.0.0/gems/dcell-0.15.0/lib/dcell.rb:68:in `block in setup'
        from /opt/axsh/wakame-vnet/vnet/vendor/bundle/ruby/2.0.0/gems/dcell-0.15.0/lib/dcell.rb:45:in `synchronize'
        from /opt/axsh/wakame-vnet/vnet/vendor/bundle/ruby/2.0.0/gems/dcell-0.15.0/lib/dcell.rb:45:in `setup'
        from /opt/axsh/wakame-vnet/vnet/vendor/bundle/ruby/2.0.0/gems/dcell-0.15.0/lib/dcell.rb:101:in `start'
        from ./bin/vna:35:in `'

どうやらredis-serverとの接続ががおかしいようなので、状態を確認してみます。

# service redis status
redis-server が停止していますが PID ファイルが残っています

redis-serverが正常に起動できていなかったことで、
OpenVNetのコンポーネントとredis-serverの接続が確立できていなかったことが原因でした。

下記のコマンドでredis-serverのPIDを消し、再度redis-serverを起動し、状態を確認してみます。

# rm /var/run/redis/redis.pid
rm: remove 通常ファイル `/var/run/redis/redis.pid'? y
# service redis start
redis-server を起動中:                                     [  OK  ]
# service redis status
redis-server が停止していますが PID ファイルが残っています

どうやらredis-server起動直後に異常終了してPIDファイルだけ残存しているようです。
redisのログを確認してみます。

# less /var/log/redis/redis.log
[10266] 02 Dec 06:20:16 * Server started, Redis version 2.4.10
[10266] 02 Dec 06:20:16 # WARNING overcommit_memory is set to 0! Background save may fail under low memory condition. To fix this issue add 'vm.overcommit_memory = 1' to /etc/sysctl.conf and then reboot or run the command 'sysctl vm.overcommit_memory=1' for this to take effect.
[10266] 02 Dec 06:20:16 # Short read or OOM loading DB. Unrecoverable error, aborting now.

まず、2行目の警告は毎回出るので、下記のようにカーネルパラメータを弄って対処する。

echo "vm.overcommit_memory = 1" >> /etc/sysctl.conf
sysctl -p

次に、3行目のエラーは、どうやらredisのdumpファイルが壊れてしまっているようなので、renameして再起動する。

# mv /var/lib/redis/dump.rdb /var/lib/redis/dump.rdb.bk
# service redis start
redis-server を起動中:                                     [  OK  ]
# service redis status
redis-server (pid  11220) を実行中...

vnmgr、vna、webapiを再起動してdb.shを実行すると最後まで走りました。よかったよかった。
あとは、「Check Virtual Network Operation.」の手順に沿って仮想ネットワークの動作を試せます。


vnet-test-kvmの中身を見てみる

テスト環境vnet-test-kvmの中身は下記のような構成になっていました。

# tree -f
.
├── ./db.sh
└── ./vm
    ├── ./vm/run-vm
    ├── ./vm/run-vm-all
    ├── ./vm/term-vm
    ├── ./vm/term-vm-all
    ├── ./vm/vm1.raw
    ├── ./vm/vm2.raw
    ├── ./vm/vm3.raw
    └── ./vm/vm4.raw

db.shの中身を読んでみると、vnetデータベースを作成した後、下記の手順でREST APIを叩いて試験環境をセットアップしているようです。

  1. 物理ネットワークnw-publicを作成
  2. 論理ネットワークvnet1, vnet2を作成
  3. データパスnode1を作成
  4. node1にnw-public, vnet1, vnet2を関連付け
  5. vm1, vm3をvnet1に割り当て
  6. vm2, vm4をvnet2に割り当て
  7. サービスインタフェースの設定
  8. ルーティングの設定

vm1とvm3が所属する論理ネットワークvnet1と、vm2とvm4が所属する論理ネットワークvnet2は独立したネットワークとなるため、例えばvm1はvm2とは通信できませんがvm3とは通信できるという状態になります。

virtual_network

「Check Virtual Network Operation.」の手順にある、run-vm-allを実行すると、vm1〜vm4の4台のVMがqemu-kvmコマンド経由で起動され、OpenVSwitchに接続されます。

# ./run-vm-all
*** vm1 ***
node-id: 1
interface name: if-x5vjmksl
mac address: 52:54:00:0d:84:8c
*** vm2 ***
node-id: 2
interface name: if-sve1s6xp
mac address: 52:54:00:9a:cc:00
*** vm3 ***
node-id: 3
interface name: if-bvixz40n
mac address: 52:54:00:0a:fb:78
*** vm4 ***
node-id: 4
interface name: if-7st2alal
mac address: 52:54:00:e5:f9:fb

なお、VM起動中には、vm1.pidのようなPIDファイルが生成されます。
個別に起動したい場合は、引数にID、インタフェース名、MACアドレスを指定してrun-vmを実行します。

#./run-vm 1 if-x5vjmksl 52:54:00:0d:84:8c

また、term-vm-allを実行すると、4台のVMがすべて停止されます。

# ./term-vm-all

個別に停止したい場合は、引数にIDを指定してterm-vmを実行します。

# ./term-vm 1

ソースコードを読んでみる

OpenVNetのソースコードはGitHubリポジトリに公開されています。
トップレベルにvnctlディレクトリとvnetディレクトリがありますが、本体はvnetディレクトリ配下にあります。
ただ、今回は既にインストール済の環境があるので、/opt/axsh/wakame-vnet/に格納されたファイルをターゲットにします。
Rubyにはyardというドキュメンテーションツールがあるので、これで整理してみます。

# gem install yard
# yard doc

yard doc

せっかくなのでクラス図もみてみましょう。

# yard graph --full -f tapp.dot
# dot -Tpng tapp.dot  -o tapp.png

OpenVNet クラス図

巨大な画像になってしまいました・・・。
ファイルサイズ重いのでご注意を。

クラス数こそ結構ありますが、想像通りシンプルな作りになっているようです。


vnetデータベースの中身を見てみる

ここで、OpenVNetがどんな情報をデータベースに格納しているのか見てみましょう。

# mysql vnet -u root -p
Enter password:  <-そのままEnter 

テーブル一覧を見てみます。

 mysql> SHOW TABLES;
+---------------------------+
| Tables_in_vnet            |
+---------------------------+
| datapath_networks         |
| datapath_route_links      |
| datapaths                 |
| dc_segments               |
| dhcp_ranges               |
| interface_security_groups |
| interfaces                |
| ip_addresses              |
| ip_leases                 |
| mac_addresses             |
| mac_leases                |
| network_services          |
| networks                  |
| route_links               |
| routes                    |
| schema_info               |
| security_groups           |
| tunnels                   |
| vlan_translations         |
+---------------------------+
19 rows in set (0.00 sec)

もうちょっと全体を俯瞰するために、ER図が見たくなりました。
MySQL Workbenchを使ってvnetデータベースのER図を自動生成してみました。

ER diagram - MySQL Workbench
PDFはこちら
(MySQL Workbenchに慣れてなくて、自動生成時にリレーションで結線できてません。)

こうやってみると、どんな情報を格納しているのかおぼろげに見えてきますね。


フローテーブルの中身を見てみる

# ovs-ofctl dump-flows br0
NXST_FLOW reply (xid=0x4):
 cookie=0x900000000000001, duration=4.782s, table=0, n_packets=0, n_bytes=0, idle_age=4, priority=1,tun_id=0 actions=drop
 cookie=0x900000000000001, duration=4.782s, table=0, n_packets=0, n_bytes=0, idle_age=4, priority=2,in_port=CONTROLLER actions=write_metadata:0x2040000000000/0x20c0000000000
 cookie=0x500000000000001, duration=4.086s, table=0, n_packets=0, n_bytes=0, idle_age=4, priority=2,in_port=1 actions=write_metadata:0x80000000000/0xc0000000000
 cookie=0x5000000fffffffe, duration=4.387s, table=0, n_packets=0, n_bytes=0, idle_age=4, priority=2,in_port=LOCAL actions=write_metadata:0x40000000000/0xc0000000000
 cookie=0x900000000000001, duration=4.782s, table=0, n_packets=0, n_bytes=0, idle_age=4, priority=0 actions=write_metadata:0x80000000000/0xc0000000000
 cookie=0x300000000000001, duration=4.086s, table=2, n_packets=0, n_bytes=0, idle_age=4, priority=10 actions=write_metadata:0x300000000000001/0xff000000ffffffff
 cookie=0x900000000000001, duration=4.782s, table=2, n_packets=0, n_bytes=0, idle_age=4, priority=0 actions=drop
 cookie=0x900000000000001, duration=4.782s, table=3, n_packets=0, n_bytes=0, idle_age=4, priority=0 actions=drop
 cookie=0x700000000000002, duration=3.955s, table=4, n_packets=0, n_bytes=0, idle_age=3, priority=30,tun_id=0x1,dl_dst=52:54:00:60:22:22 actions=write_metadata:0x600000000000002/0xff000000ffffffff
 cookie=0x900000000000001, duration=4.782s, table=4, n_packets=0, n_bytes=0, idle_age=4, priority=0 actions=drop
 cookie=0x300000000000001, duration=4.086s, table=6, n_packets=0, n_bytes=0, idle_age=4, priority=10 actions=write_metadata:0x300000000000001/0xff000000ffffffff
 cookie=0x900000000000001, duration=4.782s, table=6, n_packets=0, n_bytes=0, idle_age=4, priority=0 actions=drop
 cookie=0x900000000000001, duration=4.782s, table=7, n_packets=0, n_bytes=0, idle_age=4, priority=0 actions=drop
 cookie=0x900000000000001, duration=4.782s, table=8, n_packets=0, n_bytes=0, idle_age=4, priority=0 actions=drop
 cookie=0x900000000000001, duration=4.782s, table=9, n_packets=0, n_bytes=0, idle_age=4, priority=0 actions=drop
 cookie=0x900000000000001, duration=4.782s, table=10, n_packets=0, n_bytes=0, idle_age=4, priority=0 actions=drop
 cookie=0x900000000000001, duration=4.782s, table=11, n_packets=0, n_bytes=0, idle_age=4, priority=0 actions=drop
 cookie=0x900000000000001, duration=4.782s, table=12, n_packets=0, n_bytes=0, idle_age=4, priority=0 actions=drop
 cookie=0x200000000000001, duration=4.025s, table=20, n_packets=0, n_bytes=0, idle_age=4, priority=90,dl_dst=08:00:27:10:03:01 actions=drop
 cookie=0x700000000000002, duration=3.955s, table=20, n_packets=0, n_bytes=0, idle_age=3, priority=90,dl_dst=52:54:00:60:22:22 actions=drop
 cookie=0x200000000000001, duration=4.025s, table=20, n_packets=0, n_bytes=0, idle_age=4, priority=90,dl_src=08:00:27:10:03:01 actions=drop
 cookie=0x700000000000002, duration=3.955s, table=20, n_packets=0, n_bytes=0, idle_age=3, priority=90,dl_src=52:54:00:60:22:22 actions=drop
 cookie=0x900000000000001, duration=4.782s, table=20, n_packets=0, n_bytes=0, idle_age=4, priority=0 actions=drop
 cookie=0x300000000000001, duration=4.086s, table=20, n_packets=0, n_bytes=0, idle_age=4, priority=30,metadata=0x300000000000001/0xff000000ffffffff actions=drop
 cookie=0x900000000000000, duration=4.782s, table=21, n_packets=0, n_bytes=0, idle_age=4, priority=80,arp actions=drop
 cookie=0x900000000000001, duration=4.782s, table=21, n_packets=0, n_bytes=0, idle_age=4, priority=90,in_port=CONTROLLER actions=drop
 cookie=0x500000000000001, duration=4.086s, table=21, n_packets=0, n_bytes=0, idle_age=4, priority=30,in_port=1 actions=drop
 cookie=0x900000000000000, duration=4.782s, table=21, n_packets=0, n_bytes=0, idle_age=4, priority=82,arp,tun_id=0 actions=drop
 cookie=0x900000000000000, duration=4.782s, table=21, n_packets=0, n_bytes=0, idle_age=4, priority=84,arp,metadata=0x40000000000/0xc0000000000 actions=drop
 cookie=0x900000000000001, duration=4.782s, table=21, n_packets=0, n_bytes=0, idle_age=4, priority=0 actions=drop
 cookie=0x500000000000001, duration=4.086s, table=22, n_packets=0, n_bytes=0, idle_age=4, priority=41,ip,in_port=1 actions=drop
 cookie=0x5000000fffffffe, duration=4.387s, table=22, n_packets=0, n_bytes=0, idle_age=4, priority=41,arp,in_port=LOCAL actions=drop
 cookie=0x500000000000001, duration=4.086s, table=22, n_packets=0, n_bytes=0, idle_age=4, priority=41,arp,in_port=1 actions=drop
 cookie=0x5000000fffffffe, duration=4.387s, table=22, n_packets=0, n_bytes=0, idle_age=4, priority=41,ip,in_port=LOCAL actions=drop
 cookie=0x900000000000001, duration=4.782s, table=22, n_packets=0, n_bytes=0, idle_age=4, priority=40,ip actions=drop
 cookie=0x900000000000001, duration=4.782s, table=22, n_packets=0, n_bytes=0, idle_age=4, priority=40,arp actions=drop
 cookie=0x900000000000001, duration=4.782s, table=22, n_packets=0, n_bytes=0, idle_age=4, priority=90,in_port=CONTROLLER actions=drop
 cookie=0x500000000000001, duration=4.086s, table=22, n_packets=0, n_bytes=0, idle_age=4, priority=31,in_port=1 actions=drop
 cookie=0x5000000fffffffe, duration=4.387s, table=22, n_packets=0, n_bytes=0, idle_age=4, priority=31,in_port=LOCAL actions=drop
 cookie=0x900000000000001, duration=4.782s, table=22, n_packets=0, n_bytes=0, idle_age=4, priority=0 actions=drop
 cookie=0x900000000000001, duration=4.782s, table=33, n_packets=0, n_bytes=0, idle_age=4, priority=0 actions=drop
 cookie=0x900000000000001, duration=4.782s, table=34, n_packets=0, n_bytes=0, idle_age=4, priority=0 actions=drop
 cookie=0x900000000000001, duration=4.782s, table=35, n_packets=0, n_bytes=0, idle_age=4, priority=0 actions=drop
 cookie=0x900000000000001, duration=4.782s, table=36, n_packets=0, n_bytes=0, idle_age=4, priority=0 actions=drop
 cookie=0x900000000000001, duration=4.782s, table=37, n_packets=0, n_bytes=0, idle_age=4, priority=0 actions=drop
 cookie=0x900000000000001, duration=4.782s, table=38, n_packets=0, n_bytes=0, idle_age=4, priority=0 actions=drop
 cookie=0x200000000000001, duration=4.025s, table=40, n_packets=0, n_bytes=0, idle_age=4, priority=90,dl_dst=08:00:27:10:03:01 actions=drop
 cookie=0x700000000000002, duration=3.955s, table=40, n_packets=0, n_bytes=0, idle_age=3, priority=90,dl_dst=52:54:00:60:22:22 actions=drop
 cookie=0x200000000000001, duration=4.025s, table=40, n_packets=0, n_bytes=0, idle_age=4, priority=90,dl_src=08:00:27:10:03:01 actions=drop
 cookie=0x700000000000002, duration=3.955s, table=40, n_packets=0, n_bytes=0, idle_age=3, priority=90,dl_src=52:54:00:60:22:22 actions=drop
 cookie=0x900000000000001, duration=4.782s, table=40, n_packets=0, n_bytes=0, idle_age=4, priority=0 actions=drop
 cookie=0x300000000000001, duration=4.086s, table=40, n_packets=0, n_bytes=0, idle_age=4, priority=30,metadata=0x300000000000001/0xff000000ffffffff actions=drop
 cookie=0x900000000000001, duration=4.782s, table=41, n_packets=0, n_bytes=0, idle_age=4, priority=30,dl_dst=ff:ff:ff:ff:ff:ff actions=drop
 cookie=0x900000000000001, duration=4.782s, table=41, n_packets=0, n_bytes=0, idle_age=4, priority=0 actions=drop
 cookie=0x5000000fffffffe, duration=4.387s, table=42, n_packets=0, n_bytes=0, idle_age=4, priority=30,dl_dst=02:01:00:00:00:01 actions=LOCAL
 cookie=0x900000000000001, duration=4.782s, table=42, n_packets=0, n_bytes=0, idle_age=4, priority=30,dl_dst=ff:ff:ff:ff:ff:ff actions=drop
 cookie=0x500000000000001, duration=4.086s, table=42, n_packets=0, n_bytes=0, idle_age=4, priority=21,metadata=0x1000000000000/0x1000000000000,in_port=1 actions=IN_PORT
 cookie=0x500000000000001, duration=4.086s, table=42, n_packets=0, n_bytes=0, idle_age=4, priority=20 actions=output:1
 cookie=0x900000000000001, duration=4.782s, table=42, n_packets=0, n_bytes=0, idle_age=4, priority=0 actions=drop
 cookie=0x900000000000001, duration=4.782s, table=44, n_packets=0, n_bytes=0, idle_age=4, priority=0 actions=drop
 cookie=0x5000000fffffffe, duration=4.387s, table=45, n_packets=0, n_bytes=0, idle_age=4, priority=1,dl_dst=02:01:00:00:00:01 actions=LOCAL
 cookie=0x900000000000001, duration=4.782s, table=45, n_packets=0, n_bytes=0, idle_age=4, priority=0 actions=drop
 cookie=0x900000000000001, duration=4.782s, table=50, n_packets=0, n_bytes=0, idle_age=4, priority=0 actions=drop
 cookie=0x900000000000001, duration=4.782s, table=51, n_packets=0, n_bytes=0, idle_age=4, priority=0 actions=drop
 cookie=0x300000000000001, duration=4.086s, table=51, n_packets=0, n_bytes=0, idle_age=4, priority=1,metadata=0x300000000000001/0xff000000ffffffff actions=LOCAL
 cookie=0x900000000000001, duration=4.782s, table=52, n_packets=0, n_bytes=0, idle_age=4, priority=10,metadata=0x80000000000/0xc0000000000 actions=drop
 cookie=0x500000000000001, duration=4.086s, table=52, n_packets=0, n_bytes=0, idle_age=4, priority=1 actions=LOCAL,output:1
 cookie=0x900000000000001, duration=4.782s, table=52, n_packets=0, n_bytes=0, idle_age=4, priority=0 actions=drop
 cookie=0x900000000000001, duration=4.782s, table=53, n_packets=0, n_bytes=0, idle_age=4, priority=10,metadata=0x80000000000/0xc0000000000 actions=drop
 cookie=0x900000000000001, duration=4.782s, table=53, n_packets=0, n_bytes=0, idle_age=4, priority=0 actions=drop
 cookie=0x900000000000001, duration=4.782s, table=54, n_packets=0, n_bytes=0, idle_age=4, priority=0 actions=drop
 cookie=0x900000000000001, duration=4.782s, table=60, n_packets=0, n_bytes=0, idle_age=4, priority=0 actions=CONTROLLER:65535
 cookie=0x700000000000002, duration=3.955s, table=61, n_packets=0, n_bytes=0, idle_age=3, priority=4,dl_dst=52:54:00:60:22:22 actions=load:0x1->NXM_NX_TUN_ID[],write_metadata:0x800000000000/0x800000000000
 cookie=0x900000000000001, duration=4.782s, table=61, n_packets=0, n_bytes=0, idle_age=4, priority=0 actions=drop
 cookie=0x500000000000001, duration=4.086s, table=62, n_packets=0, n_bytes=0, idle_age=4, priority=2,metadata=0x1400000000000/0x1400000000000,in_port=1 actions=IN_PORT
 cookie=0x500000000000001, duration=4.086s, table=62, n_packets=0, n_bytes=0, idle_age=4, priority=1,metadata=0x400000000000/0x400000000000 actions=output:1
 cookie=0x900000000000001, duration=4.782s, table=62, n_packets=0, n_bytes=0, idle_age=4, priority=0 actions=drop
 cookie=0x900000000000001, duration=4.782s, table=63, n_packets=0, n_bytes=0, idle_age=4, priority=0 actions=drop
 cookie=0x500000000000001, duration=4.086s, table=64, n_packets=0, n_bytes=0, idle_age=4, priority=2,metadata=0x1400000000000/0x1400000000000,in_port=1 actions=IN_PORT
 cookie=0x500000000000001, duration=4.086s, table=64, n_packets=0, n_bytes=0, idle_age=4, priority=1,metadata=0x400000000000/0x400000000000 actions=output:1
 cookie=0x900000000000001, duration=4.782s, table=64, n_packets=0, n_bytes=0, idle_age=4, priority=0 actions=drop
 cookie=0x900000000000001, duration=4.782s, table=65, n_packets=0, n_bytes=0, idle_age=4, priority=0 actions=drop

結構な数のフローエントリが挿入されてます。table=65!
この時点で格納されていた全82フローをアクションごとに分類すると、下記となりました。

  • drop : 63
  • write_metadata : 8
  • output : 4
  • LOCAL : 4
  • IN_PORT : 3
  • CONTROLLER : 1

やはり、仮想ネットワーク機能の特性上、ほとんどのフローがパケットのdropに使用されているようです。


vnctlでCLIから操作してみる

基本的には、ritchey98さんの12/17分の下記エントリに書かれているようなことができそうです。

今回はネットワーク情報をターゲットに、vnctlコマンドによって情報を取得してみます。

# vnctl network show
{"id"=>1, "uuid"=>"nw-public", "display_name"=>"public", "ipv4_network"=>"172.16.20.0", "ipv4_prefix"=>24, "domain_name"=>"public", "network_mode"=>"physical", "editable"=>nil, "created_at"=>"2013-12-01T16:46:35Z", "updated_at"=>"2013-12-01T16:46:35Z", ""=>nil}
{"id"=>2, "uuid"=>"nw-vnet1", "display_name"=>"vnet1", "ipv4_network"=>"10.102.0.0", "ipv4_prefix"=>24, "domain_name"=>"vnet1", "network_mode"=>"virtual", "editable"=>nil, "created_at"=>"2013-12-01T16:46:35Z", "updated_at"=>"2013-12-01T16:46:35Z", ""=>nil}
{"id"=>3, "uuid"=>"nw-vnet2", "display_name"=>"vnet2", "ipv4_network"=>"10.102.0.0", "ipv4_prefix"=>24, "domain_name"=>"vnet2", "network_mode"=>"virtual", "editable"=>nil, "created_at"=>"2013-12-01T16:46:35Z", "updated_at"=>"2013-12-01T16:46:35Z", ""=>nil}

いい感じです。


webapiでリモートから操作してみる

公式ドキュメントとして、WebAPI Referenceがあるのですが、12/22時点では一部記述が古い様子。
とりあえず書いてある通り試してみましょう。

外部のサーバから1Box OpenVNetのサーバに対してREST API経由でネットワークの情報を取ってきます。
(今回は10.0.1.7が宛先IPアドレスです。)

# curl -s -X GET http://10.0.1.7:9090/api/1.0/networks</pre>
<style type="text/css"><!--
body { text-align:center;font-family:helvetica,arial;font-size:22px;     color:#888;margin:20px}   #c {margin:0 auto;width:500px;text-align:left}
--></style>
<pre></pre>
<h2>Sinatra doesn’t know this ditty.</h2>
<pre> <img alt="" src="http://10.0.1.7:9090/api/__sinatra__/404.png" /></pre>
<div id="c">
Try this:
<pre># in vnet_api.rb
class Vnet::Endpoints::V10::VnetAPI
  get '/1.0/networks' do
    "Hello World"
  end
end</pre>
</div>
<pre>

残念ながら、404 NotFound。
もしやドキュメントのREST APIで対象としているURLが古い・・・?
ということでdb.shを見てみると、こんな感じ。

http://$webapi_host:$port/api/networks

ということで、バージョン番号部分が不要だったようです。

そこで、修正後のURLで再度curlコマンドを叩いてみます。

# curl -s -X GET http://10.0.1.7:9090/api/networks
[{"id":1,"uuid":"nw-public","display_name":"public","ipv4_network":"172.16.20.0","ipv4_prefix":24,"domain_name":"public","network_mode":"physical","editable":null,"created_at":"2013-12-01T21:16:49Z","updated_at":"2013-12-01T21:16:49Z","":null},{"id":2,"uuid":"nw-vnet1","display_name":"vnet1","ipv4_network":"10.102.0.0","ipv4_prefix":24,"domain_name":"vnet1","network_mode":"virtual","editable":null,"created_at":"2013-12-01T21:16:49Z","updated_at":"2013-12-01T21:16:49Z","":null},{"id":3,"uuid":"nw-vnet2","display_name":"vnet2","ipv4_network":"10.102.0.0","ipv4_prefix":24,"domain_name":"vnet2","network_mode":"virtual","editable":null,"created_at":"2013-12-01T21:16:49Z","updated_at":"2013-12-01T21:16:49Z","":null}]

意図した通り、REST API経由で値がとれました。よかったよかった。
REST APIの使い方を知るには、db.shを参考にするのがよさそうです。


以上の通り、OpenVNetをいろいろと弄ってみました。
これまではドキュメントがほとんどない状況で、敷居が高い印象が否めませんでしたが、
Installation Guideが公開されたことで、だれでも触れるようになってきています。
OpenVNet、この機会にいろいろと弄ってみてはいかがでしょうか?

広告
  1. OF1.3のフローを出力する際は、下記のようにすると詳細まで出るみたいです。
    $ ovs-ofctl -O OpenFlow13 dump-flows br0 …

  1. トラックバックはまだありません。

コメントを残す

以下に詳細を記入するか、アイコンをクリックしてログインしてください。

WordPress.com ロゴ

WordPress.com アカウントを使ってコメントしています。 ログアウト / 変更 )

Twitter 画像

Twitter アカウントを使ってコメントしています。 ログアウト / 変更 )

Facebook の写真

Facebook アカウントを使ってコメントしています。 ログアウト / 変更 )

Google+ フォト

Google+ アカウントを使ってコメントしています。 ログアウト / 変更 )

%s と連携中

%d人のブロガーが「いいね」をつけました。