Introduzione
In questo documento vengono descritte le diverse modalità di rilevamento di un problema generale sul fabric.
Prerequisiti
Requisiti
- Cisco raccomanda la conoscenza di ACI
- Conoscenze base di bash
Componenti usati
Il documento può essere consultato per tutte le versioni software o hardware.
Dispositivi usati:
- Cisco ACI con versione 4.2(3)
Le informazioni discusse in questo documento fanno riferimento a dispositivi usati in uno specifico ambiente di emulazione. Su tutti i dispositivi menzionati nel documento la configurazione è stata ripristinata ai valori predefiniti. Se la rete è operativa, valutare attentamente eventuali conseguenze derivanti dall'uso dei comandi.
Premesse
Strumenti utilizzati per acquisire le informazioni
- Inviato per sostituire: L'uso di "s/<oldword >/<new word>/g" g definisce che è fatto più di una volta.
- Inviare per acquisire le righe dall'inizio alla fine: Utilizzare "/<begin/,/end/p>". Combinate l'opzione -n (noprint) con il flag di stampa /p per duplicare le funzionalità di grep.
- Sed può essere utilizzato più volte utilizzando ";", ad esempio: potrebbe: sed "s/<oldword >/<nuova parola>/g; s/<oldword2 >/<nuova parola2>/g"
- awk -F '<separatore_campo>' '{print $2}' In questo esempio specifico, la riga viene divisa in base al FIELD_SEPARATOR definito e viene stampato il secondo blocco delimitato. Entrambe le sintassi fanno esattamente la stessa cosa.
- awk '{ print $1, $2 }' stampa i primi due campi di ogni record di input, con uno spazio tra di essi.
- ordinare | uniq Riporta le righe ripetute. Utilizzo delle righe del prefisso -c per il numero di occorrenze.
- sort -nrk <colonna> ordina le righe più in alto. -n per un ordinamento numerico, -k per una chiave in modo da poter modificare la colonna e se si desidera definire il valore più basso è possibile rimuovere -r
- python -m json.tool Visualizza JSON in un formato grazioso.
Elenco di tutti i comandi a riga singola
Ottenere solo gli ID dei nodi delle FOGLIA all'interno dell'infrastruttura:
- In un elenco:
APIC#acidiag fnvread | grep leaf | awk '{print $1}'
- In una riga con le virgole come separatori:
APIC#acidiag fnvread | grep leaf | awk '{print $1}' | sed -z 's/\n/,/g;s/,$/\n/'
Verificare se sono presenti reimpostazioni dell'interfaccia:
Le informazioni vengono ordinate sulle interfacce con il maggior numero di ripristini.
APIC#moquery -c ethpm.PhysIf | egrep "dn|lastLinkStChg|resetCtr" | tr -d "\n" | sed "s/dn/\ndn/g;s/lastLinkStChg/\tlastLinkStChg/g;s/resetCtr/\tresetCtr/g" | sort -nrk 9 | more
opzione più lenta
APIC#for leaf in `acidiag fnvread | grep leaf | awk '{print $1}'`; do echo; echo " -> leaf ID: $leaf "; fabric $leaf show interface | sed -n '/net[0-9]\/[0-9]\+ is up/,/Tx pause/p' | egrep "is up|Last link flapped|interface resets" | grep -v Dedicated | tr -d "\n" | sed "s/resets/rests\n/g" | sort -nrk 9 ; done;
Controllare l'interfaccia con la classificazione più alta:
Per individuare il punto in cui viene ricevuto il maggior numero di traffico:
Eseguire una query sull'infrastruttura per tutte le interfacce con throughput di output su un valore specifico (b). Il valore di m definisce se b è gb, mb o kb.
Per filtrare in base a gb impostare m su 12500000. Per filtrare in base a mb impostare m su 125000. Per filtrare in base a kb impostare m su 125.
APIC#bash
APIC#b=1; m=125000;b=$((b*m)); printf "%-65s %25s\n", "Node/Interface" "Bits/Second"; icurl 'http://localhost:7777/api/class/eqptEgrTotal5min.json?query-target-filter=gt(eqptEgrTotal5min.bytesRateLast,"'$b'")&order-by=eqptEgrTotal5min.bytesRateLast|desc' 2>/dev/null | python -m json.tool | egrep "dn|bytesRateLast" | sed -e 's/\s\+//g' | tr -d '\n' | sed -e 's/\"bytesRateLast\"/\n\"bytesRateLast\"/g' | sed -r '/^\s*$/d' | awk -F "\"" '{ printf "%-65s %25.2f\n", $8,$4*8}'
APIC#for leaf in `acidiag fnvread | grep leaf | awk '{print $1}'`; do echo; echo " -> leaf ID: $leaf "; fabric $leaf show int | sed -n '/net[0-9]\/[0-9]\+ is up/,/Tx pause/p' | egrep -i '[0-9]+ is up|30 seconds input' | tr -d '\n' | sed 's/packets\/sec/\n/g' | sort -n -r -k 10 ; done;
Trova tutte le modifiche alla topologia STP:
- Il comando passa in ciascuna foglia e verifica se sono state apportate modifiche recenti alla topologia e in quali interfacce:
APIC#for node in `acidiag fnvread | grep leaf | awk '{print $1}'`; do echo; echo "node ID: $node "; fabric $node show mcp internal info vlan all | grep -A 2 -B 4 "Last TC flush at" | sed -z 's/\n/ /g' | sed 's/--/\n/g;s/ $/\n/' | sort -n -r -k 22 ; done;
- Il comando passa in ciascuna foglia e verifica il conteggio più alto in base alle modifiche PVRSTP e le interfacce visualizzate:
APIC#for node in `acidiag fnvread | grep leaf | awk '{print $1}'`; do echo; echo "node ID: $node "; fabric $node show mcp internal info vlan all | grep -A 2 -B 4 "Last TC flush at" | sed -z 's/\n/ /g' | sed 's/--/\n/g;s/ $/\n/' | sort -n -r -k 11 ; done;
Verificare se sono presenti interruzioni RPF multicast:
Questa operazione deve essere eseguita per la singola foglia in quel momento e verifica tutte le VRF PIM abilitate per ogni perdita di RPF:
APIC#for vrf in `show ip mroute summary vrf all | grep 'IP Multicast Routing Table for VR' | awk '{print $7}' | sed 's/"//g' ` ; do echo; echo -e "VRF id: $vrf: \n" ; show ip mroute summary rpf-failed vrf $vrf | egrep "Source count: [1-9][0-9]*|[1-9]\.[0-9]{3}|LEAF|leaf" | sed -n '/Group.*count: [1-9][0-9]*/,/bps [0-9]*/p' | awk '{print $1, $2}' | sed 's/,/ - SRC \/ pckt:\n/g' ; done;
Verificare se ci sono troppi pacchetti che ottengono Glean:
- Glean ARP fabric:
APIC#for leaf in `acidiag fnvread | grep leaf | awk '{print $1}'`; do echo; echo " -> leaf ID: $leaf "; fabric $leaf show ip arp internal event-history event | grep glean | grep "Received pkt Fabric-Glean" | awk -F 'log_collect_arp_glean;' '{print $2}' | awk -F 'info =' '{print $1}' | sort | uniq -c ; done;
2. ARP glean Pacchetti ricevuti:
APIC#for leaf in `acidiag fnvread | grep leaf | awk '{print $1}'`; do echo; echo " -> leaf ID: $leaf "; fabric $leaf show ip arp internal event-history event | grep "Received glean packet" | awk -F 'log_collect_arp_glean;' '{print $2}' | awk -F 'info =' '{print $1}' | sort | uniq -c ; done;
Statistiche rilascio QoS:
Verificare che QoS abbia ricevuto cali per l'intera struttura:
APIC#moquery -c qosmIfClass -f 'qosm.IfClass.RxDropPacketsCount!="0"' | egrep "RxDropPacketsCount|dn" | awk '{print $3}' | tr -d "\n" | sed 's/level[0-9]/level\t\n/g'| sed 's/plane/plane\n/g' | awk -F 'topology/' '{print $2}'
Verificare le perdite di trasmissione QoS per l'intero fabric:
APIC#moquery -c qosmIfClass -f 'qosm.IfClass.TxDropPacketsCount!="0"' | egrep "TxDropPacketsCount|dn" | awk '{print $3}' | tr -d "\n" | sed 's/level[0-9]/level\t\n/g'| sed 's/plane/plane\n/g' | awk -F 'topology/' '{print $2}'
Interfaccia scartata:
Errori FCS (errori CRC non-stallati)
APIC#moquery -c rmonDot3Stats -f 'rmon.Dot3Stats.fCSErrors>="1"' | egrep "dn|fCSErrors"
FCS + errori CRC stomped
APIC#moquery -c rmonEtherStats -f 'rmon.EtherStats.cRCAlignErrors>="1"' | egrep "dn|cRCAlignErrors"
Perdite buffer di output
APIC#moquery -c rmonEgrCounters -f 'rmon.EgrCounters.bufferdroppkts>="1"' | egrep "dn|bufferdroppkts"
output errors
APIC#moquery -c rmonIfOut -f 'rmon.IfOut.errors>="1"' | egrep "dn|errors"
Cancella tutti i contatori di interfaccia
Comando per ottenere un elenco di nodi dell'infrastruttura
APIC# acidiag fnvread | egrep " active" | egrep "leaf|spine" | awk '{print $1}' | sed -e 'H;${x;s/\n/,/g;s/^,//;p;};d'
101,102,103,204,205,206,301,1001,1002,2001,2002
Comando per cancellare i contatori per l'elenco precedente
APIC# fabric 101,102,103,204,205,206,301,1001,1002,2001,2002 clear counters interface all
Problemi della sessione BGP:
Per controllare se vi sono sessioni BGP che presentano problemi nell'alloggiamento della struttura
APIC#moquery -c bgpPeerEntry -f 'bgp.PeerEntry.operSt!="established" and bgp.PeerEntry.dn*"overlay-1"' | egrep "dn|operSt" | tr -d "\n" | sed "s/dn/\ndn/g;s/operSt/\t-\toperSt/g"
Per controllare una sessione BGP
APIC#moquery -c bgpPeerEntry -f 'bgp.PeerEntry.operSt!="established" | egrep "dn|operSt" | tr -d "\n" | sed "s/dn/\ndn/g;s/operSt/\t-\toperSt/g"
Problemi della sessione OSPF:
Identificare le sessioni che non sono in stato completo.
APIC#moquery -c ospfAdjEp -f 'ospf.AdjEp.operSt!="full"' | egrep "dn|peerIp" | tr -d '\n' | sed "s/dn : topology\//\nNode : /g;s/peerIp/\tpeerIp/g;s/ //g" | sed "s/\/sys.*dom-/ VRF: /g;s/\/if-\[/ Interface : /g;s/\]\/adj-/ Adj: /g"
Identificare le sessioni che si alternano continuamente e ordinare le informazioni in base al conteggio più alto:
APIC#moquery -c ospfAdjStats -f 'ospf.AdjStats.stChgCnt!="0"' | egrep "dn|stChgCnt" | tr -d "\n" | tr -d " " | sed "s/dn:topology\//\nNode: /g;s/\/adjstatsstChgCnt:/\tADJ changes: /g;s/\/if-\[/ Interface: /g;s/\]\/adj-/ Adj /g" | sed "s/\/sys.*dom-/ VRF: /g" | sort -nrk 11
Pacchetti primari inviati alla CPU
Tener conto: questo comando esegue il debug di 500 pacchetti. Per un importo inferiore, modificare il numero dopo -c.
lEAF#tcpdump -i kpm_inb -c 500 > /tmp/cpu-dp.txt
LEAF#cat /tmp/cpu-dp.txt | grep IP | awk '{print $3 , $4 , $5}' | grep -v $HOSTNAME | awk -F ':' '{print $1}' | sort | uniq -c | sort -nrk 1
Diretto senza creare un nuovo file:
LEAF#tcpdump -i kpm_inb -c 500 | grep IP | awk '{print $3 , $4 , $5}' | grep -v $HOSTNAME | awk -F ':' '{print $1}' | sort | uniq -c | sort -nrk 1
Controllare l'infrastruttura dall'apic in cui viene distribuita una relazione contrattuale specifica
APIC#moquery -c actrlRule -f 'actrl.Rule.sPcTag=="32783" and actrl.Rule.dPcTag=="46" and actrl.Rule.scopeId=="2818048"'
Controllare se un Encrypt è già stato distribuito e ottenere l'epg corrispondente
APIC#moquery -c l2CktEp -f 'l2.CktEp.encap=="vlan-3018"'
Utilizzo memoria di tutti i nodi nella struttura:
APIC#bash
APIC# clear ; echo -e "Node ID\t\tFree Memory\tUsed Memory" ; moquery -c procSysMemHist15min -f 'proc.SysMemHist15min.index=="1"' | grep dn | awk -F " " '{print $3}' | xargs -n 1 -I {} sh -c 'freeAvg=`moquery -d {} | grep freeAvg | sed -E -e "s/[[:blank:]]+/ /g" | cut -d " " -f3` ; usedAvg=`moquery -d {} | grep usedAvg | sed -E -e "s/[[:blank:]]+/ /g" | cut -d " " -f3` ; totalAvg=`moquery -d {} | grep totalAvg | sed -E -e "s/[[:blank:]]+/ /g" | cut -d " " -f3` ; node=`echo {} | cut -d "/" -f3` ; freeAdj=$(( freeAvg * 100 )) ; usedAdj=$(( usedAvg * 100 )) ; percFree=$(( freeAdj / totalAvg )) ; percUtil=$(( usedAdj / totalAvg )) ; echo -e "$node\tFree% : $percFree\tUsed% : $percUtil"'
Verificare le cadute sullo stack (i pacchetti di eccezione vengono puntati)
Esaminate le perdite di TX. Utilizzare il comando sort -nk 6 -r :
APIC# cat istack_debug | egrep "Protocol:|x_pkts_dropped" | tr -d "\n" | sed "s/Protocol/\nProtocol/g" | sort -nk 6 -r | more
Convalida contratto
Esamina tutte le relazioni per un contratto specifico. Utilizzare lo script che sostituisce il nome del contratto e del tenant:
APIC# CONTRACT='brc-<contract-name>'
APIC# TN='<tenant>'
#CHECK CONSUMERS
#To get the count of epgs consuming a contract (excluding vzany consumer):
APIC#icurl -g 'http://localhost:7777/api/node/mo/uni/tn-'$TN'/'$CONTRACT'.json?query-target=subtree&target-subtree-class=vzRtCons,vzConsDef&rsp-subtree-include=count&query-target-filter=or(eq(vzRtCons.tCl,"fvAEPg"),eq(vzRtCons.tCl,"l2extInstP"),eq(vzRtCons.tCl,"l3extInstP"),wcard(vzConsDef.dn,"uni/tn-'.*'/inherited-\[uni/tn-"))'
#To list all epg objects consuming a contract (excluding vzany consumers):
APIC#icurl -g 'http://localhost:7777/api/node/mo/uni/tn-'$TN'/'$CONTRACT'.json?query-target=subtree&target-subtree-class=vzRtCons,vzConsDef&query-target-filter=or(eq(vzRtCons.tCl,"fvAEPg"),eq(vzRtCons.tCl,"l2extInstP"),eq(vzRtCons.tCl,"l3extInstP"),wcard(vzConsDef.dn,"uni/tn-'.*'/inherited-\[uni/tn-"))' | python -m json.tool
#To get the count of vzanys consuming a contract:
APIC#icurl 'http://localhost:7777/api/node/mo/uni/tn-'$TN'/'$CONTRACT'.json?query-target=children&target-subtree-class=vzRtAnyToCons&rsp-subtree-include=count'
#To list all vzany objects consuming a contract:
APIC#icurl 'http://localhost:7777/api/node/mo/uni/tn-'$TN'/'$CONTRACT'.json?query-target=children&target-subtree-class=vzRtAnyToCons' | python -m json.tool
#CHECK PROVIDERS
#To get the count of epgs providing a contract (excluding vzany consumer):
APIC#icurl -g 'http://localhost:7777/api/node/mo/uni/tn-'$TN'/'$CONTRACT'.json?query-target=subtree&target-subtree-class=vzRtProv,vzProvDef&rsp-subtree-include=count&query-target-filter=or(eq(vzRtProv.tCl,"fvAEPg"),eq(vzRtProv.tCl,"l2extInstP"),eq(vzRtProv.tCl,"l3extInstP"),wcard(vzProvDef.dn,"uni/tn-'.*'/inherited-\[uni/tn-"))'
#To list all epg objects providing a contract (excluding vzany consumers):
APIC#icurl -g 'http://localhost:7777/api/node/mo/uni/tn-'$TN'/'$CONTRACT'.json?query-target=subtree&target-subtree-class=vzRtProv,vzProvDef&query-target-filter=or(eq(vzRtProv.tCl,"fvAEPg"),eq(vzRtProv.tCl,"l2extInstP"),eq(vzRtProv.tCl,"l3extInstP"),wcard(vzProvDef.dn,"uni/tn-'.*'/inherited-\[uni/tn-"))' | python -m json.tool
#To get the count of vzanys providing a contract:
APIC#icurl 'http://localhost:7777/api/node/mo/uni/tn-'$TN'/'$CONTRACT'.json?query-target=children&target-subtree-class=vzRtAnyToProv&rsp-subtree-include=count'
#To list all vzany objects providing a contract:
APIC#icurl 'http://localhost:7777/api/node/mo/uni/tn-'$TN'/'$CONTRACT'.json?query-target=children&target-subtree-class=vzRtAnyToProv' | python -m json.tool