Поиск по этому блогу

26.09.2017

Мониторинг CBQOS

Предварительно требуется включить хранение индексов в nvram на случай перезагрузки оборудования. В целом, это очень неудобно, т.к. при периодическом опросе таблицы будут выдаваться данные по удаленным интерфейсам, классам. Чем больше изменений, тем больше бесполезных данных.
snmp-server ifindex persist
snmp mib persist cbqos
Классы на оборудовании следует описывать одинаково и понятно. Позже будет ясно почему. Со временем у меня появилась деформация указывать в классе "match ip dscp" вместо "match dscp", т.к. в каком-то IOS была ошибка и маркированный трафик в класс без "ip" не попадал. Хотя по документации такое написание предназначено для ipv4 и для ipv6.
class-map match-all VOICE
 match ip dscp ef
class-map match-all ROUTING
 match dscp cs6
class-map match-all SIGNALING
 match ip dscp cs3
Политика чаще всего применяется на подинтерфейсах. В таких случаях их надо минимум две:
  • та, в которой ограничивается полоса в class-default. Она же применяется на подинтерфейс;
  • та, в которой описываются классы: голос, видео и прочее.
policy-map 2M-child
 class VOICE
  priority 384
 class ROUTING
  bandwidth 64
 class SIGNALING
  bandwidth 64
 class class-default
policy-map 2M-parent
 class class-default
  shape average 2000000
  service-policy 2M-child

interface GigabitEthernet0/0.2424
 service-policy output 2M-parent
Получилось в итоге вот что
router#sh policy-map interface GigabitEthernet0/0.2424
 GigabitEthernet0/0.2424 

  Service-policy output: 2M-parent

    Class-map: class-default (match-any)  
      455059675 packets, 384367617899 bytes
      5 minute offered rate 181000 bps, drop rate 0000 bps
      Match: any 
      Queueing
      queue limit 64 packets
      (queue depth/total drops/no-buffer drops) 0/4571/0
      (pkts output/bytes output) 455052525/384360547838
      shape (average) cir 2000000, bc 8000, be 8000
      target shape rate 2000000

      Service-policy : 2M-child

        queue stats for all priority classes:
          Queueing
          queue limit 64 packets
          (queue depth/total drops/no-buffer drops) 0/0/0
          (pkts output/bytes output) 29106653/6001497128

        Class-map: VOICE (match-all)  
          27335175 packets, 5831100762 bytes
          5 minute offered rate 16000 bps, drop rate 0000 bps
          Match: ip dscp ef (46)
          Priority: 384 kbps, burst bytes 9600, b/w exceed drops: 0
          

        Class-map: ROUTING (match-all)  
          1771995 packets, 170445390 bytes
          5 minute offered rate 0000 bps, drop rate 0000 bps
          Match:  dscp cs6 (48)
          Queueing
          queue limit 64 packets
          (queue depth/total drops/no-buffer drops) 0/0/0
          (pkts output/bytes output) 516/48926
          bandwidth 64 kbps

        Class-map: SIGNALING (match-all)  
          1174 packets, 77300 bytes
          5 minute offered rate 0000 bps, drop rate 0000 bps
          Match: ip dscp cs3 (24)
          Queueing
          queue limit 64 packets
          (queue depth/total drops/no-buffer drops) 0/0/0
          (pkts output/bytes output) 1174/77300
          bandwidth 64 kbps

        Class-map: class-default (match-any)  
          425951331 packets, 378365994447 bytes
          5 minute offered rate 164000 bps, drop rate 0000 bps
          Match: any 
          
          queue limit 64 packets
          (queue depth/total drops/no-buffer drops) 0/4571/0
          (pkts output/bytes output) 425944182/378358924484
