ネットワーク構成図のレイアウト処理を考えてみる (1)

## はじめに

[ネットワーク (を中心に情報システム) の構成を可視化できないかという話を考えている](https://qiita.com/corestate55/items/8a39af553785fd77c20a)わけですが、可視化 = 見せ方を考えるとレイアウトをどうするか、という問題にぶち当たります。大雑把に言うと、以下の要素がそれぞれトレードオフになっていきます。

* 描画したいオブジェクト(ノード等)の数: 図のスケーラビリティ
* システムの全体感の把握

どんなトレードオフがあるのか、という話と、それに対して今回試してみている方法についてまとめてみます。

## 構成図に求めるもの

とりあえずネットワーク図(構成図)というところを考えます。

ネットワーク図では通常、図のどこにどんなものを置くのかというルールが設定されます。例えば、対外接続系・内部バックボーン・コア・アクセス…などの位置づけ、冗長系(アクティブ・スタンバイ)などの役割などに応じた配置ですね。そうした役割や上下関係などのルール、隣接するノードとの接続パターンなどを束ねて「情報量を減らす」ことをやらないとあっという間に構成パターンが増大して扱いきれなくなってしまいます。

ということで、構成図にはパターンがあるし、何かの隣にあるからこうだ・この位置にあるからこうしているはず、みたいに位置関係に運用上必要な情報が埋め込まれていることが (実際に作業で使うレベルの構成図の) ポイントになると思っています。

## トレードオフ

さて。図にどんな情報を埋め込むかですね。たとえばコアスイッチとして使っているL3スイッチが 10 個の VRF を持っていて 200 VLAN くらい収容しているとなるとどうでしょうか。愚直に図を起こして、図に 100 個単位のオブジェクトが並んだとすると、要素が多すぎて必要な情報を探し出すことが難しくなってしまいます。この程度のサイズ感でも、情報を全部図に落とし込むのはとても難しい。実際には、レイヤ・顧客・サービスなどいくつかの単位で図を分割して作成しているのではないかと思います。

ところが、図を分けるとそれはそれで複雑度が上がってしまう。分けたパートごとには構成がわかっても「全体」が見えにくくなってしまうわけです。なので特定のオペレーションに対して予期せぬトラブル (見えてなかった部分への影響) が発生したり、あるトラブルに対してどこまで影響するものなのかを判断するのに時間がかかってしまう。

ネットワーク構成単位の増加 (図のスケーラビリティ) と、システムの全体感の把握というところにはトレードオフの関係があるわけです。でも運用上はやっぱり全体→必要な情報(詳細)への絞り込みをやっていきたいという思いがあります。(複数の図を頭の中に入れて脳内マッピングするのには限界がありますし、脳内マップできるようになるのにそれなりのスキルや習熟が必要。)

## ためしてみたこと

[これまでの記事](https://qiita.com/corestate55/items/9d8023eb19637f9bbd1e)の中で、半手動でのネットワーク図レイアウトを作っているという話をしました。今回はそれの拡張というか、応用の話です。(図の題材については[前の記事](https://qiita.com/corestate55/items/8a39af553785fd77c20a)を参照。)

### 表示階層の増減とドリルダウン操作

まず表示する情報量の調整についての機能について見てみましょう。

階層のあるデータを作ってその階層を全部出すと、さっぱりスケールしませんでした。まあわかっていたことですが……。全体の中で見たいものがどこにあるのか(全体感の把握)と見たいもの「掘り下げ」をやる機能が必要だろうということで、表示階層のコントロールとクリックによるドリルダウン操作を入れてみています。

![nest1a.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154230/a2cae8be-4eac-18ec-cd02-cc01decff619.gif)

ドリルダウン操作ですが、最初に着目したルータ (as2core1) にある依存関係をたどったときに、関連する他のルータについてもハイライトが移っていくことに注目してください。

![nest1b.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154230/0b1c3b3a-d434-0417-3922-09a37f872cd6.gif)

OSPF Area, BGP AS のように複数の関連するノードがある(依存関係が定義されている)ものにフォーカスを移した際、as2core1 からたどっていますが、それらが依存する周囲のノードがどこなのか、とかもわかるようになっています。そのため「図として見る」→「周囲の関係する構成要素がどれなのかを知りたい」が表示できています。

### Grid Fitting

続いて、レイアウトについての機能です。

上の例ではレイアウトは固定で、表示する情報を増やしたとき(表示階層を増やしたとき)に合わせてレイアウトを設定してあります。なので、表示階層を減らしたときにはどうしても余白が目立ってしまいます。全体の構成(全体感)を捉えたい、というときには表示量を減らして広い範囲を画面に入れたいのですが、レイアウトを固定してしまうとそれがなかなかできない。

もともと、半手動レイアウトということで、縦横にグリッドを置いて、グリッド交点を指定してオブジェクトを配置する(配置情報は手書き)という方法をとっています。グリッドを動かすことでレイアウトを手動調整する……という機能だったわけですが、いざ使うと表示階層増減によってオブジェクトの大きさが変わるため、手動でいちいちグリッド調整なんかやってらんないんですよね。

なので、グリッド操作によるレイアウト調整を自動化しました。以下の図では表示する情報が変わったときに、自動的にグリッド位置が変更されている点に注目してください。

![nest2a.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154230/7682bd55-b064-6726-7e3d-b98f52ff78e2.gif)

ドリルダウンして個別に表示階層を選択したときにもグリッドが自動調整されます。

![nest2b.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154230/40e67be3-815d-e6b4-e4d0-65af70889842.gif)

このグリッド自動調整は、縦横の各グリッドそれぞれについて、グリッド上にあるノードの最大値(幅・高さ)をだして、グリッド幅をその最大値に合わせる機能です。この方法にはひとつ大きなメリットがあって、 **最初に決めたレイアウトに対して相対的な位置関係がほぼ保持できる** んですよね。表示階層を変えた時に、中にたくさん要素があって隙間があいてしまうケースはあります。ありますが、その余白を埋めるために変に操作すると、今度は最初グリッド上の配置の時に意図したであろうノード間の位置関係が崩れてしまうんですよね……。「ノードが重ならない程度にグリッドを詰める」処理は、単純なわりにレイアウト調整としては効果のある方法なんじゃないかと思っています。

まあデメリットもあって、「隙間が空く」のは書いた通りですが、手動のところ……最初にどのノードをどのグリッドに置くかを決めるところがえらい面倒くさいです。ホスト名とかをもとに配置をルール化できるようなネットワークであればいいんですが、そのようなルールがちゃんと決められているようなところは構成図に関してあまり困っていないのでは……? 初期レイアウト作成のための補助ツールがほしいところではありますが……。

## おわりに

「コンピュータで構成図を描く」ときに、手書き紙図面ではできない表現やインタラクティブ性を入れたいという期待がやっぱりありますよね。見た目のところについてはいくつか作りこみや工夫をしてみたので、今回はその紹介をしてみました。もっとこういうことができないのかとか、こうした方がいいんじゃないかとか、気になるところがあればコメント等ください。

まあ正直言うと、こういったフィルタや絞り込みの機能を入れたところで、100 個～とか構成要素があるようなケースは現状まだまだ「見せる」のは難しいんですけどね (絞り込みとかをしていく段階で 100 個の候補がべろっと出てしまう)。特定のパターンや種別のものを束ねて見せるとか、別なやり方を考えないと難しそうなんだけど、そうした「特定のパターンや種別」ってどうやって判断するの……などが難しくて。なんかいいやりかたないでしょうかね。

構成図に困っているところ・システム構成を見えるようにしたいシステムって、ルールが設定されてないとか、ルールはあるけど少量多品種サービスを収容していてとにかく数が多いとか、「異なるものがたくさんあって複雑」なところが多いんだろうなと思っています。複雑さに対応するための何かを入れても、複雑さは完全にはなくせなくて、形や場所を変えて出てくる。せめてその問題ポイントを「人が現地に行って直接作業しなければいけないところ」から「設定やプログラムで処理 (自動化) できるところ」に変えていきたい、というのがいまの狙いどころなんじゃないでしょうか。

参照:

* [corestate55/netoviz: RFC8345\-based Network Topology Visualizer](https://github.com/corestate55/netoviz)
* https://netoviz.herokuapp.com/
  *  Heroku上で動かしているので触ってみてください