あさのひとりごと

3日坊主にならないように、全力を尽くします。 記事は個人のひとりごとです。所属する組織の意見を代表するほど、仕事熱心じゃないです。

Raspberry Pi3 でOpenvSwitch+Tremaを動かした~OpenFlow入門~

由緒正しき物理ネットワークの世界では、スイッチやルータなどの通信機器が独立したOSや制御ソフト、ルーティング機能やデータ転送機能もっていて、設定や構成などの作業も手作業で行っていました。ネットワークの構成は物理に依存し、人間によってケーブルを抜き差しするという温かみのある運用を行っていました。私の青春時代は、まさにこれにすべてを費やしていたといっても過言はありません。

SDN(Software-Defined Networking)は、物理的な変更を行わず、ソフトウエアの設定変更のみでネットワーク構成を変更できる、素晴らしいものです。

SDNは通信機器の制御機能データ転送機能を分離し、制御機能をソフトウェアで一元管理することで、どの通信機器にどのような動作をさせるかをソフトウエアで設定できるようになります。

私は、SDNの超初心者ですが、とても楽しそうな世界が果てしなく広がっている気がしてならないので、RaspberryPi3を使ってOpenvSwitchを動かして、Hello Tremaをやってみました。

対象読者

  • OpenFlow超初心者
  • Linuxの基本コマンドが分かる
  • RaspberryPi3がセットアップできる
  • Rubyの文法が分かる

RaspberryPi3のセットアップ

Raspberry Piラズベリーパイ)は、教育用に開発されたシングルボードコンピュータです。ARMプロセッサを搭載し、microUSBで電源を供給し、OSをSDカードにインストールすることで動作します。一言でいってしまえば、約6000円で買うことができる、タバコの箱サイズの小さなパソコンです。秋葉原秋月電子に行けば買えますし、Amazonでポチッとしてもよいでしょう。翌日には届きます。

いくつかのモデルがありますが、最新版のRaspberry Pi3は、CPUが1.2 GHz クアッドコア Cortex-A53 ARMv8 64bit で、2.4GHz帯のIEEE 802.11 b/g/n(1x1:1)に対応したBroadcom BCM43438が搭載されています。f:id:dr_asa:20170511085921j:plain

公式サイトは、以下になります。

Raspberry Pi - Teach, Learn, and Make with Raspberry Pi https://www.raspberrypi.org/

Raspberry Piで利用できるOSは、公式サイトからダウンロードできます。Linuxベースのもの以外にも、Windows10 IoT CoreやRISC OSも利用できます。RISC OS はARMアーキテクチャシステム向けに設計されたOSです。

RaspberryPi3のセットアップは簡単です。公式サイトからダウンロードしたイメージをMicroSDカードに入れて初期セットアップをしてしまえば、すぐに使えます。

詳細な手順については、このあたりを読んでいただければと思います。

Raspberry Piで電子工作をはじめよう! ~まずはRasbian(OS)のセットアップから~ http://codezine.jp/article/detail/9027

RaspberryPiのセットアップが完了し、同一セグメント内の他のPCのターミナルコンソールからアクセスできれば準備は完了です。

OpenvSwitchのインストー

OpenFlowとは、ネットワークをソフトウエアで制御する技術です。ネットワークスイッチの動作を制御する標準プロトコルで、ネットワークの動作をソースコードで記述できます。OpenvSwitchはOpenFlowに対応したソフトウエアスイッチです。 今回は、これをRaspberryPiで動かしたい!まずはここまで頑張ります。

OpenvSwitchの公式サイトは以下の通りです。 http://openvswitch.org/ f:id:dr_asa:20170511090032j:plain

Ubuntu/Debianであればapt-getコマンド、CentOSであえばyumコマンドでインストールできますが、RaspberryPiでは、Rasbian というDebianベースのOSが動いています。そこでソースコードからインストールしていきます。

1. OpenvSwitchのダウンロード

以下のサイトにソースコードが公開されていますので、ダウンロードします。最新版は、2.5.0です。 http://openvswitch.org/download/

$ wget http://openvswitch.org/releases/openvswitch-2.5.0.tar.gz
--2016-06-24 22:31:42--  http://openvswitch.org/releases/openvswitch-2.5.0.tar.gz
openvswitch.org (openvswitch.org) をDNSに問いあわせています... 69.56.251.103
openvswitch.org (openvswitch.org)|69.56.251.103|:80 に接続しています... 接続しました。
HTTP による接続要求を送信しました、応答を待っています... 200 OK
長さ: 4603077 (4.4M) [application/x-gzip]
`openvswitch-2.5.0.tar.gz' に保存中

openvswitch-2.5.0.t 100%[=====================>]   4.39M  2.50MB/s 時間 1.8s

2016-06-24 22:31:44 (2.50 MB/s) - `openvswitch-2.5.0.tar.gz' へ保存完了 [4603077/4603077]

