Tech Sketch Bucket of Technical Chips by TIS Inc.

OpenDaylightアプリケーションの作り方

Pocket

近年の仮想化技術の進化に伴い、ネットワークをソフトウェアによって柔軟に設計、構築、運用するSoftware-Defined Networking(SDN)が適用され始め、これを実現するための様々なSDNコントローラやプラットフォームが台頭してきています。 OpenDaylight は、 Linux Foundation 内で発足した、オープンソースのSDNコントローラプラットフォームの協業開発プロジェクト、およびそのソフトウェアです。プロジェクトには著名な通信機器関連企業を始め、数多くのコミッタが参加しており、米国時間の2014年2月4日に初期リリースであるHydrogenが公開され、話題になりました。

今回の記事では、OpenDaylightの簡単な概要と、アーキテクチャやOpenDaylightアプリケーションの作成方法を中心にご紹介します。


OpenDaylightとは

OpenDaylightは、オープンソースのSDNコントローラプラットフォームです。OSGi(後述)を採用することで多様なコントローラ実装をBundleとして追加する機構を持ち、コントローラ自体を停止させることなく機能の追加削除ができるようになっています。

OpenDaylight Hydrogenリリースには、

  • 基本機能を持つ、評価や研究向けの Base Edition
  • マルチテナントネットワークを実現するネットワーク仮想化機能が追加された、データセンター向けの Virtualization Edition
  • 経路制御やネットワーク監視機能が追加された、プロバイダやキャリア向けの Service Provider Edition

がありますが、今回はHydrogenリリースのBase Editionを対象に話を進めます。

OpenDaylightのアーキテクチャ

OpenDaylightはjavaで実装されており、実体はOSGi Frameworkと、その上で動作するBundle群です。大きく分類すると

  • コントローラ操作を外部から可能にするNorthbound API (OpenDaylight API)
  • 具体的なコントローラアプリケーションを実装していくコントローラプラットフォーム
  • 通信機器との実際のやりとりを担うSouthbound API

で構成されています。

opendaylight01.jpg
http://www.publickey1.jp/blog/13/ibmbrocadejuniperbig_switchvmwaresoftware-defined_networkingopendaylight.html より引用)

Base Editionに含まれる主な機能には、

  • Northbound API
    • ユーザ管理や、コントローラプラットフォームの各機能を外部からコントロールできるREST API
  • コントローラプラットフォーム
    • ネットワークトポロジを構築するTopology Manager
    • 統計情報を収集、管理するStatistics Manager
    • 機器を管理するSwitch Manager
    • 機器のFlowを管理するForwarding Rules Manager
    • 機器に接続されたホストの追跡を行うHostTracker
    • ARPパケットを処理するARP Handler
    • SAL(後述)に含まれるデータ処理機能
  • Southbound API
    • OpenFlow
    • NETCONF
    • OVSDB

があり、これらもBundleとして実装されています。

base_edition.jpg
http://www.opendaylight.org/software/base-edition より引用)

OSGiとは

先程から出現している OSGi とは、javaによるサービスプラットフォームおよびサービスの仕様です。実行環境であるOSGi Frameworkのプロセス空間上で、様々な処理(Service)を提供するモジュール(Bundle)群が相互連携しながら動作し、プロセスを停止させることなくBundleの追加や削除をローカルまたはリモートから行うことができます。このような特徴と、Javaさえ動作すればどこでもOSGi FrameworkおよびBundleが動作する特徴などから、組み込み分野で多く紹介されています(というより、当初は機器内で動作させる目的のものでした)。

組み込み以外でOSGiを採用したソフトウェアとして有名なのはEclipseで、OSGi Frameworkには Equinox が使用されています。今回のOpenDaylightでは、実行基盤としてEquinoxを、BundleとServiceのライフサイクルや依存性管理に Apache Felix の機能(DependencyManager)を利用する形態をとっています。

Service Abstraction Layer(SAL)

OpenDaylightには Service Abstraction Layer(SAL) という層が存在します。これはSouthbound APIとコントローラプラットフォーム、Northbound APIの間のデータ交換や変換を担う層で、さまざまなプロトコルに対応できるようプラグインの追加を可能にしたり、そのデータをOpenDaylightアプリケーション(ComponentやNetwork Service Functionとも呼ばれる)で処理可能にしたりするもので、非常に重要なものです。

これも実体はBundleとして実装され、OSGi Framework上で動作しています。OpenDaylightアプリケーション、Southbound API・Northbound API実装であるプラグインや、GUIのBundleは、SALが公開するServiceを利用し、データを交換、処理します。

600px-Service_Abstraction_Layer.jpg
https://wiki.opendaylight.org/view/OpenDaylight_Controller:Architectural_Framework より引用)

