入門 MidoNet

まえ書き
=======

こんにちは、@tfukushima です。今回がQiitaへの初投稿となります。よろしくお願いします。今SpainはBarcelonaからこの記事を投稿しています。Barcelonaの写真が見たい方は[こちら](https://twitter.com/takufukushima)へどうぞ。

> **Note:** 本文中にこのようないくつかのNoteを書きましたが、基本的には読むのは必須ではなく、興味のある場合のみ読んでいただくのが良いと思います。

MidoNetとは
===========

![midonet-logo.png](https://qiita-image-store.s3.amazonaws.com/0/3704/ed3bb55d-61d8-0a54-4c92-4162e254dc73.png)

MidoNetはオープンソースのクラウドIaaS向けネットワーク仮想化プラットフォームです。以下の機能を提供します。

* 完全に仮想化された[L2](http://en.wikipedia.org/wiki/Data_link_layer)、[L3](http://en.wikipedia.org/wiki/Network_layer)そして[L4](http://en.wikipedia.org/wiki/Transport_layer)のネットワーキング
* VLANレス [VLAN](http://en.wikipedia.org/wiki/Virtual_LAN)
    - 従来のVLANの限界に縛られない仮想的なL2のアイソレーションとスイッチング
* [VXLAN](http://en.wikipedia.org/wiki/Virtual_Extensible_LAN)サポート
    - VXLAN tunnel zonesとVXLAN L2 Gateway
* Single point of failure(SPoF; 単一障害点)のない完全な分散アーキテクチャ
* 仮想L3分散ルーティング
* BGPサポート
* 分散ロードバランサ・ファイアウォール
* ステートフルおよびステートレスなNAT
* 遅延なしNATコネクショントラッキング
* Access Control Lists (ACLs)
* RESTful API
* ネットワークサービスのモニタリング

![Screen Shot 2014-12-01 at 12.34.29 PM.png](https://qiita-image-store.s3.amazonaws.com/0/3704/58b6ab6d-7e6a-04f3-1886-e301600672f3.png)

主な情報源
---------

* [公式サイト](midonet.org)
* [公式ドキュメント](http://docs.midonet.org/index.html)
* [公式Wiki](http://wiki.midonet.org/FrontPage)
* [公式ブログ](http://blog.midonet.org/)
* [midonet/midonet - GitHub](https://github.com/midonet/midonet)
* [MidoNet JIRA (issue tracker\)](https://midonet.atlassian.net/)
* [@midonet](https://twitter.com/midonet)
* [MidoNet meetup - connpass](http://midonet.connpass.com/)
* [メーリングリスト](http://lists.midonet.org/listinfo)
* [StackOverflow](https://stackoverflow.com/questions/tagged/midonet)
* IRC: #midonet on [freenode](https://freenode.net/)

過去の発表スライド
---------------

<iframe src="//www.slideshare.net/slideshow/embed_code/44770274" width="425" height="355" frameborder="0" marginwidth="0" marginheight="0" scrolling="no" style="border:1px solid #CCC; border-width:1px; margin-bottom:5px; max-width: 100%;" allowfullscreen> </iframe> <div style="margin-bottom:5px"> <strong> <a href="//www.slideshare.net/takufukushima79/introduction-to-mido-net" title="Introduction to MidoNet" target="_blank">Introduction to MidoNet</a> </strong> from <strong><a href="//www.slideshare.net/takufukushima79" target="_blank">Taku Fukushima</a></strong> </div>

<iframe src="//www.slideshare.net/slideshow/embed_code/44762433" width="425" height="355" frameborder="0" marginwidth="0" marginheight="0" scrolling="no" style="border:1px solid #CCC; border-width:1px; margin-bottom:5px; max-width: 100%;" allowfullscreen> </iframe> <div style="margin-bottom:5px"> <strong> <a href="//www.slideshare.net/takufukushima79/mido-net-deep-dive" title="MidoNet deep dive" target="_blank">MidoNet deep dive</a> </strong> from <strong><a href="//www.slideshare.net/takufukushima79" target="_blank">Taku Fukushima</a></strong> </div>

MidoNetのコンポーネント
====================

![MidoNet Architecture Overview.png](https://qiita-image-store.s3.amazonaws.com/0/3704/2e40151d-1e09-29a6-4e3d-e8a124573728.png)

Network State Database(NSDB)
-----------------------------

![Screen Shot 2015-02-14 at 10.59.01 PM.png](https://qiita-image-store.s3.amazonaws.com/0/3704/c1f49b7b-89b9-249e-459f-8d296e4fe6c4.png)


仮想ネットワークのトポロジを保存しておく場所です。すべての仮想ネットワーキングで必要な情報が保存されていて、SPoFになることを避けるためにレプリケーションされています。現在のMidoNetではZooKeeperとCassandraが使用されています。

Datapath
--------

名前の通り、datapathは各ホストに存在しVM間やホスト外部のネットワークと接続されているパケットの通り道です。実際にはdatapathはMidoNetの一部ではなく、MidoNetのrequirementsの一つになります。現在のMidoNetでは[Linux Kernelのmainlineに統合された](https://lwn.net/Articles/469775/)[**O**pen vSwitch **D**ata **p**ath (ODP)](http://openvswitch.org/)をサポートしています。

> **Note: Open vSwitch(OVS)とOpen vSwitch Datapath(ODP)**
> OVSは二つの部分に分かれています。kernel spaceに存在するdatapath(ODP)と[userland](http://en.wikipedia.org/wiki/User_space)に存在するそれを管理するユーティリティ群です。OpenFlowプロトコルを実装しているovs-vswitchdなどはuserlandにありますが、MidoNetではこれらuserlandに存在するOVSの機能は必要な場面以外では基本的に使用しておらず、ODPのみ利用しています。ODPとは[Netlink](http://www.linuxfoundation.org/collaborate/workgroups/networking/netlink)で直接やりとりしています。

他にも~~[Intel DPDK](http://dpdk.org/)を使用して高速なスイッチングを行なうことを目的とした[Intel® DPDK vSwitch (OVDK)](https://github.com/01org/dpdk-ovs)~~や総務省後援の[O3プロジェクト](http://www.o3project.org/)の一部である[Lagopus](http://lagopus.github.io/)などが存在します。

> **Note: OVDKの死**
> 先日IntelがOVSのフォークを止めてOVDKの開発を中止し、OVSのmainstreamにコミットすることを決定しました。
>
> * [Intel Dead-Ends Its Fork of Open vSwitch](https://www.sdncentral.com/news/intel-dead-ends-fork-open-vswitch/2014/11/)
> * [The Death of OVDK: Long Live Sustainable Software Architectures](http://www.6wind.com/blog/the-death-of-ovdk-long-live-sustainable-software-architectures/)

Midolman
---------

![Screen Shot 2015-02-14 at 10.57.33 PM.png](https://qiita-image-store.s3.amazonaws.com/0/3704/a6852252-5030-9c8d-8cc7-8547b7234690.png)


Midolmanは各ホスト上に存在するagentで、NSDBの情報をキャッシュしており、ホスト上のVMからのトラフィックが通過するdatapathを制御します。実際にはパケットにマッチするflow ruleが無かった場合に起こるdatapathからのupcallに対応し、仮想ネットワークトポロジ上でのパケットフローをシミュレーションした上で導き出されたflow ruleを新たにdatapathへ追加します。

> **Note: OpenFlow controllerではないMidolman**
> Midolmanが登場した背景には[OpenFlow](https://www.opennetworking.org/sdn-resources/onf-specifications/openflow)という規格の登場とOpenFlowに対応したソフトウェアによる仮想スイッチのリファレンス実装であるOpen vSwitchが関わっています。Midolmanは当初はuserlandの機能を含むOpen vSwitchを使用していましたが、現在はOpenFlowを実装しているとい言えるuserland部分を基本的に使用しておらず、独自のflow ruleによるforwardingを行なうようになっています。

MidolmanはNSDBをwatch(ZooKeeper用語; 一般的にはsubscribeまたはlisten)しており、仮想ネットワークトポロジの状態が更新された場合にはNSDBへ変更を書き出し、NSDBが変更をすべてのwatcherに通知します。

また、forwardすべきポートが別ホストのdatapathに存在する場合にはパケットをencapsulationして対象のホストへトンネリングします。

MidolmanはJavaとScalaで書かれています。パケットのシミュレーションを効率的に処理するために[Future](http://docs.scala-lang.org/overviews/core/futures.html)が多用され、[RxJava](https://github.com/ReactiveX/RxJava)や[Akka](http://akka.io/)も使用されています。Midolmanの内部構造などは別途まとめられたら良いなぁ、と思っています。

> **Note: 元々はPythonで書かれていたMidolman**
> 実はJavaで書き直される前にはMidolmanはPythonで書かれていました。若かりし頃の自分は「Pythonで何か面白いことができる!」と喜び勇んでいたのですが、ある日「Javaで書き直す」と[CEO兼CTO](http://www.midokura.com/management-team/)に言われ、「えっ...」という感じで途方に暮れたり「C++じゃダメなのか?」と言ってみたり["Revenge of the Nerds"](http://www.paulgraham.com/icad.html)を見せてチクチク攻撃したりしながらもカウンターとしてScalaを導入した覚えがあります。ちなみに残念ながら歴史的にJava7で始められたMidolmanのJava部分はまだJava8で書かれていないのですが、移行による影響などを解決してから移行していく予定です。PythonはOpenStackとのインテグレーションや後述のMidoNet CLIなどで広く使用されています。ソフトウェアにもそれに関わる人間にも色々と歴史がありますね。

Midolmanはそのまま「ミドルマン」と発音します。middle man、middleware manのような意味で名付けられたようですが、実は詳細な経緯は僕も知りません。ちなみに[Middleman](http://middlemanapp.com/)というgemがありますが、関係ありません。

MidoNet REST API
-----------------

![Screen Shot 2015-02-14 at 11.02.17 PM.png](https://qiita-image-store.s3.amazonaws.com/0/3704/83de96a3-3818-0277-d847-2726409295ba.png)


MidoNet REST APIはMidoNetの機能を使用するためのRESTfulなHTTP APIサーバです。以下にREST APIのドキュメントがまとめられています。

* [MidoNet API Specification (Latest) (Sphinx)](http://docs.midonet.org/docs/latest/rest-api/content/index.html)
* [MidoNet REST API (AsciiDoc)](https://github.com/midonet/midonet-docs/blob/master/docs/rest-api/src/rest_api.adoc)

REST APIはAuthn/Authzなしで動かすことも可能ですが、MidoStackを使用して環境を構築した場合にはにはOpenStackの[Keystone](http://docs.openstack.org/developer/keystone/)が使用されています。

> **Note: 突然の死**
> 折角MidoNet REST APIの説明をしてきましたが、**MidoNet REST APIは将来的に取り除かれる予定です。**MidoNet REST APIはNeutronによって置き替えられ、ユーザはNeutronの提供するREST APIを使用することになります。MidoNetを使用する場合にはNeutronのpluginとしてMidoNet Pluginが指定され、MidoNet PluginはRPCでNSDBとやりとりするproxyのような存在になる予定です。

MidoNet CLI
------------

MidoNet CLIはMidoNet REST APIをコールするCLIです。もちろん`curl`でも同様のことはできますが、毎回tokenをHTTPヘッダに指定しなければいけない手間などを考えるとずっと使いやすいと思います。

> **Note: 突然の死 パート2**
> 折角MidoNet CLIの説明をしてきましたが、**MidoNet CLIは将来的に取り除かれる予定です。**MidoNet CLIはNeutron CLIによって置き替えられ、ユーザはNeutron CLIを使用してMidoNetの設定を行なうことになります。Neutron APIがOpenStackにおける仮想ネットワーク APIの標準となるためです。Neutron APIはPOSIX APIと似ていると言うとイメージしやすいかもしれません。

MidoNet Manager
---------------

いわゆるWebUIです。すみません、[Midokura Enterprise MidoNet](http://www.midokura.com/midonet-enterprise/)限定です。痛い、石を投げないで!

MidoNetをインストールする
======================

MidoStackでインストール (推奨)
---------------------------

@jedipunkz さんがご自身のブログで早速試してくださった過程を書いてくださっています。ありがとうございます。

* [MidoStack を動かしてみる - Jedipunkz's Blog](http://jedipunkz.github.io/blog/2014/11/04/midostack/)

OpenStackに慣れていらっしゃるようで、というよりOpenStackでクラウド基盤を構築されている方のようで、途中でMidoStackが止まった場合でも最後まで到達されていて流石です。

### MidoStackとは

MidoStackは[DevStack](http://docs.openstack.org/developer/devstack/)にMidoNet用のパッチを適応し、一つのスクリプトを実行するだけでOpenStack+MidoNet環境を構築できるようにするプロジェクトです。MidoNet PluginがNeutronのpluginとして指定された上で基本的なMidoNetの設定が終わった状態の環境を作ることができます。CI上でのテスト環境を構築する際に使用されることもあります。

> **Note: DevStackは辛いよ**
> スクリプト一発でOpenStackの環境ができあがるDevStack、「何て素晴しいんだ!」と思われるかもしれません。確かにDevStackは素晴しいツールで、うまくscriptが実行し終った時は爽快ですね。しかし、実際に最後までscriptがうまく実行し切ることは実はなかなかありません。DevStackのmasterを使用すると失敗することは多々あります。理由はscriptがうまく動かない、Pythonパッケージのdependencyがおかしい、リポジトリが一時的にダウンしているなど様々です。DevStackは基本的にはShellScriptの集まりなので、途中で失敗したらそこで止まってしまいます。MidoStackはDevStackで環境を構築した後にMidoNet固有の設定を行なうので、途中DevStackが失敗してしまった場合にはMidoStackも失敗してしまいます。

MidoStackを実行するのはとても簡単です。以下のように`midostack`ディレクトリにある`midonet_stack.sh`を実行するだけです。最後に"Midostack has successfully completed in `t` seconds."(`t`はスクリプトの実行時間)というメッセージが出れば正常に完了したことになります。

```
$ cd midostack
midostack$ ./midonet_stack.sh
...
==================================
Executing post devstack scripts...
==================================
Executing /home/ubuntu/midostack/scripts/post_devstack.d/005.add_rootwrap_for_nova_neutron.sh... [OK]
Executing /home/ubuntu/midostack/scripts/post_devstack.d/010.setup_dot_midonetrc.sh... [OK]
Executing /home/ubuntu/midostack/scripts/post_devstack.d/015.install_midonet_cli.sh... [OK]
Executing /home/ubuntu/midostack/scripts/post_devstack.d/020.setup_fake_uplink.sh... [OK]
Executing /home/ubuntu/midostack/scripts/post_devstack.d/030.configure_libvirt.sh... [OK]
Midostack has successfully completed in _ seconds.
```

**DevStack、MidoStackはシステムグローバルにdependencyをインストールしますので、手元の環境を汚したくない場合にはVagrantを使用してください。**要求システムはmidostackの`README.md`、["Requirements"](https://github.com/midonet/midostack#requirements)では*"Ubuntu 14.04 with 4GB of RAM + swap"*となっています。割り当てメモリが少ないとDevStackが失敗することがありますので、注意してください。

もし途中でMidoStackが止まってしまうことがあった場合、まずはunstackしてから再びstackしてみましょう。

```
midostack$ ./midonet_unstack.sh
midostack$ ./midonet_stack.sh
```

> **Note: DockerとMidoNet**
> MidoStackが正常に終わるためには時間がかかり、DevStackに依存しているため最後まで走り切るとは必ずしも限りません。現在このプロセスを改善するためにMidoNetのDockerイメージを用意するという議論がML上で開始されています。
>
> * [\[MidoNet-dev\] Towards a docker-based midostack](http://lists.midonet.org/pipermail/midonet-dev/2014-November/000223.html)
>
> **UPDATE**
>
> * [\[MidoNet\] Fwd: Introducing MidonetDockerfile](http://lists.midonet.org/pipermail/midonet/2014-December/000046.html)
>
> 各Linuxディストリビュション向けの各MidoNetコンポーネント用`Dockerfile`と`fig.yml`を含む`midonet-dockerfile`の提供を試験的に開始しました。**`midonet-dockerfiel`はOpenStackを含まずMidoNetコンポーネント(Midolman, MidoNet APIおよびMidoNet CLIに加えてZooKeeperとCassandra)のみを含むことに注意してください。**
>
> * [midonet/midonet-dockerfile - GitHub](https://github.com/midonet/midonet-dockerfile)

### Vagrantを使用する場合 (推奨)

[`Vagrantfile`](https://github.com/midonet/midostack/blob/master/Vagrantfile)が`midostack`トップディレクトリに含まれているので、それを使用してください。現在のmidostackディレクトリは`/midostack`へマウントされます。

```
$ git clone http://github.com/midonet/midostack
$ cd midostack
midostack$ vagrant up
...
midostack$ vagrant ssh
vagrant@vagrant-ubuntu-trusty-64:~$ cd /midostack
vagrant@vagrant-ubuntu-trusty-64:/midostack$ ./midonet_stack.sh
...
Midostack has successfully completed in 372 seconds.
vagrant@vagrant-ubuntu-trusty-64:/midostack$ screen -x mido
```

### Bare metalなUbuntuマシンを使用する場合

再掲ですが、*DevStack、MidoStackはシステムグローバルにdependencyをインストールしますので、手元の環境を汚したくない場合にはVagrantを使用してください。* 僕は**MidoStackを実行することで生じる損害に対する責任を何ら負いません。** 

```
$ git clone http://github.com/midonet/midostack
$ cd midostack
midostack$ ./midonet_stack.sh
...
Midostack has successfully completed in 372 seconds.
midostack$ screen -x mido
```

## DockerとFigでインストール (Beta)

この方法では[Docker](https://www.docker.com/)と[Fig](http://www.fig.sh/)を使用してMidoStackを使用せず、**MidoNetコンポーネントのみをインストールします。**手軽にMidoNetがどのように構成されているのかを確認したり、開発やCIをする上で有用です。Dockerのインストール方法などは省略しますので、[Docker公式サイトのドキュメント](https://docs.docker.com/installation/)にて確認してください。

なお、DockerとFigでのインストールであってもkernel moduleとしてホストにODPをインストールしなければならず、システムグローバルな環境を汚染するので、Virtual BoxなどのVMを使用することをお勧めします。**しつこく再掲して申し訳ありませんが、僕はDockerとFigによってMidoNetをインストールすることで生じる損害に対する責任を何ら負いません。**

### ODPがkernel moduleとしてロードされていることを確認

作成されるDockerイメージはホストにOpen vSwitchのkernel moduleがインストールされていることを仮定します。Ubuntuでは`openvswitch-datapath-dkms`という名前でdebパッケージが提供されているので、aptなどでインストールしてください。インストール後は以下のコマンドでkernel moduleがロードされていることを確認してください。

```
$ sudo modprobe openvswitch
$ sudo lsmod | grep openvswitch
openvswitch            66901  0 
gre                    13796  1 openvswitch
vxlan                  37619  1 openvswitch
libcrc32c              12644  1 openvswitch
```

### midonet-dockerfileをGitHubよりcloneする

各Linuxディストリビューション用の`Dockerfile`と`fig.yml`より構成されている`midonet-dockerfile`をGitHubのリポジトリよりcloneします。

* [midonet/midonet-dockerfile - GitHub](https://github.com/midonet/midonet-dockerfile)

```
$ git clone http://github.com/midonet/midonet-dockerfile
```

### Figをインストール

Figがインストールされていない場合、以下のコマンドでインストールしてください。環境を汚染したくない場合、[virtualenv](http://virtualenv.readthedocs.org/en/latest/)や[virtualenvwrapper](http://virtualenvwrapper.readthedocs.org/en/latest/)を使用してください。

```
$ sudo pip install fig
```

### FigでMidoNetをデプロイする

`fig.yml`を含む`midonet-dockerfile`のトップディレクトリで以下のコマンドを実行してください。

```
$ cd midonet-dockerfile
$ fig up -d
```

各コンポーネント用のDockerイメージが作成されます。

```
Creating midonetdockerfile_zookeeper_1...
Pulling image midonet/zookeeper...
e284c89a84c9: Download complete
511136ea3c5a: Download complete
01bf15a18638: Download complete
30541f8f3062: Download complete
e1cdf371fbde: Download complete
9bd07e480c5b: Download complete
b5b5adea0a69: Download complete
a1e9388d25b9: Download complete
7af7e7e33a06: Download complete
Status: Downloaded newer image for midonet/zookeeper
Creating midonetdockerfile_api_1...
Pulling image midonet/midonet-api...
5e17eb055344: Download complete
511136ea3c5a: Download complete
01bf15a18638: Download complete
30541f8f3062: Download complete
e1cdf371fbde: Download complete
9bd07e480c5b: Download complete
b5b5adea0a69: Download complete
2941ef71600c: Download complete
f4836f3f64c5: Download complete
7efb46c32c04: Download complete
cdb8a2b45b92: Download complete
0d988203b28b: Download complete
1a7edcccacbf: Download complete
376e5fbb72a5: Download complete
2c860c715c0e: Download complete
Status: Downloaded newer image for midonet/midonet-api
Creating midonetdockerfile_cli_1...
Pulling image midonet/midonet-cli...
c87db896136e: Download complete
511136ea3c5a: Download complete
01bf15a18638: Download complete
30541f8f3062: Download complete
e1cdf371fbde: Download complete
9bd07e480c5b: Download complete
b5b5adea0a69: Download complete
2941ef71600c: Download complete
f4836f3f64c5: Download complete
3570c94b2d03: Download complete
9d17148ea9f0: Download complete
cc20a98f046f: Download complete
dec0462f7520: Download complete
Status: Downloaded newer image for midonet/midonet-cli
Creating midonetdockerfile_cassandra_1...
Pulling image midonet/cassandra...
ee3236fd22a0: Download complete
511136ea3c5a: Download complete
01bf15a18638: Download complete
30541f8f3062: Download complete
e1cdf371fbde: Download complete
9bd07e480c5b: Download complete
b5b5adea0a69: Download complete
12ae10aae0ac: Download complete
b2b832a54354: Download complete
e53b3f9a60f0: Download complete
8e5b6d34687f: Download complete
efe6442e72ff: Download complete
7c2a037ae86e: Download complete
d3e5b2a59e11: Download complete
e3201e6e5432: Download complete
Status: Downloaded newer image for midonet/cassandra
Creating midonetdockerfile_midolman_1...
Pulling image midonet/midolman...
c44a66aaaa2e: Download complete
511136ea3c5a: Download complete
01bf15a18638: Download complete
30541f8f3062: Download complete
e1cdf371fbde: Download complete
9bd07e480c5b: Download complete
b5b5adea0a69: Download complete
5ba35a02097f: Download complete
508f1d1c564b: Download complete
97489ffb5d39: Download complete
7dca77f2fedf: Download complete
fdfb544601c7: Download complete
8e087fc50b13: Download complete
Status: Downloaded newer image for midonet/midolman
```

### MidoNet CLIを試してみる

以下のコマンドでMidoNet CLIがインストールされたDockerイメージで`midonet-cli`が実行されます。

```
$ fig run cli midonet-cli
midonet>
```

MidoStackを使用した場合と異なり、最初は何もリソースがありません。MidoStackではOpenStack用にProvider Routerなどが作成されていました。

```
midonet> list router
midonet> list bridge
```

現時点ではまだDockerやKubernetesなどとの直接的なインテグレーションはされておらず、`midonet-dockerfile`はDockerized MidoNetのみを提供するものです。

## .debまたは.rpmでインストール

[repo.midonet.org](repo.midonet.org)よりダウンロードしてください。

インストール後の確認
-----------------

"Midostack has successfully completed in `t` seconds."というメッセージが出てMidoStackが正常に完了した後には`mido`という名前でscreenセッションが作られます。これはDevStackが`stack`というscreenセッションを作成するのに倣っています。

このscreenセッションではMidoNetのコンポーネントを使用するのに必要な設定などが既に適応されています。以下のコマンドでscreenセッションへattachしてください。

```
$ screen -x mido
```

### MidoNet CLIを試してみる

こちらも@komeiyさんが試してくださっています。

- [midonetをインストールして基本コマンドを叩いてみる](http://komeiy.hatenablog.com/entry/2014/11/13/012401)

失礼ながらIRCで海外の方がブログに言及するまで寡聞にして存じ上げなかったのですが、このエントリ以外にもOpenStack関連のものだけでなく様々なトピックがあって大変参考になります。第20回日本OpenStackユーザ会(Neutron deep dive)に参加できなかったので、以下の記事はとてもありがたく読ませていただきました。

- [日本OpenStackユーザ会(Neutron deep dive)に参加してきた](http://komeiy.hatenablog.com/entry/2014/12/02/224940)

`mido`セッションに入った後、MidoNet CLI(以下CLI)を起動してみましょう。すべてのPATHなど必要な情報が設定されているため、以下のコマンドで起動できます。

```
$ midonet-cli
midonet>
```

試しにルータ(Router)やブリッジ(Bridge)を表示してみましょう。

```
midonet> list router
router router0 name MidoNet Provider Router state up
router router1 name router1 state up infilter chain0 outfilter chain1
midonet> list bridge
bridge bridge0 name public state up
bridge bridge1 name private state up
```

表示できたでしょうか?今度はルータやブリッジのポート(Port)を表示してみましょう。

```
midonet> list router router0 port
port port0 device router0 state up mac ac:ca:ba:1b:5a:a5 address 172.19.0.2 net 172.19.0.0/30
port port1 device router0 state up mac ac:ca:ba:cd:22:99 address 200.200.200.1 net 200.200.200.0/24 peer bridge0:port0
port port2 device router0 state up mac ac:ca:ba:9d:fb:ed address 169.254.255.1 net 169.254.255.0/30 peer router1:port0
```

デフォルトでCLIはインタラクティブモードになりますが、以下のように`-e`または`--eval`オプションで1コマンドのみ実行することもできます。

```
$ midonet-cli -e 'list router'
router 898f63ab-2b06-4448-a58d-4f8c50baf634 name MidoNet Provider Router state up
router d20f78e6-2bba-4290-b8d9-2658cdf3471f name router1 state up infilter 464f1b10-9172-4565-8d25-2b9511aa8ed8 outfilter 20b2a520-40c6-4a56-9a30-e235e26bfe96
```

これらのオプションは`-h`または`--help`オプションを使用することで見ることができます。

```
$ midonet-cli -h
Usage: midonet-cli [options]
 
Options:
  -h, --help            show this help message and exit
  -A, --no-auth         Skip authentication
  --midonet-url=URL     Midonet API server URL
  -u USERNAME, --user=USERNAME
                        Username
  -i PROJECT_ID, --project-id=PROJECT_ID
                        Midonet Project ID
  --tenant=UUID         Tenant id
  -e, --eval            Evaluate a single command, given at the end of the
                        argument list
  -p, --password        Ask for password interactively
  -d, --debug           Enable debugging
```

> **Note: 困ったときの`help`と`debug on`/`debug off`**
> CLIを実行していると困る局面に遭遇することがあると思います。何をしたら良いか分からなければ`help`コマンドを、何が起きてるか分からなくてデバッグ情報が欲しい場合には`debug on`コマンドを使用してデバッグモードに入ってみてください。デバッグモードから抜けるには`debug off`を使用してください。

ちなみにCLIはreadlineライクな補完機能を持っていますので、事あるごとに`Tab`や`Ctrl-I`を押して補完すると非常に便利です。例えば、`list router router0`まで入力してから`Tab`を入力し、補完してみましょう。

```
midonet> list router router0 
port  route
```

`router`というリソースのサブリソース(URIで言えば[`/routers/:routerId/ports`など](http://docs.midonet.org/docs/latest/rest-api/content/port.html))に`port`と`route`というものがあることが分かります。他の場面でもこの補完機能は非常に強力ですので、是非試してみてください。

次に何かリソースを作成してみましょう。[ルール(Rule)](http://docs.midonet.org/docs/latest/rest-api/content/rule.html)などがいいかもしれません。ルールはいわゆるflow ruleで、パケットに対するパターンマッチとそれに対してdispatchする処理を記述するこができます。ルールは[チェイン(Chain)](http://docs.midonet.org/docs/latest/rest-api/content/chain.html)に複数含まれており、その順番(`position`)通りに適応されます。ChainとRuleを使用してNATなどを行なうことができます。ざっくり言えば[iptables](http://www.netfilter.org/projects/iptables/index.html)のように使えます。では、簡単なルールを作ってみましょう。その前に、どのようなパラメータを渡せるのか`describe`(または`desc`)コマンドで調べてみましょう。

```
midonet> desc chain chain0 rule 
Object collections:
    <NONE>
Fields:
    id           ethertype  src-port              ip-address-group-dst  pos    
hw-src       src        dst-port              in-ports              type   
hw-src-mask  dst        flow                  out-ports             action 
hw-dst       proto      port-group            fragment-policy       jump-to
hw-dst-mask  tos        ip-address-group-src  chain                 target 
```

かなり色々ありそうですね。ルールは最もパラメータが多いリソースです。最初は小さく始めましょう。

```
midonet> create chain chain0 rule dst 8.8.8.8/32 type drop 
chain0:rule2
```

ルールを作成した時に`chain0:rule2`という結果が表示されました。全てのリソースにはUUIDが割り当てられますが、長い上に見にくいので簡単のためにこのように`リソース名+番号`というエイリアス(Alias)を付けています。**注意していただきたいのは、このエイリアスは現在のCLIセッションでのみ有効だということです。** 次回CLIを起動した時はこのエイリアスが変わるかもしれません。エイリアスを使用したくない場合には`-e`オプションでノンインタラクティブモードを使用してください。

ところで、このルールは`8.8.8.8`(GoogleのDNSサーバ)へのパケット(`dst`で指定)をすべてドロップ(`type drop`で指定)します。これはヤバいルールですね。作った矢先なのですが、早速削除しましょう。

```
midonet> delete chain chain0 rule rule2
```

このようにCLIはREST APIのリソースの階層と対応するCRUD操作へのアクセスを簡単にします。より詳しい情報や目的別の設定方法などは下記オペレーションガイドを参照してください。

* [MidoNet Operation Guide](http://docs.midonet.org/docs/latest/operation-guide/content/index.html)

コントリビュートする
=================

ここまででMidoNetに興味を持っていただけたら嬉しいのですが、もしコントリビュートされたいと思われたとしたらとても嬉しいです。ここではどのようにMidoNetへコントリビューとすれば良いかを説明します。

コントリビュートする方法の詳細は以下のように`README.md`やWikiに記述されています。

* [How to contribute - midonet/midonet](https://github.com/midonet/midonet#how-to-contribute)
* [Contributing to MidoNet](http://wiki.midonet.org/How%20to%20contribute)

オープンソース前にはMidokura内部で独自に[Gerrit](https://code.google.com/p/gerrit/)をホストしていました。オープンソース化に伴なって、GitHubインテグレーション付きの[GerritHub](http://gerrithub.io/)へ移行しました。GerritHubによってGitHubへポストされたPull Requestが簡単にインポートできます。

> **Note: なぜGitHubのPull Requestでなく、Gerritなのか?**
> Gerritは[Android](https://android-review.googlesource.com/#/q/status:open)、[Chromium](https://chromium-review.googlesource.com/#/q/status:open)や[OpenStack](https://review.openstack.org/#/q/status:open,n,z)で使用されているコードレビューツールです。最近では[GoもGitHubへ移動しつつもコードレビューはGerritを使用することが決まりました。](https://groups.google.com/forum/#!topic/golang-dev/sckirqOWepg)現在MidoNetはOpenStackのネットワークコンポーネント[Neutron](https://wiki.openstack.org/wiki/Neutron#What_is_Neutron.3F)のバックエンドとして使用されることを想定されていて、コミットごとに*gate*と呼ばれるOpenStackのpre-commitテストがCIによって実行され、これによってNeutronの要件を満たすかを毎回チェックしています。また、それに加えてMidoNetのユニットテストや*MidoNet Distributed Testing System (MDTS)*によるgateも実行されます。OpenStackがGerritを採用しているためgateはGerritとの親和性が非常に高くなっています。MidokuraではNeutronのMidoNet pluginも開発しており、OpenStackの開発も同時に行なっているためワークフローを統一するという観点でGerritが採用されました。
>
> OpenStackの開発者によるGitHubとGerritの比較が以下のリンクより辿れるので、よろしければご参照ください。
>
>   * [Rant about Github pull-request workflow implementation | Julien Danjou](https://julien.danjou.info/blog/2013/rant-about-github-pull-request-workflow-implementation)

Contributor License Agreement (CLA)へサインする
---------------------------------------------

以下のサイトへアクセスし、条項を読んだ後CLAへサインしてください。

* [MidoNet Contributor License Agreement (CLA)](https://rightsignature.com/forms/Midokura-Contribu-70cd64/token/8ad6e7b19d8)

git-reviewをインストールする
-------------------------

パッチをコードレビューシステムへ投稿するにはgit-reviewをインストールし、GerritサーバをGitのremoteリポジトリとして登録します。以下はグローバル環境へgit-reviewをインストールする方法ですが、環境を汚染したくない方は[vitualenv](http://virtualenv.readthedocs.org/en/latest/)や[virtualenvwrapper](http://virtualenvwrapper.readthedocs.org/en/latest/)を使用してください。

```
$ sudo pip install git-review
```

GerritHubをリモートリポジトリ`gerrit`として登録する
---------------------------------------------

git-reviewをインストール後にGerritHubをGitのremoteジポジトリに追加します。設定は[`.gitreview`](https://github.com/midonet/midonet/blob/master/.gitreview)に書いてあるので、以下のコマンドをMidoNetのトップディレクトリで実行するだけです。

```
$ git-review -s
$ git remote show gerrit
* remote gerrit
  Fetch URL: ssh://tfukushima@review.gerrithub.io:29418/midonet/midonet
  Push  URL: ssh://tfukushima@review.gerrithub.io:29418/midonet/midonet
  HEAD branch: master
  Remote branch:
    master tracked
  Local ref configured for 'git push':
    master pushes to master (local out of date)
```

コードを変更する
-------------

作業を開始する前に現在のワーキングツリーが最新であることを確かめておくと後でconflictが起きにくくなります。また、新たに作業用のブランチを作成すると良いでしょう。以下のコマンドで`origin`は[midonet/midonet](https://github.com/midonet/midonet)のリモートリポジトリ名です。

```
$ git fetch origin
$ git checkout origin/master -b new_branch_name
```

ワーキングツリーでコードを変更し、コミットしましょう。コミットメッセージは英語で一行目にサマリを、2行目に空行を入れて3行目以降はコミットの詳細な説明を記述してください。コミットは`-s`オプションで[sign-off](http://stackoverflow.com/questions/1962094/what-is-the-sign-off-feature-in-git-for)を追加することが奨励されます。

```
$ git add -p
$ git commit -s
```

パッチを投稿する
-------------

ワーキングツリーでコードを変更してコミットを作成し、パッチを投稿する準備ができたところで現在のパッチが最新のmasterブランチへ適応できることを確認しましょう。

```
$ git fetch origin
$ git rebase origin/master
```

そしていよいよパッチをGerritHubへ投稿します。初めて投稿する時はドキドキしますね。git-reviewをインストールしていれば`git`コマンドに`review`というサブコマンドが追加されています。自分の変更が何であるかを示すために`-t`オプションで分かりやすいタグ名を付けておきましょう。ある機能を追加するためにパッチが複数あった場合にそれらをグルーピングするのにも役立ちます。

```
$ git review master -t tag
```

パッチが複数個あった場合には確認のプロンプトが出ますので`yes`と入力してください。

> **Note: [GerritとRietveld](https://code.google.com/p/gerrit/wiki/Background)**
> Gerritはオランダ人の家具デザイナー/建築家の[Gerrit Rietveld](http://en.wikipedia.org/wiki/Gerrit_Rietveld)にちなんで名付けられました。[Rietveld](https://cloud.google.com/appengine/articles/rietveld)はGoogleの社内コードレビューツール[であった](https://news.ycombinator.com/item?id=8605997)Mondrianのオープンソース版であり、Python作者の[Guido van Rossum](https://www.python.org/~guido/)によって作られました。GerritはAndroid Open Source Projectが採用したGit向けレビューコードシステムの必要性から始まり、Rietveldへのパッチを経て現在ではGoogle App Engine上のPython実装からJ2EEサーブレットコンテナ上のJavaアプリケーションとなっています。

まとめ
=====

この記事ではMidoNetの概要と導入を紹介しました。より詳細なアーキテクチャやコードの説明は追って投稿したいと思います。待てない方は[`docs`](https://github.com/midonet/midonet/tree/master/docs)以下にあるドキュメント、例えば[`midolman.md`](https://github.com/midonet/midonet/blob/master/docs/midolman.md)から始めてみるのが良いと思います。また、英語になりますが[Midolmanのcode walk-through](https://www.youtube.com/playlist?list=PL3jhmuwWx3RxH4oro_hRq-kUOC8j2z_ps)をYouTube上でプレイリストとして公開しています。ご興味のある方はぜひご覧ください。Chromecastで大画面に写して見ると快適かもしれません。

### Disclosure

私はMidoNetを開発している[Midokura](http://www.midokura.com/)で働いています。しかし、MidoNetコミュニティでの活動で述べられていることは私の個人的な意見に基づくものであり､私の雇用者には一切の関係はありません。この記事は勤務中および勤務外に書かれましたが、現在は会社の出張でSpainのBarcelonaへ来ています。