サマリ
- この記事は3社協同プロジェクトの紹介記事であり、ブログリレーの中編です
- configを頼りにL1トポロジをNetBox上で再現し、Batfishで解析できるようにしました
- 障害耐性を測るためにリンク障害を模擬したL1トポロジを自動生成しました
- Batfishの解析結果からL1/L2/L3の情報をモデルとして抽出し再利用可能にしました
はじめに
イノベーションセンターの田島です。主にサービスプロバイダ網の技術検証から検証用ASの設計・構築・運用まで担当しています。
この記事は沖縄オープンラボラトリ 1 で実施している、TIS株式会社/ビッグローブ株式会社/NTTコミュニケーションズ株式会社の3社協同プロジェクト「Model Driven Network DevOps PJ」 2 の内容を紹介します。詳細は後述しますが、このPJではトポロジをはじめとするNW構成情報を中心にした設計・構築・運用プロセスの検討とPoCの実施・評価を実施しています。
この記事では下記の図の強調部分を紹介します。前後の部分を分割し全体を3パートに分けて各社持ち回りで紹介するブログリレー形式をとっています。これに加えて前編後編もあわせてご覧いただくと全貌がより一層理解しやすくなります。
- ブログリレーの前編:モデルベースなネットワーク自動化への挑戦/ビッグローブ株式会社
- ブログリレーの中編:実ネットワークをモデルとして抽象化しオペレーションを高度化するチャレンジ(この記事)
- ブログリレーの後編:ネットワークのモデルベース検査と障害シミュレーションによる運用高度化への挑戦/TIS株式会社

プロジェクトの概要
我々のプロジェクトでは、ネットワークの複雑化に起因して発生する、人間では事前にネットワークの状態を把握しきれない問題に対処しようとしています。ネットワークの状態を把握できなくなると次のような影響が出ます。
- ネットワークの運用、特にオンプレでは構築・変更に対する事前検証およびレビューが重要視される
- しかし規模の問題などで検証環境では不十分に模擬できない等の状況が発生し、人間の思考力に依存する箇所が発生する
- その結果レビューの品質が安定しないばかりか、実際にやってみて問題に直面するといった状況が発生しかねない
これに対処するため、ネットワークを含めたシステム全体のあるべき姿としてモデルを定義し、モデルデータで各種の検証やテストを行えるソフトウェア群の実装を目指しています。計算機上にモデルを構築し実機との間で同期を取ることで様々なオペレーションの模擬が人間より高い精度で、広い網羅性で、短時間でできるようになると考えています。また、このモデルデータを使うことで1つの巨大なシステムでは無く各コンポーネントの責務が明確になった、対象の環境に合わせた拡張がしやすいソフトウェアを作れると考えています。図のような本番環境とモデルを相互に同期する仕組みを作り、下記のような機能の実現を目指しています。
- 設計ポリシのルールに各モデルデータが準拠しているのかのチェック
- シミュレーションによる設定変更やテスト実行
- 時系列のモデルデータの差分による構成や状態変化の可視化
- モデルデータから検証環境の自動構築や機能検証実施
- 検証済みモデルデータの自動デプロイ

