Posted at

Tremaに入門してみる -外部のOpen vSwitchに接続まで-

More than 3 years have passed since last update.

Tremaの勉強のため

https://yasuhito.github.io/trema-book/#hello_trema

を参考に入門していきます。

何点かすんなり行かなかったところもあるのでメモも兼ねて残しておきます。

一応今回のゴールとしてはTremaを入れたマシンと別のマシンで動いているOpen vSwitchにつなぐことです。


環境

VirtualBox上にUbuntu16.04のVMを二台用意して以下のように設定します。


Tremaインストール

Tremaはマシン2の方に入れていきます。

rubyのインストールからはじめていきます。

$ sudo apt-get update

$ sudo apt-get install ruby2.0 ruby2.0-dev build-essential

で早速エラー

$ sudo apt-get install ruby2.0 ruby2.0-dev build-essential

パッケージリストを読み込んでいます... 完了
依存関係ツリーを作成しています
状態情報を読み取っています... 完了
E: パッケージ ruby2.0 が見つかりません
E: 'ruby2.0' に一致するパッケージは見つかりませんでした
E: 正規表現 'ruby2.0' ではパッケージは見つかりませんでした
E: パッケージ ruby2.0-dev が見つかりません
E: 'ruby2.0-dev' に一致するパッケージは見つかりませんでした
E: 正規表現 'ruby2.0-dev' ではパッケージは見つかりませんでした

手順書ではruby2.0とありますがruby2.0 やuby2.0-devのパッケージは見当たらないので全てruby2.3にします。

$ sudo apt-get install ruby2.3 ruby2.3-dev build-essential

bundlerのインストール

$ sudo gem install bundler

Open vSwitchのインストール

$ sudo apt-get install openvswitch-switch

これでTremaの準備は終了


Hello Trema

https://yasuhito.github.io/trema-book/#hello_trema にも書いてある

Hello World的なやつをやってみます。

ここでの操作はマシン2のみです。

まずは、プロジェクトディレクトリを作成します。

$ mkdir -p hello_trema/lib

$ cd hello_trema

Gemfileを作成しTremaをインストールします。

source 'https://rubygems.org'

gem 'trema'

でインストールしたいのですが

$ bundle install

An error occurred while installing trema (0.4.7), and Bundler cannot continue.
Make sure that `gem install trema -v '0.4.7'` succeeds before bundling.

この時のbundlerのバージョンが1.12.5なのですが

これを1.11.2にしてみます

gem install bundler -v '1.11.2'

bundle _1.11.2_ install

これでtremaが使えるようになったはず

とりあえずバージョン確認してみる

$ bundle exec trema --version

trema version 0.10.1

次にTremaが実行する本体lib/hello_trema.rbを作成します。


lib/hello_trema.rb

# Hello World!

class HelloTrema < Trema::Controller
def start(_args)
logger.info 'Trema started.'
end

def switch_ready(datapath_id)
logger.info "Hello #{datapath_id.to_hex}!"
end
end


これで、Tremaを起動するとTrema started.と表示され

スイッチがTremaに接続するとそのスイッチのdatapath_idが表示されます。

またTremaが自分で起動する仮想スイッチ(OpenvSwitch)の情報をtrema.confを作成し記述します。


trema.conf

vswitch { datapath_id 0xabc }


実行してみます。

$ bundle exec trema run ./lib/hello_trema.rb -c trema.conf

Trema started.
Hello 0xabc!

これでTremaが動きました。

一旦tremaを停止させます。

$ bundle exec trema kill --all


別マシンのopenvswitchに接続してみる

下の図のような構成でTremaとOpenvSwitchを別マシンに入れました。

この状態で先ほどのhello_tremaを実行すると別マシンのOpen vSwitchも接続されるはず。


マシン1の準備

OpenvSwitchをインストールします

$ apt-get install -y openvswitch-switch

ブリッジを作成、マシン2とつながるインターフェースを作成したブリッジにつなぎます。

ついでにブリッジのdatapath-idを0x1に設定します。

$ sudo ovs-vsctl add-br ovsbr0

$ sudo ovs-vsctl add-port ovsbr0 enp0s8
$ ovs-vsctl set bridge ovsbr0 other-config:datapath-id=0000000000000001

enp0s8についていたipをブリッジに移します。

$ sudo ifconfig enp0s8 0.0.0.0

$ sudo ifconfig ovsbr0 192.168.239.101/24

状態を確認しておきます。

$ sudo ovs-ofctl show ovsbr0

OFPT_FEATURES_REPLY (xid=0x2): dpid:0000000000000001
n_tables:254, n_buffers:256
capabilities: FLOW_STATS TABLE_STATS PORT_STATS QUEUE_STATS ARP_MATCH_IP
actions: output enqueue set_vlan_vid set_vlan_pcp strip_vlan mod_dl_src mod_dl_dst mod_nw_src mod_nw_dst mod_nw_tos mod_tp_src mod_tp_dst
3(enp0s8): addr:08:00:27:af:d2:31
config: 0
state: 0
current: 1GB-FD COPPER AUTO_NEG
advertised: 10MB-HD 10MB-FD 100MB-HD 100MB-FD 1GB-FD COPPER AUTO_NEG
supported: 10MB-HD 10MB-FD 100MB-HD 100MB-FD 1GB-FD COPPER AUTO_NEG
speed: 1000 Mbps now, 1000 Mbps max
LOCAL(ovsbr0): addr:08:00:27:af:d2:31
config: 0
state: 0
speed: 0 Mbps now, 0 Mbps max
OFPT_GET_CONFIG_REPLY (xid=0x4): frags=normal miss_send_len=0

ovsbr0(OpenvSwitch)のコントローラをマシン2に設定しておきます

$ sudo ovs-vsctl set-controller ovsbr0 tcp:192.168.239.101:6653


実行


  • 実行してみた(失敗)

今回はTrema側でOpen vSwitchを起動する必要がないので起動時に -c オプションは必要ありません

$ bundle exec trema run ./lib/hello_trema.rb

/var/lib/gems/2.3.0/gems/pio-0.30.0/lib/pio/open_flow/message.rb:21:in `rescue in read': Invalid OpenFlow10 Hello message. (Pio::ParseError)


  • 実行してみた(成功)

マシン1でOpenvSwitchにバージョンを指定してみます。

sudo ovs-vsctl set bridge ovsbr0 protocols=OpenFlow10

もう一度実行してみると

$ bundle exec trema run ./lib/hello_trema.rb

Trema started.
Hello 0x1!

datapath-id 0x1 が繋がっていることが確認でき、成功しました。