Excel以外でネットワーク構成図を書きたくなったのでPlantUMLとnwdiagを試してみました。
はじめまして。インフラまわりの担当をしているいせです。
インフラエンジニアなら誰しもExcelでネットワーク構成図を作成した経験があるのではないでしょうか?
私はラクーンに就職する前に2社で働いた経験があるのですが、いずれの現場でもExcelの構成図を触る機会がありました。
そんなExcelのネットワーク構成図ですが、私は以下の点で不便に感じています。
- 図形の中のテキストを検索できない
- 図形の位置をそろえるのが面倒
- 構成図を更新したときなどに差分比較しにくい
- 構成図の規模が大きくなるとうまくレイアウトするのが大変
そこで、テキストベースでホストやネットワークの関係性(ホストAとBは同じセグメント、セグメントZとYはルータRを介して接続される、など)を記述することで構成図を自動的に作成してくれるツールがないか探してみました。今回は以下の2つのツールを試してみたいと思います。
nwdiagを使ってみる
こちらはテキストからネットワーク構成図を作成するツールです。今回はこれを使用してL3(IPレイヤー)の構成図を作成してみます。
インストール
nwdiagはPythonで書かれており、pipでインストールすることができます。
pip install nwdiag
ちなみに今回の検証は以下の環境で実施しています。
[root@ise01 ~]# uname -a
Linux ise01 3.10.0-957.1.3.el7.x86_64 #1 SMP Thu Nov 29 14:49:43 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux
[root@ise01 ~]# cat /etc/redhat-release
CentOS Linux release 7.6.1810 (Core)
[root@ise01 ~]# python --version
Python 2.7.5
[root@ise01 ~]# pip --version
pip 18.1 from /usr/lib/python2.7/site-packages/pip (python 2.7)
[root@ise01 ~]# nwdiag --version
nwdiag 1.0.4
[root@ise01 ~]#
図の書き方
テキストで構成図の内容を記述し、それをコマンドで画像へ変換することで構成図を作成することができます。
以下はサンプルの構成図になります。
nwdiag {
network external {
address = "10.0.0.0/24"
fw01 [address = ".1/24"];
}
network dmz {
address = "172.16.0.0/24"
fw01 [address = ".254"];
bigip01 [address = ".253"];
}
network web-lan {
address = "172.16.10.0/24"
bigip01 [address = ".253"];
fw02 [address = ".252"];
web01 [address = ".11"];
web02 [address = ".12"];
web03 [address = ".13"];
web11 [address = ".21"];
web12 [address = ".22"];
}
network db-lan {
address = "172.16.20.0/24"
fw02 [address = ".254"];
db01 [address = ".11"];
db02 [address = ".12"];
}
}
これをテキストで保存し、次のコマンドで画像へ変換します。
nwdiag -T svg
-T
オプションで変換後の画像の形式をしていすることができます。svg以外にもいくつかの形式に対応していますが、私はブラウザで開くことができて、画像内テキストの検索ができるsvgが好きです。
もっと楽をしたい、、、ESXiから自動でnwdiagを作成する
ラクーンでは10台程の物理サーバの上に、VMWare ESXiを使用して100台ほどの仮想サーバを立てています。テキストで済むとはいえ、これをすべて人手でnwdiagへ落とし込むのは大変そうです。
そこで、ESXiにsshでログインし、設定情報を取得して自動で構成図を作成する簡単なBashスクリプトを作成してみました。
#!/bin/bash
user=root
declare -A port_assign
esxi_list="$@"
for esxi in $esxi_list ;do
conf=$(ssh -n -l $user $esxi "esxcli network vm list" | tail -n +3)
while read line ;do
host=$(echo $line | awk '{print $2}' | sed 's/^\[.*\]_//' | sed 's/_(.*)$//')
ports=$(echo $line | sed 's/, / /g' |awk '{for(i=4;i<=NF;i++){printf("%s ",$i)}}')
for port in $ports ;do
port_assign[$port]="${port_assign[$port]} $host"
done
done < <(echo "$conf")
done
echo "nwdiag {"
for port in ${!port_assign[@]} ;do
echo " network $port {"
for host in ${port_assign[$port]} ;do
echo " $host ;"
done |sort
echo " }"
done
echo "}"
※余談ですが、当初10-16行目のwhile文をecho "$conf" |while read line ・・・ done
と書いていたところ、ループ内で連想配列$port_assign
へ追加した要素がループの外から参照できなくなってしまいまいた。原因はパイプ以降がサブシェルになってしまい、変数のスコープが分かれてしまったためです。そこでプロセス置換を利用し、パイプを使用しないコードに変更しています。
引数にESXiのホスト名かIPアドレスを指定して実行すると、nwdiagを出力します。
なお、ESXiのバージョンは6.0を使用しています。
esxi2nwdiag.sh <ESXi①のIPアドレス> <ESXi②のIPアドレス> ・・・
ESXiのポートグループごとにサブネットを切っていると仮定しています。複数のESXiから構成されているネットワークの場合は、ポートグループ名が一致していれば引数に複数のESXiを指定することでまとめて一つの構成図として出力することができます。
例として2台のESXiにまたがるネットワーク構成図をnwdiag化させていみました。ESXiの設定は以下のようになっています。画像では物理アダプタが設定されていませんが、本来は1台目と2台目の間がLANケーブルで接続されており、それぞれのポートグループでVLANが分かれている想定です。
スクリプトで出力したテキストがこちら。
nwdiag {
network DMZ {
vRuter ;
}
network Web-LAN {
vRuter ;
web_server01 ;
web_server02 ;
web_server11 ;
web_server12 ;
}
network DB-LAN {
db_server01 ;
db_server01 ;
vRuter ;
}
}
そして、これをnwdiagで画像に変換した結果が下記になります。
ラクーンの構成図を作ってみた結果
本番環境でスクリプトを実行し構成図を作成してみたのですが、実用的とは言い難いものができてしまいまた。
100以上のノードを一枚の図に書き込もうとすると、細かすぎて見にくくなってしまうのが問題です。試してみた限りでは20-30台程度が上限のようです。
PlantUMLを使ってみる
PlantUMLはその名にある通り、UMLをテキストから作成することができるツールです。いろいろと試してみたのですが、こちらはIPレイヤーではなくアプリケーションレイヤーの構成図とする方が向いていそうです。今回はこの用途で使用してみます。
インストール
PlantUMLはVisual Studio Codeのプラグインとして導入することができます。今回はこれを使用します。
VS Codeのプラグインだと書きながらプレビューできる点が便利です。
PlantUMLは以下のソフトを利用しています。それぞを公式サイトからダウンロードし、インストールしてください。
続いてVS CodeにPlantUMLのプラグインを追加します。プラグインはMarketplaceに上がっているので、VS Code上でワンクリックでインストール可能です。
なお、今回の検証環境は以下の通りです。
- Windows 10
- Visual Studio Code 1.30.2
- Java SE Development Kit 8u201
- PlantUML 2.10.2 (Plugin)
- Graphviz 2.38
図の書き方
以下はサンプルの構成図になります。
@startuml
node "load balancer" as lb01
node "web-server01" as web01 {
agent "apache2" as web01.apache2
}
node "web-server02" as web02 {
agent "apache2" as web02.apache2
}
node "web-server03" as web03 {
agent "apache2" as web03.apache2
}
node "db-server01" as db01 {
agent "mysql" as db01.mysql
agent "keepalived" as db01.keepalived
db01.keepalived -up-> db01.mysql
}
node "db-server02" as db02 {
agent "mysql" as db02.mysql
agent "keepalived" as db02.keepalived
db02.keepalived -up-> db02.mysql
}
lb01 ----> web01.apache2 :http
lb01 ----> web02.apache2 :http
lb01 ----> web03.apache2 :http
web01.apache2 ----> db01.mysql
web02.apache2 ----> db01.mysql
web03.apache2 ----> db01.mysql
web01.apache2 ....> db02.mysql
web02.apache2 ....> db02.mysql
web03.apache2 ....> db02.mysql
db01.keepalived <-left-> db02.keepalived
@enduml
このファイルをVS Codeで開き、Alt + d
を入力するとPlantUMLのプレビュー画面が表示されます。
さらにCtrl + Shift + p
を入力、「PlantUML: ファイル内のダイアグラムをエクスポート」を選択し、その後ファイル形式を指定するとテキストファイルの保存先フォルダ内に画像ファイルとして図を出力することができます。
また、テキストを拡張子.pu
で保存するとVS Code上でシンタックスハイライトが有効になります。
ラクーンの構成図を作ってみた結果
アプリケーションレイヤーの構成図はスクリプトで自動化することが難しかったので(アプリによって設定ファイルやフォーマットが異なるため)、手作業で作成してみました。
こちらも規模が大きくなると難があるように感じました。冗長化されたサーバを一つにまとめたり、アプリケーションのドメインごとに別の図にかき分けたりと規模を小さくすれば何とか使用できそうです。ちなみに、作成した構成図は社内のGitLabで管理するようにしてみました。
まとめ
今回はネットワーク構成図をテキストから作成する方法としてnwdiagとPlantUMLをご紹介しました。
nwdiagはホストが10-30台程度の環境であれば実用化できそうですが、ラクーンの規模では難しいように感じました。
PlantUMLは規模によっては書き方に工夫が必要になりますが、アプリケーションレイヤーの構成図として使用することができそうです。