tarコマンドで解凍します

$ tar xzf openvswitch-2.5.0.tar.gz

2. ビルドの依存関係チェック

OpenvSwitchをビルドするにあたり、必要なパッケージをチェックします。

$ dpkg-checkbuilddeps
dpkg-checkbuilddeps: Unmet build dependencies: graphviz autoconf (>= 2.64) automake (>= 1.10) | automake1.10 debhelper (>= 8) dh-autoreconf libssl-dev libtool python-all (>= 2.7) python-qt4 python-twisted-conch python-zopeinterface

いろいろ必要なようですので、apt-getコマンドでインストールしていきます。

$ sudo apt-get -y install graphviz autoconf automake dh-autoreconf libssl-dev libtool python-all python-qt4 python-twisted-conch python-zopeinterface

また、uuid-runtimeとdkmsも必要になるので、ここでインストールしておきます。

$ sudo apt-get -y install uuid-runtime dkms

これで準備が完了しました。

3. OpenvSwitchのビルド

ソースコードを展開すると、以下のような構成になっています。 RaspberryPiのOSはDebian系なので、INSTALL.Debian.mdを読みながらビルド/インストールします。

$ ls
AUTHORS             INSTALL.Windows.md          Vagrantfile       ofproto
CONTRIBUTING.md     INSTALL.XenServer.md        WHY-OVS.md        ovn
COPYING             INSTALL.md                  acinclude.m4      ovsdb
CodingStyle.md      INSTALL.userspace.md        aclocal.m4        package.m4
DESIGN.md           IntegrationGuide.md         appveyor.yml      python
Documentation       Makefile.am                 boot.sh           rhel
FAQ.md              Makefile.in                 build-aux         selinux
INSTALL.DPDK.md     NEWS                        config.h.in       tests
INSTALL.Debian.md   NOTICE                      configure         third-party
INSTALL.Docker.md   OPENFLOW-1.1+.md            configure.ac      tutorial
INSTALL.Fedora.md   PORTING.md                  datapath          utilities
INSTALL.KVM.md      README-lisp.md              datapath-windows  vswitchd
INSTALL.Libvirt.md  README-native-tunneling.md  debian            vtep
INSTALL.NetBSD.md   README.md                   include           windows
INSTALL.RHEL.md     REPORTING-BUGS.md           lib               xenserver
INSTALL.SELinux.md  SECURITY.md                 m4
INSTALL.SSL.md      TODO.md                     manpages.mk

INSTALL.Debian.mdには、次のような記述があります。もし、めっちゃ急いでるようだったら、テスト無しでもできますよ。と。

-------------
If you are in a big hurry, you can even skip the unit tests:
`DEB_BUILD_OPTIONS='parallel=8 nocheck' fakeroot debian/rules binary`

DEB_BUILD_OPTIONS='nocheck' fakeroot debian/rules binary
-------------

というわけで、次のコマンドを実行してビルドします。

$ DEB_BUILD_OPTIONS='nocheck' fakeroot debian/rules binary

ものすごく、時間がかかります。コーヒーでも飲みながら待ちましょう。

なお、ビルドには、build-essentialとfakerootが必要になるので最新版が入っていない時はいれておきます。2016-05-27-raspbian-jessieは、最新版がすでに入っていたので不要でした。

$ sudo apt-get -y install build-essential fakeroot

4. OpenvSwitchのインストー

ビルドが完了したら、親ディレクトリにdebファイルが生成されています。やったね!

$ pwd
/home/pi/hello_trema

$ ls
openvswitch-2.5.0
openvswitch-2.5.0.tar.gz
openvswitch-common_2.5.0-1_armhf.deb
openvswitch-datapath-dkms_2.5.0-1_all.deb
openvswitch-datapath-source_2.5.0-1_all.deb
openvswitch-dbg_2.5.0-1_armhf.deb
openvswitch-ipsec_2.5.0-1_armhf.deb
openvswitch-pki_2.5.0-1_all.deb
openvswitch-switch_2.5.0-1_armhf.deb
openvswitch-test_2.5.0-1_all.deb
openvswitch-testcontroller_2.5.0-1_armhf.deb
openvswitch-vtep_2.5.0-1_armhf.deb
python-openvswitch_2.5.0-1_all.deb

いよいよインストールをしていきます。

$ sudo dpkg -i openvswitch-common_2.5.0-1_armhf.deb
$ sudo dpkg -i openvswitch-datapath-dkms_2.5.0-1_all.deb
$ sudo dpkg -i openvswitch-switch_2.5.0-1_armhf.deb

エラーが出なければ、これでインストール完了です。