現段階ではネットワーク機器のconfigからモデルデータを構築し、障害試験を含む各種の疎通試験ができています。図中だとターゲットとなる本番環境からモデルを構築し、自動テストを行う部分のイメージです。モデル上だと全パターンの疎通試験を行うことができるので、単一障害点の存在を確実に検出できます。
モデルデータを用いた疎通試験に必要なコンポーネント
ネットワーク機器から情報を取得し、モデルを作成し、そのモデルを用いて各種試験を模擬するためには大きく分けて下記の3ステップが必要です。
- NW装置のコンフィグを自動定期取得するステップ
- configからL1/L2/L3に分けてモデルデータを作成するステップ ※この記事の範囲
- モデルデータを評価するステップ
この記事では2の部分を紹介します。1と3についてはそれぞれビッグローブ株式会社、TIS株式会社の記事をご確認ください。
モデルデータの作成
パート1であるビッグローブ株式会社の記事 によってconfigやstatusを取得できました。それらのconfigからL1/L2/L3の情報を復元していきます。方針としてはBatfish 3 でconfigからL2/L3の再構築ができるため、それ以外の部分を独自実装します。Batfish単体ではカバーできないのは次のような部分です。
- 2022/03現在、BatfishはIPv6に未対応
- → IPv6関連を別途パースできるように開発中 (この記事では省略)
- L1トポロジは復元されない
- configから復元する
- リンク障害模擬・ノード障害模擬などの実験データの機械的な作成
- L1トポロジをベースに別途生成する
- 再利用可能な形式での各レイヤーデータの保存
L1トポロジの復元
configを基にL1の接続状態を調べ、トポロジデータとして利用可能にしました。入力はconfigのテキスト群、出力はBatfish読み込み可能なlayer1_topology.json 4 です。中間生成物として、L1トポロジをデバイスとケーブルで表現したNetBoxインスタンスと、inet-henge 5 で表示可能なトポロジデータが作成されます。トポロジはグラフDBに入れて表現することもできますが、モデルデータの1つとして後々の変更チェックなどで活用できるように、専用UIが付いているNetBoxを使用しました。
レポジトリはこちらです。
下記のようなconfigを手がかりにします。
pushed_configs$ grep -B 2 description mddo_network/configs/RegionA-CE01_config.txt ! interface Ethernet1 description to_RegionA-PE01_ge-0/0/2 -- ! interface Ethernet3 description to_RegionA-CE02_Ethernet3 -- ! interface Ethernet4 description to_RegionA-CE02_Ethernet4 -- ! interface Ethernet5 description to_RegionA-Acc01_Ethernet1 -- ! interface Ethernet6 description to_RegionA-Acc01_Ethernet2 -- ! interface Ethernet7 description to_RegionA-Acc01_Ethernet5 -- ! interface Ethernet8 description to_RegionA-Acc01_Ethernet6
上記のdescriptionを基にしてNetBoxへDevicesやInterfacesを登録します。

