2013年12月24日火曜日

OpenVNet API を見ながら仮想ネットワークのAPIについて考えたこと

Wakame Advent CalendarをきっかけにOpenVNetのAPIを見て思ったことを書いてみたいと思います。OpenFlow Controller の Northband API や OpenStack Neutron API なども見ているので、どうなっているとうれしいのか考えてみたい。

API はまだまだ発展途上にあると思われるので、何かの参考になればと思います。

  • datapath にネットワークを登録するのはなぜ?
  • API で datapath の登録は必要なのか?
  • Interface の論物マッピングの指定方法
  • 論理モデルや名称は既存の概念に近い方がよいのでは?
  • OpenVNet 内部で使用する MAC アドレスの指定はない方がよい
  • UUID が UUID ではない

datapath にネットワークを登録するのはなぜ?

ネットワークは論理的なものであり、どのノードに広がって存在するかはそのときの インタフェースの登録状況で決まるのが自然だろう。 一方、datapath は特定のノードに存在する OpenFlow スイッチ (OVS) に対応するものなので、 datapath にネットワークを登録するということは、ネットワークが新しいノードの広がる場合には ネットワークを datapath に登録しないといけないということにもなるし、 逆に datapath にネットワークを登録していないと、ネットワークがそのノードには 広がることができないということになる。

datapath とネットワークの関連付けは OpenVNet の中で面倒をみるようになっていると API を使う側から見るとうれしい。 datapath にネットワークを登録するのは実装上の都合のように思える。

同じことが route_link についても言えると思う。

API で datapath の登録は必要なのか?

OVS が VNA に接続してくるので、OpenVNet はどの OVS が配下にいるのか分かるので、 datapath を API 経由で登録しておく必要はないように思える。

上で書いたように、現在はネットワークを datapath に登録するというステップがあるので、 登録対象となる datapath を API で登録する手順になっているように思えた。 それだけの理由であれば、datapath を API 経由で登録する必要はないと思われる。

datapath を API で登録することに意味がないか、他に考えてみると、 自分の配下にある OVS を明示的に管理しておき、意図しない OVS が接続されてしまうことを避けるという 可能性がある。OpenVNet の場合は、現在のところ OpenFlow Controller と OVS が同じホスト上で動作することが前提になっているので、この目的は必要性が少なそうに見える。

やはりいらないのだろうか? もちろん datapath 一覧を取得する方はインベントリーの意味があると思う。

Interface の論物マッピングの指定方法

リソース Interface は、論理ネットワークにおける論理インタフェースを表しているが、 同時に論理インタフェースと物理情報の対応付けも必要である。 現在の Interface 作成時のパラメータにも、これらの両方が含まれているが、 物理情報の指定はもっと明示的なパラメータにした方がよいと思われる。

現在、物理インタフェースとの対応付けに使われる情報は、以下の2つである。

  • uuid
  • owner-datapath-id

UUID は必ず "if-****" という形式である必要があり、この情報が OVS に登録する物理ポートとの対応付けにも使用されている。UUID という名前からは物理インタフェースとの対応付けに使用されるとは、到底想像できないので、明らかに別パラメータを用意した方がいいと思う。

datapath-id の方は省略可能なパラメータになっているが、これは物理インタフェース名がシステム全体で一意であれば datapath-id がなくても一意に識別できるからだと推測している。

OpenFlow ネットワークで、スイッチポートを識別する情報としては、

  • (datapath_id, switch port name)
  • (datapath_id, switch port number)
  • (datapath_id, MAC address)

などが考えられる。

安全に OpenFlow ネットワークでスイッチポートを識別するには、最初の2つのいずれかを利用できる必要がある。 この方法は、OpenFlow Controller では一般的に使用されている。例えば、 Trema ベースで作られている Virtual Network PlatformAPI のポート作成 (POST /networks/<net_id>/ports) では、 datapath_id と インタフェース名 (name) または スイッチポート番号 (number) のいずれかを指定する。Trema Sliceable Switch の API では datapath_id と port (ポート番号) の組み合わせで指定する。他の OpenFlow Controller でもこの方法が一般的に使用されている。