Мониторинг счетчиков по протоколу snmp возможен при использовании mib'а CISCO-CLASS-BASED-QOS-MIB. Таблицы cbQosCMStatsTable достаточно, чтобы записать счетчики классов: кол-во переданных байт и пакетов, дропы и т.д. Для периодических опросов мне оказалось проще использовать telegraf, т.к. в таблице два индекса и оба можно использовать в качестве тегов. Конфигурационный файл /etc/telegraf/telegraf.d/router_5m.conf
[[inputs.snmp]]
  interval = "5m"
  agents = [ "router" ]
  version = 2
  community = "public"

  # cisco cbqos
  [[inputs.snmp.table]]
    name ="cbQosCMStatsTable"
    oid = "CISCO-CLASS-BASED-QOS-MIB::cbQosCMStatsTable"

    [[inputs.snmp.table.field]]
      name = "cbQosConfigIndex"
      oid = "CISCO-CLASS-BASED-QOS-MIB::cbQosConfigIndex"
      is_tag = true

    [[inputs.snmp.table.field]]
      name = "cbQosParentObjectsIndex"
      oid = "CISCO-CLASS-BASED-QOS-MIB::cbQosParentObjectsIndex"
      is_tag = true
Вот вывод результата опроса маршрутизатора telegraf'ом
> cbQosCMStatsTable,cbQosConfigIndex=1593,cbQosParentObjectsIndex=2381824,agent_host=router,host=monitoring cbQosCMNoBufDropPkt=0i,cbQosCMFragmentPkt=0i,cbQosCMPrePolicyBitRate=37000i,cbQosCMPostPolicyByte=408927954i,cbQosCMPostPolicyByte64=378366050002i,cbQosCMPostPolicyBitRate=37000i,cbQosCMDropPkt64=4573i,cbQosCMNoBufDropPktOverflow=0i,cbQosCMFragmentPktOverflow=0i,cbQosCMFragmentByteOverflow=0i,cbQosCMPrePolicyByteOverflow=88i,cbQosCMPostPolicyByteOverflow=88i,cbQosCMDropPktOverflow=0i,cbQosCMDropByte64=6884472i,cbQosCMDropBitRate=0i,cbQosCMFragmentByte=0i,cbQosCMPrePolicyPkt64=425960494i,cbQosCMPrePolicyByte=415812426i,cbQosCMDropPkt=4573i,cbQosCMDropByteOverflow=0i,cbQosCMNoBufDropPkt64=0i,cbQosCMPrePolicyPktOverflow=0i,cbQosCMPrePolicyPkt=425960494i,cbQosCMPrePolicyByte64=378372934474i,cbQosCMDropByte=6884472i 1506394289000000000
> cbQosCMStatsTable,cbQosParentObjectsIndex=2381824,agent_host=router,host=monitoring,cbQosConfigIndex=13457793 cbQosCMPostPolicyByte64=88429i,cbQosCMPostPolicyByteOverflow=0i,cbQosCMPrePolicyByte64=88429i,cbQosCMPrePolicyBitRate=0i,cbQosCMPostPolicyByte=88429i,cbQosCMDropPkt=0i,cbQosCMDropByte64=0i,cbQosCMNoBufDropPktOverflow=0i,cbQosCMFragmentPktOverflow=0i,cbQosCMPrePolicyPktOverflow=0i,cbQosCMDropByteOverflow=0i,cbQosCMDropByte=0i,cbQosCMDropBitRate=0i,cbQosCMFragmentPkt=0i,cbQosCMFragmentByteOverflow=0i,cbQosCMPostPolicyBitRate=0i,cbQosCMPrePolicyPkt64=1353i,cbQosCMPrePolicyByteOverflow=0i,cbQosCMPrePolicyByte=88429i,cbQosCMDropPktOverflow=0i,cbQosCMDropPkt64=0i,cbQosCMNoBufDropPkt=0i,cbQosCMNoBufDropPkt64=0i,cbQosCMPrePolicyPkt=1353i,cbQosCMFragmentByte=0i 1506394289000000000
> cbQosCMStatsTable,cbQosConfigIndex=1593,cbQosParentObjectsIndex=530,agent_host=router,host=monitoring cbQosCMPrePolicyPkt=455081630i,cbQosCMPrePolicyBitRate=71000i,cbQosCMPostPolicyByteOverflow=89i,cbQosCMPostPolicyByte=2118327625i,cbQosCMDropPktOverflow=0i,cbQosCMFragmentPkt=0i,cbQosCMPrePolicyPktOverflow=0i,cbQosCMPrePolicyByteOverflow=89i,cbQosCMPrePolicyByte64=384377301441i,cbQosCMPostPolicyByte64=384370416969i,cbQosCMPostPolicyBitRate=71000i,cbQosCMDropPkt64=4573i,cbQosCMDropByteOverflow=0i,cbQosCMDropByte64=6884472i,cbQosCMDropBitRate=0i,cbQosCMFragmentByte=0i,cbQosCMPrePolicyPkt64=455081630i,cbQosCMPrePolicyByte=2125212097i,cbQosCMFragmentByteOverflow=0i,cbQosCMDropPkt=4573i,cbQosCMDropByte=6884472i,cbQosCMNoBufDropPktOverflow=0i,cbQosCMNoBufDropPkt=0i,cbQosCMNoBufDropPkt64=0i,cbQosCMFragmentPktOverflow=0i 1506394289000000000
> cbQosCMStatsTable,cbQosConfigIndex=5232209,cbQosParentObjectsIndex=2381824,agent_host=router,host=monitoring cbQosCMPostPolicyByteOverflow=0i,cbQosCMPostPolicyByte64=170454794i,cbQosCMDropBitRate=0i,cbQosCMNoBufDropPktOverflow=0i,cbQosCMNoBufDropPkt=0i,cbQosCMFragmentPktOverflow=0i,cbQosCMPrePolicyBitRate=0i,cbQosCMPostPolicyByte=170454794i,cbQosCMDropPkt=0i,cbQosCMDropPkt64=0i,cbQosCMDropByteOverflow=0i,cbQosCMNoBufDropPkt64=0i,cbQosCMFragmentByte=0i,cbQosCMPrePolicyPkt64=1772091i,cbQosCMPostPolicyBitRate=0i,cbQosCMDropPktOverflow=0i,cbQosCMDropByte=0i,cbQosCMPrePolicyPktOverflow=0i,cbQosCMPrePolicyByteOverflow=0i,cbQosCMPrePolicyByte=170454794i,cbQosCMPrePolicyByte64=170454794i,cbQosCMDropByte64=0i,cbQosCMFragmentPkt=0i,cbQosCMFragmentByteOverflow=0i,cbQosCMPrePolicyPkt=1772091i 1506394289000000000
> cbQosCMStatsTable,cbQosConfigIndex=15672385,cbQosParentObjectsIndex=2381824,agent_host=router,host=monitoring cbQosCMPostPolicyByteOverflow=1i,cbQosCMNoBufDropPktOverflow=0i,cbQosCMFragmentPktOverflow=0i,cbQosCMFragmentByteOverflow=0i,cbQosCMFragmentByte=0i,cbQosCMPrePolicyPktOverflow=0i,cbQosCMPrePolicyByte64=5833823744i,cbQosCMDropPkt64=0i,cbQosCMDropByte64=0i,cbQosCMNoBufDropPkt64=0i,cbQosCMFragmentPkt=0i,cbQosCMPrePolicyPkt64=27347692i,cbQosCMPrePolicyByteOverflow=1i,cbQosCMPrePolicyByte=1538856448i,cbQosCMDropByteOverflow=0i,cbQosCMDropByte=0i,cbQosCMDropBitRate=0i,cbQosCMNoBufDropPkt=0i,cbQosCMPrePolicyPkt=27347692i,cbQosCMPrePolicyBitRate=24000i,cbQosCMPostPolicyByte=1538856448i,cbQosCMPostPolicyByte64=5833823744i,cbQosCMPostPolicyBitRate=24000i,cbQosCMDropPktOverflow=0i,cbQosCMDropPkt=0i 1506394289000000000
Индекс напрямую связан с именем класса. Так в старых платформах (2800,2900,7200,3750) все class-default имеют индекс 1593. Это дает некоторое преимущество, т.к. можно анализировать определенные метрики без привязки к другим таблицам этого mib'а. Видно, что 4 из 5 записей относятся к cbQosParentObjectsIndex=2381824, т.е. к политике 2M-child, примененной к конкретному интерфейсу. В итоге вся таблица периодически пишется в базу и по выбранным метрикам можно построить графики. Обычно маршрутизаторов и политик на них больше, чем одна. Поэтому необходимо как-то анализировать какие индексы к каким интерфейсам и политикам относятся. Для этого необходимо опросить следующие таблицы и записать результат
#IfName 1.3.6.1.2.1.31.1.1.1.1
#cbQosIfIndex 1.3.6.1.4.1.9.9.166.1.1.1.1.4
#cbQosConfigIndex 1.3.6.1.4.1.9.9.166.1.5.1.1.2
#cbQosObjectsType 1.3.6.1.4.1.9.9.166.1.5.1.1.3
#cbQosParentObjectsIndex 1.3.6.1.4.1.9.9.166.1.5.1.1.4
#cbQosPolicyMapName 1.3.6.1.4.1.9.9.166.1.6.1.1.1
#cbQosCMName 1.3.6.1.4.1.9.9.166.1.7.1.1.1
Немного забегая вперед, выведу данные по индексам с привязкой к интерфейсу и хосту
$ cbqos-show.sh | grep 2424
10.9.999.1|Gi0/0.2424|5232209|ROUTING|2381824|2M-child
10.9.999.1|Gi0/0.2424|1593|class-default|530|2M-parent
10.9.999.1|Gi0/0.2424|13457793|SIGNALING|2381824|2M-child
10.9.999.1|Gi0/0.2424|1593|class-default|2381824|2M-child
10.9.999.1|Gi0/0.2424|15672385|VOICE|2381824|2M-child
Запрос сформирован на данных в таблицах перечисленных ниже. cbQosConfigIndex и cbQosConfigIndex2 - одинаковы, т.к не придумал как иначе мне получить имя политики.
CREATE TABLE Ifname (ip, IfIndex int, IfName);
CREATE TABLE cbQosIfIndex (ip,PolicyIndex int, IfIndex int);
CREATE TABLE cbQosConfigIndex (ip,PolicyIndex int, ObjectsIndex int, ConfigIndex int);
CREATE TABLE cbQosConfigIndex2 (ip,PolicyIndex int, ObjectsIndex int, ConfigIndex int);
CREATE TABLE cbQosParentObjectsIndex (ip,PolicyIndex int, ObjectsIndex int, ParentObjectsIndex int);
CREATE TABLE cbQosPolicyMapName (ip, ConfigIndex int,PolicyMapName);
CREATE TABLE cbQosCMName (ip,ClassIndex int, ClassName);
Запрос с объединением таблиц
sqlite> select cbQosConfigIndex.ip,Ifname.IfName,cbQosConfigIndex.ConfigIndex,cbQosCMName.ClassName,cbQosParentObjectsIndex.ParentObjectsIndex,cbQosPolicyMapName.PolicyMapName from cbQosConfigIndex
   ...> inner join cbQosCMName on cbQosCMName.ip=cbQosConfigIndex.ip and cbQosCMName.ClassIndex=cbQosConfigIndex.ConfigIndex
   ...> inner join cbQosIfIndex on  cbQosIfIndex.ip=cbQosConfigIndex.ip and cbQosIfIndex.PolicyIndex=cbQosConfigIndex.PolicyIndex
   ...> inner join Ifname on Ifname.ip=cbQosConfigIndex.ip and cbQosIfIndex.IfIndex=Ifname.IfIndex
   ...> inner join cbQosParentObjectsIndex on cbQosParentObjectsIndex.ip=cbQosConfigIndex.ip and cbQosConfigIndex.ObjectsIndex=cbQosParentObjectsIndex.ObjectsIndex
   ...> inner join cbQosConfigIndex2 on cbQosConfigIndex.ip=cbQosConfigIndex2.ip and cbQosParentObjectsIndex.ParentObjectsIndex=cbQosConfigIndex2.ObjectsIndex
   ...> inner join cbQosPolicyMapName on cbQosPolicyMapName.ip=cbQosConfigIndex2.ip and cbQosPolicyMapName.ConfigIndex=cbQosConfigIndex2.ConfigIndex
   ...> where Ifname.IfName like '%2424';
10.9.999.1|Gi0/0.2424|5232209|ROUTING|2381824|2M-child
10.9.999.1|Gi0/0.2424|1593|class-default|530|2M-parent
10.9.999.1|Gi0/0.2424|13457793|SIGNALING|2381824|2M-child
10.9.999.1|Gi0/0.2424|1593|class-default|2381824|2M-child
10.9.999.1|Gi0/0.2424|15672385|VOICE|2381824|2M-child

Картинки в графане для примера.