Neutron サービスプラグインの作り方
はじめに
こんにちは、インフラ本部の大山裕泰です。今回は OpenStack をより柔軟な環境に拡張できる小ネタをご紹介致します。
前回のエントリでも述べましたが Neutron ではコンピュートノードのエージェントを制御したり、独自の拡張機能を本体の機能と連携させたりといった事がプラグイン機構によって実現できます。
今回は、Neutron のプラグイン機構についてと、ルータに対する各種操作に同期する Neutron L3 プラグインの仕組みと実装について見てゆきます。
また、今回紹介する手法を応用するこよによって、以下のようなことが出来るようになると思います。
- Floating-IP 割当/削除時における DNS との連携
- テナントネットワーク、及び Flaoting-IP の作成/更新/削除に伴う課金システムとの連携
まずは Neutron のプラグイン機構について少し詳しく見てゆきます。
Neutron プラグイン機構
「コアプラグイン」と「サービスプラグイン」
冒頭で述べたように Neutorn では、コントロールプレーンを実現する「コアプラグイン」に加えて、ネットワークに関する様々な機能を「サービスプラグイン」という形で OpenStack Networking のメインプロセスである neutron-server から切り離して使える設計になっています。
Neutron は、今回紹介する、ルータや Floating-IP の管理などの L3 機能に加え、VPN や LB、FW などといった機能毎に「サービスタイプ」を規程しており、ユーザはサービスタイプ毎にそれぞれの環境が必要としている要件を満たすプラグインの実装を一つ選択して利用できます。
以下が OpenStack Juno 版における各サービスタイプの一覧になります。
サービスタイプ | プラグインの種別 |
---|---|
LOADBALANCER | LBaaS のプラグイン |
FIREWALL | FWaaS のプラグイン |
VPN | VPNaaS のプラグイン |
METERING | トラフィック流量計測機能 (Neutron Metering) のプラグイン |
L3_ROUTER_NAT | ルータ (L3) 関連機能のプラグイン |
また、コアプラグインとサービスプラグインはそれぞれ Neutorn の設定ファイル (/etc/neutron/neutron.conf) の core_plugin と service_plugins で指定します。以下は neutron.conf における両パラメータの抜粋になります。
1 2 |
> core_plugin = neutron.plugins.ml2.plugin.Ml2Plugin > service_plugins = neutron.services.l3_router.l3_router_plugin.L3RouterPlugin,neutron_lbaas.services.loadbalancer.plugin.LoadBalancerPlugin,neutron.services.metering.metering_plugin.MeteringPlugin,neutron_vpnaas.services.vpn.plugin.VPNDriverPlugin,neutron_fwaas.services.firewall.fwaas_plugin.FirewallPlugin |
コアプラグインのパラメータ (core_plugin) では一つの値 (neutron.plugins.ml2.plugin.Ml2Plugin) だけが設定されていますが、サービスプラグインのパラメータ (service_plugins) にはリスト形式で複数の値が設定されています。
先に述べたように、サービスプラグインは各サービスタイプ毎に一つしか指定されるため、ここで指定されている値はそれぞれサービスタイプ毎のサービスプラグインを表しています。どのプラグインがどのサービスタイプのものかはプラグインの実装側で指定されています。これについては後で L3 プラグインを実際に作成する際に見てゆきます。
拡張 (Extension) 機能
Neutron のプラグイン機構の設計でもう一つ重要な仕組みが 拡張 (Extension) 機能 になります。これは、各種プラグインを経由して Neutron 本体の API や機能の拡張を行うための仕組みで、プラグインは一つ以上の拡張機能を利用することで、当該拡張機能が提供する API コールをハンドリングし独自の実装を加えることができます。後述する L3 プラグインでは router 拡張機能 を実際に使い、Floating IP アドレスの作成 / 削除の処理をハンドリングしています。
L3 プラグインを作ってみた
では実際に L3_ROUTER サービスプラグインを作ってみたいと思います。
今回作成した L3 プラグイン (L3GREEPlugin) では router 拡張機能 を用いて、Neutron の L3 関連オブジェクト (ルータ, Floating IP アドレス) の 作成, 更新, 取得, 削除処理をハンドリングすることができます。実際には例として、Floating-IP の作成/削除に同期してログを出力する処理を実装しています(その他の処理についても同様にして実装することができると思います)。以下がソースコードの全文になります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
from oslo_config import cfg from oslo_utils import importutils from neutron.common import constants as q_const from neutron.db import common_db_mixin from neutron.db import l3_db from neutron.plugins.common import constants from neutron.openstack.common import log as logging LOG = logging.getLogger(__name__) class L3GREEPlugin(common_db_mixin.CommonDbMixin, l3_db.L3_NAT_db_mixin): """Implementation of the Neutron L3 Router Service Plugin.""" supported_extension_aliases = ["router"] def __init__(self): super(L3GREEPlugin, self).__init__() def get_plugin_type(self): return constants.L3_ROUTER_NAT def get_plugin_description(self): return "L3 Router Service Plugin for test (this method must be specified)." def create_floatingip(self, context, floatingip): LOG.info("[GREE] [create_floatingip]") return super(L3GREEPlugin, self).create_floatingip( context, floatingip, initial_status=q_const.FLOATINGIP_STATUS_DOWN) def delete_floatingip(self, context, floatingip): LOG.info("[GREE] [delete_floatingip]") return super(L3GREEPlugin, self).delete_floatingip(context, floatingip) |
まず L3GREEPlugin が継承している親クラス (13行目) ですが、一つ目の親クラスとして指定されている CommonDbMixin は、コア/サービスプラグイン共通で利用されるユーティリティメソッドが定義されたクラスになります。そして二つ目の親クラス L3_NAT_db_mixin は、各種 L3 関連オブジェクト (ルータ, Floating-IP, ポートなど) の DB モデルに対する処理を規程したクラスになります。
またクラス変数 supported_extension_aliases によって、プラグインが利用する拡張機能を選択します(16行目)。ここでは "router" 拡張機能を選択し、L3 関連オブジェクト (ルータ、及び Flaoting IP アドレス) のリソースを Neutron 本体から扱えるようにしています。
続いて get_plugin_type メソッド (21行目) によってプラグインのサービスタイプを指定し、get_plugin_description メソッド (24行目) によって当該プラグインがどんなものかを指定しています。このメソッドは、サービスマネージャーがプラグインをロードする際に呼び出し、結果をデバッグログに出力するだけなので動作としてはとくに影響はありませんが、これを宣言しないとサービスマネージャー側でメソッドコールに失敗し neutron-server プロセスが停止します。
そして最後に、Floating IP アドレスの割当/解放処理をハンドリングする create_floatingip / delete_floatingip メソッド (27行目/33行目) を宣言しています。これらは router 拡張機能 (extensions/l3.py) でテンプレートが定義され、L3GREEPlugin の親クラス (L3_NAT_db_mixin) で実装が書かれています。ここでは、これらのメソッドをオーバーライドし、呼び出されたタイミングでログメッセージを書き出した後、通常の処理を実行しています。尚、router 拡張機能で定義されているテンプレートメソッドの一覧は RouterPluginbase クラスの定義 から確認できます。
動かしてみた
以上で述べた Neutron の独自プラグイン (L3GREEPlugin) を実際に動かしてみようと思います。
まずはサービスタイプ "L3_ROUTER_NAT" のサービスプラグインとして、作成したサービスプラグインを指定するようにコントローラノードの neutron.conf を修正します。以下は、先ほど示した内容との差分になります。
1 2 3 4 5 6 7 8 9 10 11 |
--- neutron.conf.old 2015-03-08 18:58:00.216617584 +0900 +++ neutron.conf 2015-03-08 18:57:52.024428677 +0900 @@ -12,7 +12,7 @@ policy_file = /etc/neutron/policy.json debug = True verbose = True -service_plugins = neutron.services.l3_router.l3_router_plugin.L3RouterPlugin,neutron_lbaas.services.loadbalancer.plugin.LoadBalancerPlugin,neutron.services.metering.metering_plugin.MeteringPlugin,neutron_vpnaas.services.vpn.plugin.VPNDriverPlugin,neutron_fwaas.services.firewall.fwaas_plugin.FirewallPlugin +service_plugins = neutron.services.l3_router.l3_gree.L3GREEPlugin,neutron_lbaas.services.loadbalancer.plugin.LoadBalancerPlugin,neutron.services.metering.metering_plugin.MeteringPlugin,neutron_vpnaas.services.vpn.plugin.VPNDriverPlugin,neutron_fwaas.services.firewall.fwaas_plugin.FirewallPlugin core_plugin = neutron.plugins.ml2.plugin.Ml2Plugin rabbit_userid = stackrabbit rabbit_password = pass |
次に neutron-server プロセスを再起動させ、horizon から Floating IP アドレスの割当/解放を実施して、期待通りに動作するか確認してみます。
Floating IP アドレスを割り当てると、以下のログが neutron-server のログに出力されました。
1 |
2015-03-08 08:46:14.670 INFO neutron.services.l3_router.l3_gree [req-46d11ec0-d0c5-4b76-b37e-a25c91f0c0b0 admin b74978e2119a4a839ee3b037ace54a0a] [GREE] [create_floatingip] |
続いて、割り当てた Floating IP アドレスを削除してみます。
同様に以下のログが出力されました。
1 |
2015-03-08 08:46:39.553 INFO neutron.services.l3_router.l3_gree [req-90ca1413-628c-4522-9826-5635367c9e26 admin b74978e2119a4a839ee3b037ace54a0a] [GREE] [delete_floatingip] |
まとめ
いかがだったでしょうか。ここではごく簡単な例しか示しませんでしたが、ここで紹介したテクニックを応用することで冒頭で述べたように他のシステムとの連携であったり、独自処理の追加といった事ができるようになり OpenStack をより柔軟に運用してゆく事ができるようになると思います。