ポート番号を指定する方法とインタフェース名を指定する方法を比べると、インタフェースを指定する方法の方がサーバー管理者から見ると敷居が低いと思う。いくつか理由があると思う。一つは、VM を起動する際に、インタフェース名は libvirt の設定ファイルなどでも登場するため、サーバー管理者にも比較的馴染みがあるパラメータだという点。もうひとつは、ポート番号は OpenFlow スイッチにインタフェースを接続してみないと分からず、インタフェース名の方が変化が少ないため、管理しやすいということである。

(datapath_id, MAC address) の方法は、VM 管理などサーバー側の管理者から見るとわかりやすい指定方法である。OpenFlow スイッチでのポート番号を知る必要がないので、API を利用するにあたっての敷居が低くなる。一方、スイッチポートから受信したパケットの MAC アドレスを信用して処理を行うため、MAC アドレスの信頼性をどうやって確保するかが課題となる。そのため、あまり積極的には使われていない印象を受ける。

比較すると、(datapath_id, インタフェース名) を指定する方法が自然に見える。

論理モデルや名称は既存の概念に近い方がよいのでは?

最初に API を見た時、route_link っていったい何だろう?と思いました。サンプルスクリプトを見てみると、実は論理ルータと1:1に対応しているみたいと気付くと、あとは簡単でした。

このとき思ったのが、最初から router という名前だったら分かりやすかったのではないか?ということでした。

仮想ネットワークを作成する際も、論理構造としては、L2、L3 などのこれまで広まっている IP ネットワークの考え方やモデルが基本になってくると思います。ネットワーク仮想化は、論理構造と物理構造を分離して使い勝手を向上するのがひとつの価値ですが、その際に論理構造の定義は既存の概念を踏襲できると、とっつきやすいと思います。一方で、論理構造を物理構造にどのようにマッピングするかは、それぞれのネットワーク仮想化プラットフォームの腕の見せどころなのだと思います。

OpenVNet 内部で使用する MAC アドレスの指定はない方がよい

OpenVNet の API では、ネットワークの MAC2MAC で使用するブロードキャストアドレスや、 route_link の MAC アドレスなど、OpenVNet の内部で使用する MAC アドレスを指定する必要がある。 これらは API を利用する人から見ると、どの MAC アドレスが割り当て済みなのか管理する必要があり、指定することが難しい。あらかじめ OpenVNet が使用してよい MAC アドレス空間をプールとして登録しておき、自動で払い出すようにすべきだと思う。場合によっては Wakame や OpenVNet で OUI を取得してもいいかもしれない。

同様のことは、OpenVNet が機能を提供するルータや DHCP などの mode-simulated のインタフェースについても言える。これらの MAC アドレスも自動で払いだしてくれるとうれしい。

UUID が UUID ではない

これは些細なこと。API でリソース識別子として UUID というフィールドがあるが(以下の引用はネットワークの例)、 正確には UUID ではなく、単なる ID である。

また、OpenVNet の UUID フィールドはリソース種別に応じたプレフィックスが必要である (ネットワークの場合は nw-)。この意味でも、純粋な UUID ではない。

UUID は RFC 4122 http://www.ietf.org/rfc/rfc4122.txt でそのフォーマットや ユニーク性を担保して値を生成する方法が規定されている。 UUID とするのであれば、きちんと RFC で定められた UUID を生成するのがよいと思う。

# ./vnctl.sh network show
{"id"=>1,
 "uuid"=>"nw-net1",
 "display_name"=>"net1",
 "ipv4_network"=>"172.16.1.0",
 "ipv4_prefix"=>24,
 "domain_name"=>"dom1",
 "network_mode"=>"virtual",
 "editable"=>nil,
 "created_at"=>"2013-12-23T17:24:53Z",
 "updated_at"=>"2013-12-23T17:24:53Z",
 ""=>nil}

まとめ

OpenVNet API へのコメントが中心ですが、仮想ネットワークの API について考えたことを書き連ねてみました。 API を比較すると設計思想などが見えてくるので、比べてみるのはおもしろいです。

OpenVNet の話をすると、API はいろいろと改善の余地がありそうです。まだ生まれたてなので、機能が大きくなる前に API がどうあるべきかの観点からの見直しを行うのも一つの選択肢かなとも思いました。