現在、SALにはアプローチの異なるAPI-Driven SAL(AD-SAL)とModel-Driven SAL(MD-SAL)の二種類の概念が存在します。MD-SALのほうが後発で、モデルからSouthbound APIとNorthbound APIを自動生成するなどが可能となり、AD-SALとは実装の方法も異なりますが、SAL自体の目的としては変わりません。Hydrogenリリースでは、OpenFlow1.0はAD-SAL、OpenFlow1.3はMD-SALで実装されています。

OpenDaylightアプリケーションの作成

上記で、OpenDaylightアプリケーションはOSGi Framework上で動作するBundleであることを説明しました。今回は、手始めにAD-SALを利用する形で実際にOpenDaylightアプリケーションの作成手順と例を見てみます。

Eclipse、Mavenからの作成

Bundleの実体は、特定のManifestファイル、および特定のインタフェースや手続きを実装するクラス群を格納したjarファイルですが、Bundle作成にはMavenを利用するのが近道です。実際にOpenDaylightの各コンポーネントはMavenで作成されています。任意のエディタとコマンドラインで作成してもよいですが、より簡単に作成するためにEclipseを使用します。現在公開されているEclipse 4.3ではMavenと連携するためのm2eプラグインが同梱されており、これにはMaven3が付属しているため、EclipseをインストールするだけでOpenDaylightアプリケーションをビルドすることができます。

HelloWorld

今回は手始めに、AD-SALで対応するOpenFlow1.0のスイッチを対象としたシンプルなレイヤ2スイッチを実装してみます。具体的にはPACKET-INイベントでMACアドレスを学習して、対象スイッチにFlowを設定するようなBundleを作成し、OpenDaylightのOSGi Frameworkにロードして実行します。本記事にはソースコードの抜粋のみ記載しますが、今回使用するソースコード全体は以下に配置してありますので、適宜参照下さい。
HelloWorld ソースコード

今回のOpenDaylightアプリケーション作成の流れの概要は、以下のとおりです。

  1. pom.xmlの作成
    1. packagingをbundleにし、buildでmaven-bundle-pluginを指定することで、OSGi Bundleの作成を定義
    2. 必要なOpenDaylightのライブラリをdependencyに記述
  2. ソースコードの作成
    1. Activatorにて、HelloWorldで利用する他のサービスの定義や、パケット受信時のコールバック登録
    2. HelloWorldにて、SALのインタフェースを実装し、Forwarding、Floodingなどのパケット処理を実装

まず、EclipseからMavenプロジェクトを作成し、pom.xmlにビルド情報や依存関係設定します。プロジェクトは、Maven Simple Projectで構いません。

成果物の指定であるPackagingをbundleに設定、buildでmaven-bundle-pluginプラグインを追加することで、Manifestファイルを含んだBundleを生成するようになります。
■pom.xml(抜粋:packaging)

■pom.xml(抜粋:build)

今回はアプリケーションの作成にSALを使用するため、依存ライブラリにはOpenDaylightのSALを追加します。また、OSGiではサービスを相互に参照するため、Import-Package、Export-Packageを設定します。
■pom.xml(抜粋:dependencies)

次にソースコードを記述します。Bundleの作成に必要なActivatorのクラスと、Serviceのクラスを実装します。Activatorでは自身のServiceのエクスポートと、他に動作しているServiceのうちで利用するものを定義します。

Activatorは、ComponentActivatorAbstractBaseを継承します。OSGiのServiceの作成には、Activatorを利用する、xmlを利用する(Declarative Service)など幾つか方法ありますが、OpenDaylightのHydrogenリリースではActivator(とFelixのDependency Manager)を利用することになっています。
■Activator.java(抜粋:クラス定義)

getImplementationをオーバーライドし、Service実装の返却を実装します。これは、先に述べたFelixでのライフサイクル管理、Service依存性管理に必要です。
■Activator.java(抜粋:getImplementation)

configureInstanceをオーバーライドし、Serviceのインタフェースを設定します。これも、ライフサイクル管理、Service依存性管理に必要です。
■Activator.java(抜粋:configureInstance、Service登録)

またconfigureInstanceでは、利用する他のServiceを指定します。スイッチ自体とのポートの取得にSwitchManagerが必要です。データの処理はSALを通して行うためDataPacketServiceを指定し、スイッチへのFlowの設定のためFlowProgrammerServiceを指定します。
■Activator.java(抜粋:configureInstance、利用Service指定)

HelloWorldは、Southbound APIからの受信データ処理を行うため、IListenDataPacketを実装する形でクラスを定義します。
■HelloWorld.java(抜粋:クラス定義)

Activator.javaで指定した名称をもつメソッドを実装します。このメソッドは、Bundle開始時などにコールバックされます。
■HelloWorld.java(抜粋:利用Serviceの保持設定)

