CCIE lab対策(6.2. Network Automation)その3
前回は登録したデバイスに対して、通常のCLI操作と同じことをNSOから操作する検証をしました。今回は、サービス作成とサービスデプロイの検証をします。
1. サービス自動化の流れ
NSOにはテンプレートベースでサービスを作成し、そのサービスを実行することで自動化を実現することができます。
以下のリンク先に関連する内容があります。
community.cisco.com
これは素晴らしい!良い物を見つけました!
— やすお (@chimay_wh) March 18, 2022
①NSOの起動から②サービス作成して③デプロイするまでの簡潔な説明とサンプルがあります!
① Cisco NSOhttps://t.co/UlD4B5ZzqK
② Create Servicehttps://t.co/eNFoBd6Znb
③ Deploy Servicehttps://t.co/ZY87XG3rLd
かいつまんでまとめると、NSOでサービスを自動化する流れは以下のようになります。
例として作成するサービスはデバイス(IOS-XR:N1)にloopbackインターフェースを作成する内容です。
2. サービススケルトン作成
① NSOをインストールしたOS(Linux:Ubuntu)で、"ncs-make-package"コマンドを実行します。
大事なことは、カレントディレクトリに一連のディレクトリ・ファイルが生成されるということです。ここでは例として、OS(Linux:Ubuntu)の/root/WORKにLOOPBACKというサービス名で作成します。
ncs-make-package --service-skeleton template 【サービス名】
root@chas4:~/WORK# ncs-make-package --service-skeleton template LOOPBACK root@chas4:~/WORK#
② カレントディレクトリに一連のディレクトリ・ファイル(以後、サービスパッケージ若しくはパッケージと省略します。)が生成されます。
以降は生成されたパッケージを編集していきます。ディレクトリ階層は以下のようになっております。パッケージ開発で編集する対象は赤枠内にある2つのファイルのみです。
3. サービスパッケージ開発
3.1 サービステンプレート
サービスパッケージの開発ではサービステンプレートの作成とサービスモデルの作成を行います。サービステンプレートを作成するにあたり、NSOのconfig modeでサンプルコンフィグを作成します。
① デバイス(IOS-XR:N1)でloopbackインターフェースを作成します。 ただしcommitはしません。
admin@ncs# config Entering configuration mode terminal admin@ncs(config)# devices device N1 config admin@ncs(config-config)# interface Loopback 1 admin@ncs(config-if)# ipv4 address 10.0.0.1 255.255.255.255 admin@ncs(config-if)#
② 仮にcommitした場合のconfigをXML形式で表示します。
commit dry-run outformat xml
admin@ncs(config-if)# commit dry-run outformat xml result-xml { local-node { data <devices xmlns="http://tail-f.com/ns/ncs"> <device> <name>N1</name> <config> <interface xmlns="http://tail-f.com/ned/cisco-ios-xr"> <Loopback> <id>1</id> <ipv4> <address> <ip>10.0.0.1</ip> <mask>255.255.255.255</mask> </address> </ipv4> </Loopback> </interface> </config> </device> </devices> } } admin@ncs(config-if)#
今回作成するサービスは、loopbackインターフェースを作成するものです。具体的に言うと...
Interface Loopback100-199 この範囲で100種類作れるようにします。
かつIPアドレスは、10.100.x.x/32~10.199.x.x/32 に設定するというものです。
③ 出力したXMLファイルを見ると変動する値と固定の値の2種類があります。
この赤と青を変数扱いにすれば、テンプレートとして使えることが何となく想像できると思います。変数はサービス利用時に利用者が指定することを想定しています。
④ サービステンプレートを作成します。サービステンプレートは、OS(Linux:Ubuntu)で編集します。以下は、変更前のサービステンプレート(LOOPBACK-template.xml)です。
<config-template xmlns="http://tail-f.com/ns/config/1.0" servicepoint="LOOPBACK"> <devices xmlns="http://tail-f.com/ns/ncs"> <device> <!-- Select the devices from some data structure in the service model. In this skeleton the devices are specified in a leaf-list. Select all devices in that leaf-list: --> <name>{/device}</name> <config> <!-- Add device-specific parameters here. In this skeleton the service has a leaf "dummy"; use that to set something on the device e.g.: <ip-address-on-device>{/dummy}</ip-address-on-device> --> </config> </device> </devices> </config-template>
英語のコメント通りです。" Add device-specific parameters here."の箇所を編集します。編集内容は、③の太字部分をコピー&ペーストして、変数を特定の文字列に置き換えます。
変数(1)ループバックインターフェース名:LOOPBACK-INTF
変数(2)IPアドレス:IP-ADDRESS
参考までに完成したサービステンプレートを以下に示します。
<config-template xmlns="http://tail-f.com/ns/config/1.0" servicepoint="LOOPBACK"> <devices xmlns="http://tail-f.com/ns/ncs"> <device> <!-- Select the devices from some data structure in the service model. In this skeleton the devices are specified in a leaf-list. Select all devices in that leaf-list: --> <name>{/device}</name> <config> <interface xmlns="http://tail-f.com/ned/cisco-ios-xr"> <Loopback> <id>{LOOPBACK-INTF}</id> <ipv4> <address> <ip>{IP-ADDRESS}</ip> <mask>255.255.255.255</mask> </address> </ipv4> </Loopback> </interface> </config> </device> </devices> </config-template>
3.2 サービスモデル
① サービスモデルを作成します。サービスモデルも、OS(Linux:Ubuntu)で編集します。
以下は、変更前のサービスモデル(LOOPBACK.yang)です。
module LOOPBACK { namespace "http://com/example/LOOPBACK"; prefix LOOPBACK; import ietf-inet-types { prefix inet; } import tailf-ncs { prefix ncs; } list LOOPBACK { key name; uses ncs:service-data; ncs:servicepoint "LOOPBACK"; leaf name { type string; } // may replace this with other ways of refering to the devices. leaf-list device { type leafref { path "/ncs:devices/ncs:device/ncs:name"; } } // replace with your own stuff here leaf dummy { type inet:ipv4-address; } } }
② 今回の編集ポイントは大きく6つあります。
a) インポートするモジュールの名前をimportステートメントで、インポートする名前とprefixを宣言します。
import tailf-common { prefix tailf; }
b) augmentステートメントで、サービスを宣言します。
augment /ncs:services {
c) 定義が分からなくならないようにコメントを挿入します。
tailf:info “【コメント文】”;
leaf name { tailf:info “Service Instance Name”; type string; }
d) デバイスをleaf-listではなくleafに変更します。かつサービス利用時に入力必須項目1にします。
leaf-list device { tailf:info “Router Name”; mandatory true; type leafref { path "/ncs:devices/ncs:device/ncs:name"; } }
e) 変数(1)ループバックインターフェース名:LOOPBACK-INTF を記述します。
typeは符号なし整数を指定します。かつサービス利用時に入力必須項目にします。
leaf LOOPBACK-INTF { tailf:info “Loopback Interface Number from 100 to 199”; mandatory true; type uint32{ range “100..199”; } }
f) 変数(2)IPアドレス:IP-ADDRESS を記述します。
かつサービス利用時に入力必須項目にします。ここで敢えて間違えた記述(pattern)をします。後でコンパイルエラーを修正したいからという理由です。
leaf IP-ADDRESS{ tailf:info "Valid IP range from 10.100.x.x to 10.199.x.x"; mandatory true; type inet:ipve-address{ pattern “10\.1[0-9][0-9]\.[0-9]+\.[0-9]+”; } }
4. パッケージのコンパイル
① Makefile が配置されている”LOOPBACK/src”ディレクトリに移動して、makeコマンドを実行してサービスコードをコンパイルします。
cd ~/WORK/LOOPBACK/src make
/nso-5.7//bin/ncsc `ls LOOPBACK-ann.yang > /dev/null 2>&1 && echo "-a LOOPBACK-ann.yang"` \ --fail-on-warnings \ \ -c -o ../load-dir/LOOPBACK.fxs yang/LOOPBACK.yang yang/LOOPBACK.yang:37:19: error: illegal character after \ yang/LOOPBACK.yang:37:32: error: illegal character after \ yang/LOOPBACK.yang:37:40: error: illegal character after \ Makefile:26: recipe for target '../load-dir/LOOPBACK.fxs' failed make: *** [../load-dir/LOOPBACK.fxs] Error 1 root@chas4:~/WORK/LOOPBACK/src#
コンパイルしてエラーがある場合は、XX行目にエラーがあると通知してくれます。タイポだったり構文エラーだったり理由は様々です。
② YANGファイルで間違えた記述を修正します。"."までを一つの区切りとするように()で括り、全体をシングルクォーテーションで囲みました。
leaf IP-ADDRESS{ tailf:info "Valid IP range from 10.100.x.x to 10.199.x.x"; type inet:ipve-address{ pattern '(10\.)(1[0-9][0-9]\.)([0-9]+\.)([0-9]+)'; } }
③ 再度コンパイルします。
cd ~/WORK/LOOPBACK/src make
root@chas4:~/WORK/LOOPBACK/src/yang# cd ../ root@chas4:~/WORK/LOOPBACK/src# make /nso-5.7//bin/ncsc `ls LOOPBACK-ann.yang > /dev/null 2>&1 && echo "-a LOOPBACK-ann.yang"` \ --fail-on-warnings \ \ -c -o ../load-dir/LOOPBACK.fxs yang/LOOPBACK.yang root@chas4:~/WORK/LOOPBACK/src#
このようにエラーが無くなればOKです!
④ 作成したパッケージ格納ディレクトリへのシンボリックリンクを、NSOのランタイムディレクトリ2のpackagesディレクトリ配下に作成します。
ln -s 【パッケージ格納ディレクトリ】【NSOランタイムディレクトリ】/packages
root@chas4:~/WORK/LOOPBACK/src# ln -s ~/WORK/LOOPBACK/ /nso-5.7/ncsrun/packages/ root@chas4:~/WORK/LOOPBACK/src# ls -l /nso-5.7/ncsrun/packages/ total 117548 lrwxrwxrwx 1 root root 20 Mar 25 09:28 LOOPBACK -> /root/WORK/LOOPBACK/ -rw-r--r-- 1 root root 6899909 Jan 12 02:56 ncs-5.7-cisco-asa-6.13.12.tar.gz -rw-r--r-- 1 root root 61131311 Jan 22 08:48 ncs-5.7-cisco-ios-6.77.10.tar.gz -rw-r--r-- 1 root root 42440773 Jan 21 19:09 ncs-5.7-cisco-iosxr-7.38.3.tar.gz -rw-r--r-- 1 root root 9891157 Jan 12 12:44 ncs-5.7-cisco-nx-5.22.8.tar.gz root@chas4:~/WORK/LOOPBACK/src#
参考までにシンボリックリンクを削除する場合は、unlinkコマンドを使います。
unlink 【シンボリックリンクのパス】
root@chas4:~/WORK/LOOPBACK/src# unlink /nso-5.7/ncsrun/packages/LOOPBACK root@chas4:~/WORK/LOOPBACK/src# root@chas4:~/WORK/LOOPBACK/src# ls -l /nso-5.7/ncsrun/packages/ total 117548 -rw-r--r-- 1 root root 6899909 Jan 12 02:56 ncs-5.7-cisco-asa-6.13.12.tar.gz -rw-r--r-- 1 root root 61131311 Jan 22 08:48 ncs-5.7-cisco-ios-6.77.10.tar.gz -rw-r--r-- 1 root root 42440773 Jan 21 19:09 ncs-5.7-cisco-iosxr-7.38.3.tar.gz -rw-r--r-- 1 root root 9891157 Jan 12 12:44 ncs-5.7-cisco-nx-5.22.8.tar.gz root@chas4:~/WORK/LOOPBACK/src#
重要なのはコンパイルに成功してからシンボリックリンクを作成することです。
参考までに完成したサービスモデルを以下に示します。
module LOOPBACK { namespace "http://com/example/LOOPBACK"; prefix LOOPBACK; import ietf-inet-types { prefix inet; } import tailf-ncs { prefix ncs; } import tailf-common { prefix tailf; } augment /ncs:services { list LOOPBACK { key name; uses ncs:service-data; ncs:servicepoint "LOOPBACK"; leaf name { tailf:info “Service Instance Name”; type string; } leaf device { tailf:info “Router Name”; mandatory true; type leafref { path "/ncs:devices/ncs:device/ncs:name"; } } leaf LOOPBACK-INTF { tailf:info “Loopback Interface Number from 100 to 199”; mandatory true; type uint32 { range “100..199”; } } leaf IP-ADDRESS { tailf:info "Valid IP range from 10.100.x.x to 10.199.x.x"; mandatory true; type inet:ipve-address { pattern '(10\.)(1[0-9][0-9]\.)([0-9]+\.)([0-9]+)'; } } } } }
5. パッケージをNSOにロード
ncs_cli -u admin -C
root@chas4:~/WORK/LOOPBACK/src# ncs_cli -u admin -C User admin last logged in 2022-03-25T08:09:39.475876+00:00, to chas4, from 127.0.0.1 using cli-console admin connected from 127.0.0.1 using console on chas4 admin@ncs#
② パッケージをロードします。少し時間がかかります。"result true"と表示すれば成功です!
packages reload
admin@ncs# packages reload >>> System upgrade is starting. >>> Sessions in configure mode must exit to operational mode. >>> No configuration changes can be performed until upgrade has completed. >>> System upgrade has completed successfully. reload-result { package LOOPBACK result true } reload-result { package cisco-asa-cli-6.13 result true } reload-result { package cisco-ios-cli-6.77 result true } reload-result { package cisco-iosxr-cli-7.38 result true } reload-result { package cisco-nx-cli-5.22 result true } admin@ncs# System message at 2022-03-17 02:54:36... Subsystem stopped: ncs-dp-8-cisco-ios-cli-6.77:IOSDp admin@ncs# System message at 2022-03-17 02:54:36... Subsystem stopped: ncs-dp-9-cisco-nx-cli-5.22:NexusDp admin@ncs# System message at 2022-03-17 02:54:36... Subsystem stopped: ncs-dp-7-cisco-asa-cli-6.13:ASADp admin@ncs# System message at 2022-03-17 02:54:36... Subsystem started: ncs-dp-10-cisco-asa-cli-6.13:ASADp admin@ncs# System message at 2022-03-17 02:54:36... Subsystem started: ncs-dp-11-cisco-ios-cli-6.77:IOSDp admin@ncs# System message at 2022-03-17 02:54:36... Subsystem started: ncs-dp-12-cisco-nx-cli-5.22:NexusDp admin@ncs#
いよいよ、サービスの実行です。
6. NSOでサービス実行
今回作成するサービスは、loopbackインターフェースを作成するものです。具体的に言うと...
Interface Loopback100-199 この範囲で100種類作れるようにします。
かつIPアドレスは、10.100.x.x/32~10.199.x.x/32 に設定するというものです。
① sync-fromを実行し、NSOのCDBを最新化します。"result true"と表示すれば成功です!
sync-fromを実行せずにサービスを実行すると途中でエラーを表示してしまいます。
devices sync-from device 【デバイス名】
admin@ncs# devices sync-from device N1 sync-result { device N1 result true } admin@ncs#
② サービスの実行は、config modeで行います。
config
admin@ncs# config Entering configuration mode terminal admin@ncs(config)#
③ サービスを実行します。サービス名は"LOOPBACK"です。識別文字列は数字だけでも良いです。
services 【サービス名】【識別文字列】
admin@ncs(config)# services LOOPBACK TEST_OF_LOOPBACK100
④ サービスを実行するデバイスの入力が求められます。今回は登録している”N1”を入力します。
N1
Value for 'device' [N1]: N1
入力候補が複数ある場合は、その旨表示されます。利用者に優しいです。
e.g. Value for 'device' [N1,N2,N3,N4,...]:
⑤ ループバックインターフェース名を入力します。今回は、”100”を入力します。
100
Value for 'LOOPBACK-INTF' (<unsignedInt, 100 .. 199>): 100
サービステンプレート、サービスモデルで指定した"LOOPBACK-INTF"と範囲を表示します。
⑥ ループバックインターフェースのIPアドレスを入力します。今回は、”10.100.1.100”を入力します。
10.100.1.100
Value for 'IP-ADDRESS' (<IPv4 address>): 10.100.1.100 admin@ncs(config-LOOPBACK-TEST_OF_LOOPBACK100)#
⑦ commitするとどうなるのかを確認します。
commit dry-run
admin@ncs(config-LOOPBACK-TEST_OF_LOOPBACK100)# commit dry-run cli { local-node { data devices { device N1 { config { interface { + Loopback 100 { + ipv4 { + address { + ip 10.100.1.100; + mask 255.255.255.255; + } + } + } } } } } services { + LOOPBACK TEST_OF_LOOPBACK100 { + device N1; + LOOPBACK-INTF 100; + IP-ADDRESS 10.100.1.100; + } } } } admin@ncs(config-LOOPBACK-TEST_OF_LOOPBACK100)#
⑧ 定義に問題がないことを確認したら、commitします。もしこの時点で入力し直したい場合は、サービスを強制終了します。
abort
admin@ncs(config-LOOPBACK-TEST_OF_LOOPBACK100)# abort admin@ncs#
サービスを強制終了したら、②からやり直します。
⑨ 仮に⑦で問題ないことを確認したとしてcommitします。
commit
admin@ncs(config-LOOPBACK-TEST_OF_LOOPBACK100)# commit Commit complete. admin@ncs(config-LOOPBACK-TEST_OF_LOOPBACK100)#
⑩ デバイスのshowコマンドでループバックの定義状況を確認します。
do devices device N1 live-status exec show ip int lo100
admin@ncs(config)# do devices device N1 live-status exec show ip int lo100 result Fri Mar 25 10:19:54.453 UTC Loopback100 is Up, ipv4 protocol is Up Vrf is default (vrfid 0x60000000) Internet address is 10.100.1.100/32 MTU is 1500 (1500 is available to IP) Helper address is not set Directed broadcast forwarding is disabled Outgoing access list is not set Inbound common access list is not set, access list is not set Proxy ARP is disabled ICMP redirects are never sent ICMP unreachables are always sent ICMP mask replies are never sent Table Id is 0xe0000000 RP/0/RP0/CPU0:N1# admin@ncs(config)#
これで、オペレータが”デバイス”と”インターフェース名”と”IPアドレス”を入力するだけでループバックインターフェースの設定をすることができました。
参考までに②~⑥で誤った入力をするとどうなるかを紹介します。
サービス実行対象を間違えた場合
admin@ncs(config)# services LOOPBACK 101 Value for 'device' [N1]: N2 The value must be one of: N1
"N1"だけが入力できる旨が通知されます。デバイス名を正しく入力して、インターフェース名を間違えた場合
Value for 'device' [N1]: N1 Value for 'LOOPBACK-INTF' (<unsignedInt, 100 .. 199>): 200 Error: bad value: "200" is out of range.
200は間違いである旨が通知されます。インターフェース名を正しく入力して、IPアドレスを間違えた場合
Value for 'LOOPBACK-INTF' (<unsignedInt, 100 .. 199>): 101 Value for 'IP-ADDRESS' (<IPv4 address>): 1.1.1.1 Error: bad value: "1.1.1.1" is an invalid value.
1.1.1.1は間違いである旨が通知されます。IPアドレスを正しく入力して、定義の内容を確認します。
Value for 'IP-ADDRESS' (<IPv4 address>): 10.101.101.101 admin@ncs(config-LOOPBACK-101)# commit dry-run cli { local-node { data devices { device N1 { config { interface { + Loopback 101 { + ipv4 { + address { + ip 10.101.101.101; + mask 255.255.255.255; + } + } + } } } } } services { + LOOPBACK 101 { + device N1; + LOOPBACK-INTF 101; + IP-ADDRESS 10.101.101.101; + } } } } admin@ncs(config-LOOPBACK-101)#
仮にオペレータが間違えた入力をしてもコマンドが受け付けられないようになっています。フールプルーフ3が備わっているのは素敵です。
次回はデバイス(IOS-XR)にSegment Routingを自動設定するサービスの作成とデプロイの検証をします。
最後までお読みいただきありがとうございました!