0. はじめに
この記事はシスコの有志による Cisco Systems Japan Advent Calendar 2024 (一枚目) の 22日目として投稿しています。
2017年版: https://qiita.com/advent-calendar/2017/cisco
2018年版: https://qiita.com/advent-calendar/2018/cisco
2019年版: https://qiita.com/advent-calendar/2019/cisco
2020年版: https://qiita.com/advent-calendar/2020/cisco
2020年版(2枚目): https://qiita.com/advent-calendar/2020/cisco2
2021年版: https://qiita.com/advent-calendar/2021/cisco
2021年版(2枚目): https://qiita.com/advent-calendar/2021/cisco2
2022年版(1,2): https://qiita.com/advent-calendar/2022/cisco
2023年版: https://qiita.com/advent-calendar/2023/cisco
2024年版: https://qiita.com/advent-calendar/2024/cisco <=== ここ
1. 今年の内容は?
去年IOS-XRのAI-Driven Telemetryについて書きました。
今年も引き続きAIブームは続いていますが、機械学習を用いたNetworkの異常検知についてここ数日聞く機会がありましたので、それについて書いてみようと思います。
機会学習を用いたNetworkの異常検知とは?
この手の話では毎度のことになりそうですが、GPTに聞いてみました。
Syslogなどを含めると非常に有効だと思いますが、自然言語処理が入ると一気に難しくなって私のキャパを超えてしまいそうなので、この記事ではTelemetryを用いて取得できる数字として処理できる情報を元に進めたいと思います。
2. まずはテレメトリを取れるように設定
これは非常に多くの記事で扱われている内容なので詳細は割愛します。
今回はIOS-XR/IOS-XEからModel Driven Telemetryでテレメトリデータを取得し、TIG(Telegraf/InfluxDB/Grafana)でテレメトリを可視化してみます。
ちなみに今回センサーパスを考えるのに、対応しているセンサーパスを機器から取得してYANG SUITEでも確認してみました。
nccで機器からセンサーパスを取得すると以下のようになります。
https://github.com/CiscoDevNet/ncc/
tkamata@tkamata-lab3:~/YANG-models$ python3 ~/ncc/ncc-get-all-schema -a 172.20.0.2 -u admin -p cisco
tkamata@tkamata-lab3:~/YANG-models$ ls
CISCO-ENTITY-FRU-CONTROL-MIB.yang Cisco-IOS-XR-freqsync-oper.yang Cisco-IOS-XR-ipv6-nd-oper-sub1.yang Cisco-IOS-XR-policy-repository-oper-sub1.yang Cisco-IOS-XR-um-aaa-diameter-cfg.yang Cisco-IOS-XR-um-traps-entity-redundancy-cfg.yang
Cisco-IOS-XR-aaa-aaacore-cfg.yang Cisco-IOS-XR-fretta-bcm-dpa-npu-stats-oper-sub1.yang Cisco-IOS-XR-ipv6-nd-oper.yang Cisco-IOS-XR-policy-repository-oper.yang Cisco-IOS-XR-um-aaa-nacm-cfg.yang Cisco-IOS-XR-um-traps-entity-state-cfg.yang
Cisco-IOS-XR-aaa-diameter-base-mib-cfg.yang Cisco-IOS-XR-fretta-bcm-dpa-npu-stats-oper-sub2.yang Cisco-IOS-XR-ipv6-new-dhcpv6d-cfg.yang Cisco-IOS-XR-portmode-cfg.yang Cisco-IOS-XR-um-aaa-radius-server-cfg.yang Cisco-IOS-XR-um-traps-flash-cfg.yang
(snip)
YANG SUITEについても今年のAdvent Calendarで触れている記事もありますので出力結果だけ出します。
以下のように内容確認することができます。
今回Routerに設定したTelemetryの設定は以下です。
telemetry model-driven
destination-group COLLECTOR
vrf Mgmt-intf
address-family ipv4 x.x.x.x port 50002
encoding self-describing-gpb
protocol tcp
!
!
sensor-group TRAFFIC
sensor-path Cisco-IOS-XR-infra-statsd-oper:infra-statistics/interfaces/interface/latest/generic-counters
!
subscription ANALYTICS
sensor-group-id TRAFFIC sample-interval 30000
destination-id COLLECTOR
!
!
sensor-group health
sensor-path Cisco-IOS-XR-wdsysmon-fd-oper:system-monitoring/cpu-utilization
sensor-path Cisco-IOS-XR-nto-misc-shmem-oper:memory-summary/nodes/node/summary
sensor-path Cisco-IOS-XR-shellutil-oper:system-time/uptime
!
sensor-group interfaces
sensor-path Cisco-IOS-XR-pfi-im-cmd-oper:interfaces/interface-summary
!
!
sensor-group routing
sensor-path Cisco-IOS-XR-clns-isis-oper:isis/instances/instance/levels/level/adjacencies/adjacency
sensor-path Cisco-IOS-XR-clns-isis-oper:isis/instances/instance/statistics-global
sensor-path Cisco-IOS-XR-ip-rib-ipv4-oper:rib/vrfs/vrf/afs/af/safs/saf/ip-rib-route-table-names/ip-rib-route-table-name/protocol/isis/as/information
sensor-path Cisco-IOS-XR-ipv4-bgp-oper:bgp/instances/instance/instance-active/default-vrf/process-info
!
sensor-group mpls-te
sensor-path Cisco-IOS-XR-mpls-te-oper:mpls-te/tunnels/summary
sensor-path Cisco-IOS-XR-ip-rsvp-oper:rsvp/interface-briefs/interface-brief
sensor-path Cisco-IOS-XR-ip-rsvp-oper:rsvp/counters/interface-messages/interface-message
subscription health
sensor-group-id health strict-timer
sensor-group-id health sample-interval 60000
destination-id COLLECTOR
!
subscription interfaces
sensor-group-id interfaces strict-timer
sensor-group-id interfaces sample-interval 60000
destination-id COLLECTOR
!
subscription routing
sensor-group-id routing strict-timer
sensor-group-id routing sample-interval 60000
destination-id COLLECTOR
!
subscription mpls-te
sensor-group-id mpls-te strict-timer
sensor-group-id mpls-te sample-interval 60000
RouterとTIGで接続できています。
RP/0/RP0/CPU0:R1#show telemetry model-driven subscription
Sun Dec 22 03:16:47.380 UTC
Subscription: health State: ACTIVE
-------------
Sensor groups:
Id Interval(ms) State
health 60000 Partial
Destination Groups:
Id Encoding Transport State Port Vrf IP
COLLECTOR self-describing-gpb tcp Active 50002 Mgmt-intf x.x.x.x
TLS : False
Subscription: mpls-te State: NA
-------------
Sensor groups:
Id Interval(ms) State
mpls-te 60000 Resolved
Subscription: routing State: ACTIVE
-------------
Sensor groups:
Id Interval(ms) State
routing 60000 Resolved
Destination Groups:
Id Encoding Transport State Port Vrf IP
COLLECTOR self-describing-gpb tcp Active 50002 Mgmt-intf x.x.x.x
TLS : False
Subscription: ANALYTICS State: ACTIVE
-------------
Sensor groups:
Id Interval(ms) State
TRAFFIC 30000 Resolved
Destination Groups:
Id Encoding Transport State Port Vrf IP
COLLECTOR self-describing-gpb tcp Active 50002 Mgmt-intf x.x.x.x
TLS : False
Subscription: interfaces State: ACTIVE
-------------
Sensor groups:
Id Interval(ms) State
interfaces 60000 Resolved
Destination Groups:
Id Encoding Transport State Port Vrf IP
COLLECTOR self-describing-gpb tcp Active 50002 Mgmt-intf x.x.x.x
TLS : False
IF OutだけですがGrafanaでこんな感じで見えました。
Traffic量の変化をSensor-pathを設定していないのに無事取得することができました。
3. ここからが本番:機械学習を使ってみる
ここで断っておきますが、このセットアップは12/22時点で作成しています。
早くから作っておけば学習結果まで出せたと思いますが、学習データの取得を考えるとこの記事の中では結果まで取り扱うことはできません。
なので、この記事ではここからは以下のRepositoryにあるデータを元に進めさせていただきます。
https;//github.com/mikemikhail/Telemetry-ML
DatabaseのImport
まずは以下のDirectoryにあるbackup dataをImportします。
/Telemetry-ML-main/data/db_backup_210321/
root@ubuntu:/opt/tig/Telemetry-ML-main/data# docker exec -it influxdb /bin/bash
root@df9adac65b0f:/# influxd restore -portable -db mdt_db -newdb mdt_db_210321 /data/db_backup_210321/
2024/12/22 03:36:34 Restoring shard 6315 live from backup 20210322T012905Z.s6315.tar.gz
2024/12/22 03:36:34 Restoring shard 6328 live from backup 20210322T012905Z.s6328.tar.gz
(snip)
root@df9adac65b0f:/#
root@df9adac65b0f:/# influx
Connected to http://localhost:8086 version 1.8.4
InfluxDB shell version: 1.8.4
>
>
> auth
username: telegraf
password:
> show databases
name: databases
name
----
telegraf
_internal
mdt_db_210321
> alter retention policy "autogen" on "mdt_db_210321" duration inf
> use mdt_db_210321
Using database mdt_db_210321
> show retention policies
name duration shardGroupDuration replicaN default
---- -------- ------------------ -------- -------
autogen 0s 6h0m0s 1 true
> show measurements
name: measurements
name
----
Cisco-IOS-XR-clns-isis-oper:isis/instances/instance/levels/level/adjacencies/adjacency
Cisco-IOS-XR-clns-isis-oper:isis/instances/instance/statistics-global
Cisco-IOS-XR-infra-statsd-oper:infra-statistics/interfaces/interface/latest/generic-counters
Cisco-IOS-XR-ip-rib-ipv4-oper:rib/vrfs/vrf/afs/af/safs/saf/ip-rib-route-table-names/ip-rib-route-table-name/protocol/isis/as/information
Cisco-IOS-XR-ip-rsvp-oper:rsvp/counters/interface-messages/interface-message
Cisco-IOS-XR-ip-rsvp-oper:rsvp/interface-briefs/interface-brief
Cisco-IOS-XR-ipv4-bgp-oper:bgp/instances/instance/instance-active/default-vrf/process-info
Cisco-IOS-XR-mpls-te-oper:mpls-te/tunnels/summary
Cisco-IOS-XR-pfi-im-cmd-oper:interfaces/interface-summary
Cisco-IOS-XR-shellutil-oper:system-time/uptime
Cisco-IOS-XR-wdsysmon-fd-oper:system-monitoring/cpu-utilization
> exit
無事に取れていそうです。
GrafanaにDataSource追加してみると以下の用に見えました。十分なデータ量ありそうですね。
TensorFlowのInstallとデータのImport
ここではTensorFlowを使って学習を行います。
PyCharmをInstallしてデータを取り込んでみます。
/Telemetry-ML-main/MLを指定して、requirement.txtの内容をpipインストールします。
root@ubuntu:/opt/Telemetry-ML-main/ML# pip install -r requirements.txt
Requirement already satisfied: absl-py==0.12.0 in /usr/local/lib/python3.6/site-packages (from -r requirements.txt (line 1)) (0.12.0)
Requirement already satisfied: astor==0.8.1 in /usr/local/lib/python3.6/site-packages (from -r requirements.txt (line 2)) (0.8.1)
(snip)
WARNING: Running pip as the 'root' user can result in broken permissions and conflicting behaviour with the system package manager. It is recommended to use a virtual environment instead: https://pip.pypa.io/warnings/venv
また、以下のDirectoryにPythonファイルが入っているのでこちらを活用します。
root@ubuntu:/opt/Telemetry-ML-main/ML/ML-anomaly_detection-replay-accelerated-4PM# ls -l
total 52
-rwxr-xr-x 1 root root 1463 Aug 28 2023 constants.py
-rwxr-xr-x 1 root root 5944 Aug 28 2023 monitor.py
-rwxr-xr-x 1 root root 22525 Aug 28 2023 read_df.py
-rwxr-xr-x 1 root root 13807 Aug 28 2023 tf_fn.py
root@ubuntu:/opt/Telemetry-ML-main/ML/ML-anomaly_detection-replay-accelerated-4PM# ./monitor.py
他のDirectoryでも並行してモデルの構築は可能ですが、環境にもよりますが私の環境では20分程度待ってみると終わりました。
学習結果
今回のパッケージでは通常のトラフィックパターンがどうなっているかを平日の60分毎に方向別で学習しています。
10分ごとにexperienceを更新しながら過去60分間のトラフィックパターンを元にトラフィック量を予測します。
そして、NRMSE(二乗平均平方根誤差)を元に異常を検知します。
簡単に各関数の説明を書くと以下のようになります。
constants.pyはコードの実行に使用する値を定義します。これには、データベースの認証情報、Trafficの方向、MLモデルの形状、実行する際のスリープの間隔などが含まれています。
read_df.pyには、データベースに特定の期間のデータを問い合わせたり、データをデータフレームと呼ばれるラベル付きに構造化する関数が含まれています。
tf_fn.pyには、機械学習関数、データの正規化、モデルの構築、学習と検証、損失計算、グラフ作成が含まれています。
monitor.pyは、ML学習を開始し、他のファイルで定義された関数を呼び出すドライバファイルです。これを実行することで学習を開始します。
中を見ていくと非常に多くのパラメータが存在しており、チューニングを行うのは職人技に思われますので、今回は誰かがチューニングしてくれたデフォルトの値で実行しました。
こちらの図では直近60分間隔のグラフを出してくれています。
青い線がMLモデルが予測した値で緑の戦が実際のトラフィック量をグラフ化したものです。
これを元に異常検知ができるものでしょうか。
次の図は、トレーニング/検証サイクルの結果(RMSE:二乗平均平方根誤差)のグラフです。RMSEは数値予測のモデルの良さを図る指標でモデルと実測の間に差がなければ低い値を取ります。
今回の結果ではハズレ値が大きくいくつか出ていますが、RMSEの変動が限定的であれば通常の変動、大きく変動する場合は(少なくとも学習モデルが想定できていない)異常なイベントを指します。
じゃあ、どれくらいの範囲に収まれば許容範囲なのかという点が非常に難しいポイントだと思います。。。
青の線がトレーニングによる予測されたもの、緑の線が実測なのですが、この図としては予期しないものが発生していることを示唆していると取れます。(けど、これが本当に障害や異常なのかまでは言い切れませんね。。。)
これで一応学習データと実測値の比較が取れたかなと思います。
4. おわりに
機械学習によるネットワークの異常検知について試してみました。
機械学習を用いた異常検知についてツールはすでにオープン化されているレベルで揃っていると思いました。
ただし、みなさま言われていることですが、誤検知などの対応はまだまだチャレンジが続く状況ですね。
使ってみるとどう難しいのかなどイメージがつきやすいですし、なにより動かしてみて面白いので興味ある方は試してみてください。
ここまで読んでいただきありがとうございました。
おしまい
免責事項
本サイトおよび対応するコメントにおいて表明される意見は、投稿者本人の個人的意見であり、シスコの意見ではありません。本サイトの内容は、情報の提供のみを目的として掲載されており、シスコや他の関係者による推奨や表明を目的としたものではありません。各利用者は、本Webサイトへの掲載により、投稿、リンクその他の方法でアップロードした全ての情報の内容に対して全責任を負い、本Web サイトの利用に関するあらゆる責任からシスコを免責することに同意したものとします。