5. OpenvSwitchの起動

インストールしたOpenvSwitchを次のコマンドで起動します。

$ sudo service openvswitch-switch start

Tremaのインストー

SDNはソフトウエアでネットワーク全体を制御するものですが、ソフトウエアである以上開発していくときにフレームワークがあったほうが楽です。Trema(とれま)とは、OpenFlowコントローラを開発するためのオープンソースソフトウエアです。

公式サイトは以下の通りです。 http://trema.github.io/trema/

OpenFlowに関しては、以下を読むことをお勧めします。 私はセレブな主婦なので、書籍を購入しました。 f:id:dr_asa:20170511090126p:plain

Tremaをインストールは次のコマンドを実行します。

$ sudo gem install trema

これで準備はすべて完了です。

Hello Trema

ソフトウエアでネットワークを!と言われてもピンと来なかったので、まずはHello Tremaを動かしてみます。考えても分からないところは手に教えてもらう、という勉強法で今まで生きてきたのでそのスタイルを貫きます。

以下からプロジェクトリポジトリをcloneします。

 $ git clone https://github.com/trema/hello_trema.git

普通のRubyのフォルダ構成なので、少し安心です。

$ ls
CHANGELOG.md     Gemfile.lock  README.md  lib    trema.conf
CONTRIBUTING.md  Guardfile     Rakefile   spec
Gemfile          LICENSE       features   tasks

1. スイッチ設定ファイル作成

trema.confというファイルがスイッチの設定ファイルになります。vswitch で始まる行が1台の仮想スイッチで、datapath_id が仮想スイッチを一意に識別するためのIDです。

datapath_id はMACアドレス的なものらしいので、重複しないように設定する必要があります。OpenFlowの仕様では、この値には64ビットの一意な整数値を割り振ることになっています。

この設定ファイルでは、0xabcというdatapath_id の仮想スイッチを1台定義しているという意味になります。

$ cat trame.conf
vswitch { datapath_id 0xabc }

2 制御コードの実装

制御部分は、Rubyで実装していきます。サンプルプロジェクトのlib/hello_trema.rbを使います。Trema::Controllerクラスを継承して作ります。

# 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

このクラスには2つのハンドラがあります。

  • start ハンドラ コントローラの起動イベント発生時に呼び出される

  • switch_ready ハンドラ スイッチがコントローラに接続し、初期化が完了したときに呼び出される

つまり、コントローラが起動したら、コンソールに 「Trema started.」が表示され、コントローラにスイッチが接続したら、「Hello スイッチのdatapath_id!」が表示されるぞ!と。

ほかにもたくさんハンドラがあるので、すこしずつ勉強していきたいと思います。

ハンドラ 説明
switch_disconnected スイッチがコントローラから切断したとき
packet_in Packet In メッセージがコントローラへ到着したとき
flow_removed フローが消えたときのFlow Removedメッセージ到着時

3. Hello Tremaの実行

tremaコマンドを使って実行します。仮想スイッチの設定ファイルは-cオプションで指定します。

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

We trust you have received the usual lecture from the local System
Administrator. It usually boils down to these three things:

    #1) Respect the privacy of others.
    #2) Think before you type.
    #3) With great power comes great responsibility.

[sudo] password for pi: 
Trema started.
Hello 0xabc!
Hello 0xabc!

う、動いた!

仮想スイッチを複数にしたらどうなんだろう、trema.confで5台ほど設定してみます。

vswitch { datapath_id 0xa01 }
vswitch { datapath_id 0xa02 }
vswitch { datapath_id 0xa03 }
vswitch { datapath_id 0xa04 }
vswitch { datapath_id 0xa05 }

動いた!!

 $ trema run lib/hello_trema.rb -c trema.conf
Trema started.
Hello 0xa05!
Hello 0xa03!
Hello 0xa04!
Hello 0xa01!
Hello 0xa02!

ありえないほど、地味ですね。どうしよう。 しかし、言葉では表現できないほど楽しい。 f:id:dr_asa:20170511090208j:plain

まとめ

RaspberryPi3をつかって、Trema+OpenvSwitchが動く環境ができあがりました。 ビルドでは、いろいろなエラーが出て苦戦しましたが、Tremaのおきて「最後まで絶対に諦めずやりぬく心」があればできるな!ということが分かりました。

実は、RasbperryPiではなく、Ubuntuの普通のサーバで「OpenFlow実践入門」を読みながら一通り動かしているのですが、スイッチ監視ツール、インテリジェント・パッチパネル、ラーニングスイッチなど動きはしたものの理解ができているか、と言われれば理解は出来ていない部分も多々です。ネットワーク技術とRubyの実装がどっちも分かってないと、果てしなくアレなので、時間をかけて勉強していきたいと思います。

おわり