ARPなど、ブロードキャストパケットをfloodingするためには、対象スイッチから入力ポートを除く全ポートを取得する必要があるため、SwitchManagerを利用してポートを取得します。
■HelloWorld.java(抜粋:flood、スイッチの全ポート取得)

指定ポートへのパケット出力には、DataPacketServiceを利用します。
■HelloWorld.java(抜粋:forward、パケット出力)

Match、Actionを指定してFlowを作成し、FlowProgrammerServiceを利用してスイッチにFlowを設定します。
■HelloWorld.java(抜粋:receiveDataPacket、Flowの作成)

記述が完了したら、Maven InstallでBundleを作成しましょう。targetディレクトリの下にjarファイルが作成されます。

コンソールからの動作確認

OpenDaylight Hydrogen Base Editionの起動

OpenDaylight Hydrogen Base Editionを ここ からダウンロードします。実行に必要な環境は、

  • Java 1.7と、それが動作する任意のOS(Windowsでも動作しますが、Linuxが推奨されています)

となっています。今回はLinux上でzip版を利用するため、Pre-Built Zip Fileのリンク先からダウンロードし、zipを展開します。起動は簡単で、run.shを実行するだけです。
■インストールと実行

暫く経つと、http://OpenDaylightを動作させている環境のIPアドレス:8080/でOpenDaylightのGUIへアクセスが可能になります。デフォルトでは、admin/adminでログインすることができます。

opendaylight_login.png

opendaylight_top.png

ネットワーク環境の準備

実際に今回のOpenDaylightアプリケーションが動作することを確認するには、OpenFlowスイッチやホストが必要です。実際に準備するのは少し手間が掛かるため、擬似的にこれを構築する Mininet を利用します。Mininetについては 過去に本Blogで取り扱っています ので、そちらを参照してください。

今回は、2階層のスイッチの末端に2つずつホストが接続された環境を作成し、起動中のOpenDaylightをコントローラとして指定します。
■Mininet起動

この時点で、画面上にはスイッチが3つ接続された状態が表示されます。

opendaylight_screen1.png

HelloWorldのロードと実行

実行の前に、少し準備が必要です。Base EditionにはいくつかのサンプルBundleが含まれており、その内のSimpleForwarding、LoadBalancerはパケットを次の処理に渡さない可能性があるため、今回のBundleの動作確認のためにはこれを停止する必要があります。また、ARPHandlerは内部でARPフレームを発生させる関係で今回のサンプルの妨げになるため、これも停止させます。

■OpenDaylightのrun.shを起動したコンソールでSimpleForwarding、LoadBalancer、ARPHandlerを停止

次に、作成したOSGi Bundleを、OSGi Frameworkにロードし、開始してみます。

■OpenDaylightのrun.shを起動したコンソールでHelloWorldをインストール

インストール時、HelloWorldのBundle IDは253だと判りますので、これを実行します。

■HelloWorldの実行

HelloWorldが起動状態になりました。Mininetで全てのホストから相互にpingを実行して、ホスト間の疎通と、スイッチのFlow設定を確認してみます。

■Flow設定確認(ping実行前)

ping実行前は、Flowは存在しません。では、pingを実行してみましょう。

■ping実行

全てのホスト間で疎通が確認できました。今回実装したのはレイヤ2スイッチであるため、宛先がホストのMACアドレスの場合、そのホストに繋がるポートへの出力を行うFlowが登録されているはずです。Flowを確認してみましょう。

■Flow設定確認(ping実行後)

うまくFlowが設定されていることが確認できます。

GUIからの動作確認

上記の動作確認後、GUI上では、Flowの統計などを確認することができます。
opendaylight_screen3.png

また、今回はARPHandlerを停止している関係でスイッチにホストが接続されている状態が表示されませんが、ARPHandlerが動作していると、内部でHostTrackerと連動してホストを表示させます。SimpleForwarding、ARPHandler、HostTrackerを起動し、HelloWorldを停止してpingallを実行すると、以下のような表示になります。

opendaylight_screen4.png

まとめ

今回は簡単なOpenDaylightアプリケーションの作成の仕方を説明しました。OpenDaylightに限らずSDNコントローラはそのアプリケーション実装が重要ですが、そのためにはコントローラプラットフォームのアーキテクチャを知る事も大切です。OpenDaylightプロジェクトは既にHydrogenの次期リリースであるHeliumに向けて動いていますが、まだまだ日本語情報が少ないのが現状のため、利用を検討している方にとって、少しでもこの情報が参考になれば幸いです。今後は、MD-SALの利用によるOpenFlow1.3に対応したOpenDaylightアプリケーションの作成、Northbound APIを利用した外部アプリケーションからの操作や、ネットワーク仮想化機能の利用などを取り扱っていく予定です。

エンジニア採用中!私たちと一緒に働いてみませんか?