NetBoxのデータからしたL1トポロジの例です。
pushed_configs$ cat mddo_network/layer1_topology.json | jq . | head
{
"edges": [
{
"node1": {
"hostname": "RegionA-Acc01",
"interfaceName": "Ethernet1"
},
"node2": {
"hostname": "RegionA-CE01",
"interfaceName": "Ethernet5"
障害模擬データの作成
全パターンの単一障害を模擬するために、一部が欠損したBatfishへの入力データを作成します。与えられたL1トポロジからリンクを除きsnapshotとして登録します。除くリンクの記述は runtime_data.json 6 で行いました。また、後から参照できるようにどのリンクを除いたかを含めたsnapshotのメタデータをsnapshot_info.jsonとして保存します。
レポジトリはこちらです。
障害模擬として除くリンクは下記のように表現されます。
playground$ cat ./configs/pushed_configs_linkdown/mddo_network_01/batfish/runtime_data.json | jq .
{
"runtimeData": {
"RegionA-Acc01": {
"interfaces": {
"Ethernet1": {
"lineUp": false
}
}
},
"RegionA-CE01": {
"interfaces": {
"Ethernet5": {
"lineUp": false
}
}
}
}
}
モデルデータの生成
ここまででL1トポロジデータとBatfishによるL2/L3のデータが準備できました。これらをまとめてモデルデータとして生成します。データの表現方法は再利用性を考え RFC8345 7 を参考にした記述としました。RFC8345形式のデータはデータ構造が決まっていることで他のソフトウェアからもアクセスしやすいと考えられます。実際にブラウザ上で表示できるnetovizがあります。
データの生成は、L1トポロジはlayer1_topology.jsonのまま、Batfishのデータは一度csvに出力し、それらを読み込み再構築します。モデルデータの再構築をする中でインターフェースの齟齬やネットワークプレフィックスの差異など、正常に再構築できないデータ、つまり設定の誤りを検出できます。
レポジトリはこちらです。
- モデルデータ生成 github.com
- RFC8345データの可視化 github.com
Batfishのデータをcsvで出力すると、例えばIPアドレスとインターフェースの対応付けであれば下記の結果が得られます。
playground$ cat models/pushed_configs/mddo_network/ip_owners.csv | head ,Node,VRF,Interface,IP,Mask,Active 0,regionb-svr01,default,enp1s5,172.31.110.100,24,True 1,regionb-pe02,default,ge-0/0/4.0,10.1.2.2,30,True 2,regionb-svr02,default,enp1s4,172.31.20.100,24,True
各データを再構築したモデルデータは下記のような構造になります。
playground$ cat netoviz_model/pushed_configs_mddo_network.json | jq . | head -n 20
{
"ietf-network:networks": {
"network": [
{
"network-id": "layer3exp",
"network-types": {
"mddo-topology:l3-network": {}
},
"node": [
{
"node-id": "regiona-ce01",
"ietf-network-topology:termination-point": [
{
"tp-id": "Vlan10#1",
"supporting-termination-point": [
{
"network-ref": "layer2",
"node-ref": "regiona-ce01_Vlan10",
"tp-ref": "Port-Channel2"
}
このデータはnetovizで各レイヤーごとに可視化できます。

データ操作のためのWeb UIサンプル
データをもとにシミュレート操作を行うためにはJupyter Notebook等を利用できますが、決まった作業であればWeb API等を介してWeb UIを用意すると操作が簡便です。しかし、BatfishではPython実装のクライアントライブラリであるpybatfishのみの提供で、そのままではフロントエンド系のフレームワークとは相性が良くないです。そこでBatfishにWeb APIのラッパをかぶせることで、Batfish内部のコマンドを隠蔽し、可視化部分を開発しやすくしました。
ここではtracerouteを実行するWeb UIの実装例を紹介します。
batfish-wrapper
BatfishにWeb API経由でアクセスできるラッパです。pybatfishをflask内で使用しています。Batfishの概念であるnetwork/snapshotに応じてURLを構成できるようにしています。
レポジトリはこちらです。
Batfishに現在登録されているnetworkやsnapshotやinterfaceの一覧を取る例は次のような一連のAPIです。
$ curl -s http://192.168.23.31:15000/api/networks | jq .
[
"batfish-test-topology",
"pushed_configs",
"pushed_configs_drawoff",
"pushed_configs_linkdown"
]
$ curl -s http://192.168.23.31:15000/api/networks/pushed_configs/snapshots | jq .
[
"mddo_network"
]
$ curl -s http://192.168.23.31:15000/api/networks/pushed_configs/snapshots/mddo_network/interfaces | jq . | head -n 20
[
{
"addresses": [],
"interface": "ae1",
"node": "regionb-ce01"
},
{
"addresses": [],
"interface": "Ethernet10",
"node": "regiona-acc01"
},
{
"addresses": [
"172.16.5.1"
],
"interface": "Port-Channel1",
"node": "regiona-ce01"
},
{
"addresses": [],
fish-tracer
インターフェースを指定して、単数もしくは複数のsnapshotに対してtracerouteのシミュレート結果を表示できるWeb UIです。モデルデータをそのまま見て解析するのはやはり見づらく、開発時にも簡単に試せるこのUIがあって便利でした。NuxtJSで上記batfish-wrapperを呼んでいます。
レポジトリはこちらです。
下記のように複数snapshotに対してのtracerouteをグラフィカルに実行できます。

まとめ
この記事では「Model Driven Network DevOps PJ」の概要紹介、configからモデルデータを作成するステップを解説しました。configからL1を復元し、障害模擬トポロジを機械生成し、BatfishでL2/L3情報も復元し、モデルデータとして出力しました。
本文中にもありますが、現在のシステムではまだまだモデルの利点を活かしきれる実装ではないため、引き続きモデルを活用できる実装を増やしています。取り組みにご興味ある方は 沖縄オープンラボラトリ までご連絡ください。
ブログリレーの次パート(TIS株式会社) に続きます。
-
次世代ICT基盤技術の実用化と普及を目指す研究機関。 https://www.okinawaopenlabs.org/↩
-
プロジェクトの紹介および2021年度の活動紹介資料のページ。 https://www.okinawaopenlabs.org/mdnd↩
-
オープンソースのconfig解析ソフト。 https://www.batfish.org/↩
-
L1トポロジを表現する、Batfishの追加入力データの1つ。 https://batfish.readthedocs.io/en/latest/formats.html#layer-1-topology↩
-
ブラウザによるネットワーク図生成フレームワーク。 https://github.com/codeout/inet-henge↩
-
インターフェースの状態を示すBatfishの追加入力データの1つ。なお2022/03時点ではサンプルのデータ構造と実際に正しく読み込まれるデータ構造が違うので注意が必要。 https://batfish.readthedocs.io/en/latest/formats.html#runtime-interface-information↩
-
ネットワークトポロジを表現するためのYANGデータモデルの定義。 https://datatracker.ietf.org/doc/html/rfc8345↩