Vous souhaiterez peut-être voir les résultats de la commande show lors de la surveillance de l'équipement réseau Cisco. Cette fois, j'aimerais obtenir le résultat de la commande show de l'invité Shell d'IOS-XE en utilisant python et l'envoyer à Elasticsearch pour la visualisation.
Guest Shell est un environnement de conteneur Linux hébergé par IOx et implémenté dans des produits tels que les séries Catalyst 9000 et ISR 4000. Guest Shell fournit une bibliothèque cli python qui vous permet d'exécuter des commandes IOSd à partir d'un script python qui s'exécute dans Guest Shell. Pour plus d'informations sur IOx, veuillez consulter ici.
Le diagramme d'image lors de la communication est le suivant.
[Guide de configuration de la programmabilité, Cisco IOS XE Fuji 16.9.x](https://www.cisco.com/c/en/us/td/docs/ios-xml/ios/prog/configuration/169/b_169_programmability_cg/guest_shell. depuis html)
Créez l'environnement avec la configuration suivante. (La méthode de construction est omise) La cible de surveillance est CSR1. Bien que simplifié, nous avons également préparé une VM pour mettre une charge de communication sur CSR1.
Software | Version |
---|---|
Elasticsearch | 6.5.0 |
Kibana | 6.5.0 |
CSR1000V | IOS-XE 16.09.04 |
Elasticsearch est un moteur de recherche en texte intégral et est également utilisé comme système de gestion de base de données appelé magasin de documents (ou orienté document). J'écrirai brièvement les termes. (Je comprends jusqu'à ce que je m'en lasse)
le terme | sens |
---|---|
Document | Unité de données JSON à stocker |
Mapping | Une définition concrète du contenu du document |
Index | Nom d'index toujours donné au document Utilisé comme unité pour définir et interroger Il peut être créé à l'avance ou automatiquement lorsque le document est enregistré. |
Template | Paramètres et mappage appliqués lors de la création d'un nouvel index |
Nous allons acquérir les informations suivantes en tant qu'éléments de suivi de CSR1.
--Heure Date)
Définissez un modèle d'index pour stocker les données ci-dessus. Définissons également l'index lors du stockage du document de CSR1 vers router-csr.
curl -XPUT 'http://elasticsearch.example.com:9200/_template/router' -H 'Content-Type: application/json' -d @router_template.json
router_template.json
{
"template": "router-*",
"mappings":{
"monitoring": {
"dynamic": "strict",
"properties": {
"@timestamp":{
"type": "date",
"format": "date_time_no_millis"
},
"cpu_utilization_iosd":{
"type": "integer"
},
"cpu_utilization_kernel":{
"type": "integer"
},
"memory_utilization_iosd":{
"type": "integer"
},
"memory_utilization_kernel":{
"type": "integer"
},
"GigabitEthernet1_input":{
"type": "integer"
},
"GigabitEthernet1_output":{
"type": "integer"
},
"interface_status":{
"type": "keyword"
},
"routing_table":{
"type": "keyword"
}
}
}
}
}
Pour la quantité d'émission / réception de GigabitEthernet1, nous utiliserons la moyenne pendant 30 secondes. Il est possible de calculer à partir de la différence entre le nombre de paquets envoyés et reçus, mais je pense qu'il est plus facile d'ajuster "load-interval" et de l'obtenir depuis "show interface".
CSR1#conf t
CSR1(config)#interface gigabitethernet 1
CSR1(config-if)#load-interval 30
Ensuite, configurez pour activer Guest Shell et configurez NAT pour communiquer à partir de Guest Shell en même temps.
CSR1#conf t
CSR1(config)#iox
CSR1(config)#ip http server
CSR1(config)# interface GigabitEthernet3
CSR1(config-if)# ip nat outside
CSR1(config-if)# exit
CSR1(config)# interface VirtualPortGroup0
CSR1(config-if)# ip address 192.168.35.1 255.255.255.0
CSR1(config-if)# ip nat inside
CSR1(config-if)# exit
CSR1(config)# ip nat inside source list GS_NAT_ACL interface GigabitEthernet3 overload
CSR1(config)# ip access-list standard GS_NAT_ACL
CSR1(config-std-nacl)# permit 192.168.35.0 0.0.0.255
CSR1(config-std-nacl)# exit
CSR1(config)#app-hosting appid guestshell
CSR1(config-app-hosting)# app-vnic gateway0 virtualportgroup 0 guest-interface 0
CSR1(config-app-hosting-gateway0)# guest-ipaddress 192.168.35.2 netmask 255.255.255.0
CSR1(config-app-hosting-gateway0)# app-default-gateway 192.168.35.1 guest-interface 0
CSR1(config-app-hosting)# name-server0 192.0.2.1
CSR1(config-app-hosting)# end
CSR1#guestshell enable
Guest Shell est maintenant activé.
Lancer guesthell
à partir du mode privilégié lancera le conteneur bash et vous permettra de vous connecter.
Lançons Guset Shell et exécutons les commandes IOSd.
CSR1#guestshell
[guestshell@guestshell ~]$ dohost "show app-hosting list"
App id State
------------------------------------------------------
guestshell RUNNING
[guestshell@guestshell ~]$ python
Python 2.7.5 (default, Jun 17 2014, 18:11:42)
[GCC 4.8.2 20140120 (Red Hat 4.8.2-16)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import cli
>>> cli.cli("show app-hosting list")
'\nApp id State\n------------------------------------------------------\nguestshell RUNNING\n'
>>> exit()
[guestshell@guestshell ~]$
Utilisez EEM pour exécuter les commandes Guest Shell à partir d'IOS-XE. ʻEvent timer watchdog` peut être utilisé comme un déclencheur pour exécuter des scripts python sur une base régulière.
CSR1#conf t
CSR1(config)#event manager applet elasticsearch
CSR1(config-applet)#event timer watchdog time 30
CSR1(config-applet)#action 100 cli command "enable"
CSR1(config-applet)#action 200 cli command "guestshell run python /home/guestshell/monitoring.py"
Extrayez la chaîne de caractères cible de la commande show correspondant à chaque élément de surveillance et utilisez-la comme valeur de l'objet de type dictionnaire, et utilisez la même clé que Mapping. Il est nécessaire de convertir le format de l'heure et de calculer la valeur de l'utilisation de la mémoire.
--Heure (date) -> afficher l'horloge
--Utilisation du processeur iOS (%) -> afficher les processus cpu | i CPU
--kernel CPU usage (%) -> show process cpu platform | i CPU
afficher la mémoire des processus | i Processeur
show process memory platform | i System memory
--GigabitEthernet1 envoyer / recevoir (bps) -> afficher l'interface GigabitEthernet1
--Liste de l'état des protocoles d'interface / ligne (texte) -> show ip interface brief
--Routen table (texte) -> show ip route
Concaténez tous les objets de type dictionnaire et envoyez-les sous forme de données JSON à Elasticsearch.
Le code sera affiché sur le lien ci-dessous. https://gist.github.com/ecodrive-18/f808df5a69b9a47e97288789cfa53c9d
Installez les bibliothèques nécessaires avant de l'exécuter.
CSR1#guestshell
[guestshell@guestshell ~]$ sudo pip install -r requirements.txt
requirements.txt
elasticsearch>=6.0.0,<7.0.0
python-dateutil==2.8.1
Essayez d'interroger Elasticsearch pour voir si les résultats de l'exécution du script peuvent être stockés.
curl -XGET 'http://elasticsearch.example.com:9200/router-csr/monitoring/_search?size=1' | jq
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 2765 100 2765 0 0 128k 0 --:--:-- --:--:-- --:--:-- 128k
{
"took": 13,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"skipped": 0,
"failed": 0
},
"hits": {
"total": 232,
"max_score": 1,
"hits": [
{
"_index": "router-csr",
"_type": "monitoring",
"_id": "hHV2Xm4BlqMaqiTz5GDW",
"_score": 1,
"_source": {
"GigabitEthernet1_output": "30000",
"routing_table": "\nCodes: L - local, C - connected, S - static, R - RIP, M - mobile, B - BGP\n D - EIGRP, EX - EIGRP external, O - OSPF, IA - OSPF inter area \n N1 - OSPF NSSA external type 1, N2 - OSPF NSSA external type 2\n E1 - OSPF external type 1, E2 - OSPF external type 2\n i - IS-IS, su - IS-IS summary, L1 - IS-IS level-1, L2 - IS-IS level-2\n ia - IS-IS inter area, * - candidate default, U - per-user static route\n o - ODR, P - periodic downloaded static route, H - NHRP, l - LISP\n a - application route\n + - replicated route, % - next hop override, p - overrides from PfR\nGateway of last resort is 172.16.0.254 to network 0.0.0.0\nS* 0.0.0.0/0 [254/0] via 172.16.0.254\n 10.0.0.0/32 is subnetted, 2 subnets\nO 10.0.0.254 [110/2] via 192.168.255.2, 19:32:27, GigabitEthernet2\nO 10.100.0.254 [110/2] via 192.168.255.2, 19:32:27, GigabitEthernet2\n 172.16.0.0/16 is variably subnetted, 3 subnets, 2 masks\nC 172.16.0.0/24 is directly connected, GigabitEthernet3\nL 172.16.0.207/32 is directly connected, GigabitEthernet3\nS 172.16.0.254/32 [254/0] via 172.16.0.254, GigabitEthernet3\n 192.168.0.0/24 is variably subnetted, 2 subnets, 2 masks\nC 192.168.0.0/24 is directly connected, GigabitEthernet1\nL 192.168.0.254/32 is directly connected, GigabitEthernet1\nO 192.168.1.0/24 [110/2] via 192.168.255.2, 19:34:13, GigabitEthernet2\n 192.168.35.0/24 is variably subnetted, 2 subnets, 2 masks\nC 192.168.35.0/24 is directly connected, VirtualPortGroup0\nL 192.168.35.1/32 is directly connected, VirtualPortGroup0\n 192.168.255.0/24 is variably subnetted, 2 subnets, 2 masks\nC 192.168.255.0/30 is directly connected, GigabitEthernet2\nL 192.168.255.1/32 is directly connected, GigabitEthernet2\n",
"cpu_utilization_iosd": "0",
"cpu_utilization_kernel": "22",
"memory_utilization_kernel": "61",
"@timestamp": "2019-11-12T16:14:30+09:00",
"interface_status": "\nInterface IP-Address OK? Method Status Protocol\nGigabitEthernet1 192.168.0.254 YES manual up up \nGigabitEthernet2 192.168.255.1 YES manual up up \nGigabitEthernet3 172.16.0.207 YES DHCP up up \nVirtualPortGroup0 192.168.35.1 YES manual up up \n",
"memory_utilization_iosd": "14",
"GigabitEthernet1_input": "787000"
}
}
]
}
}
Des informations ont été envoyées depuis CSR1 dans hits.hits._source. Il est stocké correctement.
Visualisons les informations accumulées dans Elasticsearch avec Kibana. Je n'ai pas trouvé la fonction pour afficher le texte stocké dans Visualize tel quel ... Il semble que Markdown of Canvas ait cette fonction, alors j'ai essayé de l'utiliser. Si vous affichez le texte tel qu'il est dans le bloc de code, il sera cassé, donc c'est bien. Bien sûr, vous pouvez également créer des graphiques.
J'ai essayé de visualiser en envoyant des informations sur le périphérique à partir de l'invité Shell de IOS-XE.
Si cette fonction est implémentée dans de nombreux périphériques, il peut être possible de surveiller les périphériques à l'aide de l'agent de surveillance au lieu de SNMP.
En passant, lors de l'exécution de la surveillance de type pull, Python doit être un processus résident avec l'invité Shell obtenant IOSd VTY, donc maxrun
doit être mis à 0 lors de la définition de ʻevent` d'EEM. ..
Recommended Posts