Používanie TSDuck na monitorovanie tokov IP (TS).

Dnes už existujú hotové (proprietárne) riešenia napríklad na monitorovanie IP(TS) tokov VB и iQ, majú pomerne bohatú sadu funkcií a podobné riešenia majú zvyčajne aj veľkí operátori zaoberajúci sa TV službami. Tento článok popisuje riešenie založené na projekte s otvoreným zdrojovým kódom TSDuck, určený na minimálne riadenie tokov IP(TS) pomocou počítadla CC (počítadlo kontinuity) a bitovej rýchlosti. Možnou aplikáciou je sledovanie straty paketov alebo celého toku prenajatým kanálom L2 (ktorý sa nedá normálne monitorovať napr. čítaním počítadiel strát vo frontoch).

Veľmi stručne o TSDuck

TSDuck je softvér s otvoreným zdrojovým kódom (2-Clause BSD licencia) (súprava konzolových utilít a knižnica na vývoj vlastných utilít alebo doplnkov) na manipuláciu s TS streammi. Ako vstup vie pracovať s IP (multicast/unicast), http, hls, dvb tunermi, demodulátorom dektec dvb-asi, nechýba interný generátor TS streamu a čítanie zo súborov. Výstupom môže byť nahrávanie do súboru, IP (multicast/unicast), hls, dektec dvb-asi a HiDes modulátory, prehrávače (mplayer, vlc, xine) a drop. Medzi vstupom a výstupom môžete povoliť rôzne prevádzkové procesory, napríklad premapovanie PID, skramblovanie/dekódovanie, analýzu počítadiel CC, výpočet bitovej rýchlosti a ďalšie operácie typické pre TS streamy.

V tomto článku budú ako vstup použité toky IP (multicast), procesory bitrate_monitor (z názvu je jasné, o čo ide) a procesory kontinuity (analýza počítadiel CC). Bez problémov môžete IP multicast nahradiť iným typom vstupu podporovaným TSDuck.

Tam sú oficiálne zostavy/balíky TSDuck pre väčšinu aktuálnych OS. Pre Debian žiadne neexistujú, no podarilo sa nám ich bez problémov skompilovať pre Debian 8 a Debian 10.

Ďalej sa používa TSDuck verzia 3.19-1520, ako OS je použitý Linux (na prípravu riešenia bol použitý debian 10, na skutočné použitie CentOS 7)

Príprava TSDuck a OS

Pred monitorovaním skutočných tokov sa musíte uistiť, že TSDuck funguje správne a že nedochádza k poklesom na úrovni sieťovej karty alebo OS (zásuvky). Je to potrebné, aby ste neskôr nemuseli hádať, kde došlo k poklesu - v sieti alebo „vo vnútri servera“. Prepady na úrovni sieťovej karty môžete skontrolovať príkazom ethtool -S ethX, ladenie vykonáva rovnaký ethtool (zvyčajne musíte zvýšiť vyrovnávaciu pamäť RX (-G) a niekedy zakázať niektoré zníženia zaťaženia (-K)). Ako všeobecné odporúčanie sa odporúča použiť samostatný port na príjem analyzovanej prevádzky, ak je to možné, minimalizuje to falošné poplachy v dôsledku skutočnosti, že pokles nastal súčasne na porte analyzátora v dôsledku prítomnosti inej prevádzky. Ak to nie je možné (používate minipočítač/NUC s jedným portom), potom je veľmi vhodné nakonfigurovať prioritu analyzovanej prevádzky vo vzťahu k zvyšku na zariadení, ku ktorému je analyzátor pripojený. Čo sa týka virtuálnych prostredí, tu musíte byť opatrní a byť schopní nájsť zanechanie paketov počnúc fyzickým portom a končiac aplikáciou vo virtuálnom stroji.

Generovanie a prijímanie streamu v rámci hostiteľa

Ako prvý krok pri príprave TSDuck budeme generovať a prijímať prevádzku v rámci jedného hostiteľa pomocou netns.

Príprava prostredia:

ip netns add P #создаём netns P, в нём будет происходить анализ трафика
ip link add type veth #создаём veth-пару - veth0 оставляем в netns по умолчанию (в этот интерфейс будет генерироваться трафик)
ip link set dev veth1 netns P #veth1 - помещаем в netns P (на этом интерфейсе будет приём трафика)
ip netns exec P ifconfig veth1 192.0.2.1/30 up #поднимаем IP на veth1, не имеет значения какой именно
ip netns exec P ip ro add default via 192.0.2.2 #настраиваем маршрут по умолчанию внутри nents P
sysctl net.ipv6.conf.veth0.disable_ipv6=1 #отключаем IPv6 на veth0 - это делается для того, чтобы в счётчик TX не попадал посторонний мусор
ifconfig veth0 up #поднимаем интерфейс veth0
ip route add 239.0.0.1 dev veth0 #создаём маршрут, чтобы ОС направляла трафик к 239.0.0.1 в сторону veth0

Prostredie je pripravené. Spustite analyzátor návštevnosti:

ip netns exec P tsp --realtime -t 
 -I ip 239.0.0.1:1234 
 -P continuity 
 -P bitrate_monitor -p 1 -t 1 
 -O drop

kde „-p 1 -t 1“ znamená, že musíte každú sekundu vypočítať bitovú rýchlosť a každú sekundu zobraziť informácie o bitovej rýchlosti
Spúšťame generátor prevádzky s rýchlosťou 10 Mbit/s:

tsp -I craft 
 -P regulate -b 10000000 
 -O ip -p 7 -e --local-port 6000 239.0.0.1:1234

kde “-p 7 -e” znamená, že potrebujete zbaliť 7 TS paketov do 1 IP paketu a urobiť to tvrdo (-e), t.j. vždy počkajte na 7 TS paketov od posledného procesora pred odoslaním vytvorenia IP paketu.

Analyzátor začne zobrazovať očakávané správy:

* 2020/01/03 14:55:44 - bitrate_monitor: 2020/01/03 14:55:44, TS bitrate: 9,970,016 bits/s
* 2020/01/03 14:55:45 - bitrate_monitor: 2020/01/03 14:55:45, TS bitrate: 10,022,656 bits/s
* 2020/01/03 14:55:46 - bitrate_monitor: 2020/01/03 14:55:46, TS bitrate: 9,980,544 bits/s

Teraz pridáme niekoľko kvapiek:

ip netns exec P iptables -I INPUT -d 239.0.0.1 -m statistic --mode random --probability 0.001 -j DROP

a objavia sa správy ako toto:

* 2020/01/03 14:57:11 - continuity: packet index: 80,745, PID: 0x0000, missing 7 packets
* 2020/01/03 14:57:11 - continuity: packet index: 83,342, PID: 0x0000, missing 7 packets 

čo sa očakáva. Zakážeme stratu paketov (ip netns exec P iptables -F) a pokúsime sa zvýšiť bitrate generátora na 100 Mbit/s. Analyzátor hlási veľa chýb CC a asi 75 Mbit/s namiesto 100. Snažíme sa zistiť, kto je na vine – generátor nestíha alebo problém nie je v ňom, aby sme to urobili, začneme generovať pevný počet paketov (700000 100000 paketov TS = XNUMX XNUMX paketov IP):

# ifconfig veth0 | grep TX
       TX packets 151825460  bytes 205725459268 (191.5 GiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
# tsp -I craft -c 700000 -P regulate -b 100000000 -P count -O ip -p 7 -e --local-port 6000 239.0.0.1:1234
* count: PID    0 (0x0000):    700,000 packets
# ifconfig veth0 | grep TX
        TX packets 151925460  bytes 205861259268 (191.7 GiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

Ako vidíte, vygenerovalo sa presne 100000 151925460 IP paketov (151825460-1). Takže zistíme, čo sa deje s analyzátorom, skontrolujeme to pomocou počítadla RX na veth0, presne sa rovná počítadlu TX na vethXNUMX, potom sa pozrieme na to, čo sa deje na úrovni zásuvky:

# ip netns exec P cat /proc/net/udp                                                                                                           
  sl  local_address rem_address   st tx_queue rx_queue tr tm->when retrnsmt   uid  timeout inode ref pointer drops             
  133: 010000EF:04D2 00000000:0000 07 00000000:00000000 00:00000000 00000000     0        0 72338 2 00000000e0a441df 24355 

Tu vidíte počet poklesov = 24355. V paketoch TS je to 170485 alebo 24.36 % zo 700000 25, takže vidíme, že rovnakých XNUMX % stratenej bitovej rýchlosti sú poklesy v UDP sockete. Poklesy na sokete UDP sa zvyčajne vyskytujú v dôsledku nedostatku vyrovnávacej pamäte, pozrime sa, aká je predvolená veľkosť vyrovnávacej pamäte soketu a maximálna veľkosť vyrovnávacej pamäte soketu:

# sysctl net.core.rmem_default
net.core.rmem_default = 212992
# sysctl net.core.rmem_max
net.core.rmem_max = 212992

Ak teda aplikácie explicitne nepožadujú veľkosť vyrovnávacej pamäte, sú vytvorené sokety s 208 KB vyrovnávacou pamäťou, ale ak požadujú viac, stále nedostanú to, čo požadovali. Keďže v tsp môžete nastaviť veľkosť vyrovnávacej pamäte pre vstup IP (--buffer-size), nedotkneme sa predvolenej veľkosti soketu, ale nastavíme iba maximálnu veľkosť vyrovnávacej pamäte soketu a explicitne špecifikujeme veľkosť vyrovnávacej pamäte prostredníctvom argumentov tsp:

sysctl net.core.rmem_max=8388608
ip netns exec P tsp --realtime -t -I ip 239.0.0.1:1234 -b 8388608 -P continuity -P bitrate_monitor -p 1 -t 1 -O drop

S týmto vyladením vyrovnávacej pamäte soketu je teraz hlásená bitová rýchlosť približne 100 Mbps, nevyskytujú sa žiadne chyby CC.

Na základe spotreby procesora samotnou aplikáciou tsp. Čo sa týka jedného jadrového CPU i5-4260U @ 1.40 GHz, na analýzu toku 10 Mbit/s budú potrebné 3 – 4 % CPU, 100 Mbit/s – 25 %, 200 Mbit/s – 46 %. Pri nastavení % straty paketov sa zaťaženie CPU prakticky nezvýši (ale môže sa znížiť).

Na produktívnejšom hardvéri bolo možné bez problémov generovať a analyzovať streamy nad 1Gb/s.

Testovanie na skutočných sieťových kartách

Po testovaní na páre veth musíte vziať dvoch hostiteľov alebo dva porty jedného hostiteľa, navzájom ich spojiť, spustiť generátor na jednom a analyzátor na druhom. Tu sa žiadne prekvapenie nekonalo, no v podstate všetko závisí od hardvéru, čím je slabší, tým to tu bude zaujímavejšie.

Používanie prijatých údajov monitorovacím systémom (Zabbix)

tsp nemá žiadne strojovo čitateľné API, ako je SNMP alebo podobné. Správy CC je potrebné agregovať aspoň 1 sekundu naraz (pri vysokom percente straty paketov to môžu byť stovky/tisíce/desaťtisíce za sekundu, v závislosti od bitovej rýchlosti).

Aby sa teda ušetrili informácie a nakreslili grafy chýb CC a bitovej rýchlosti a aby sa ďalej robili nejaké nehody, môžu existovať nasledujúce možnosti:

  1. Analyzujte a agregujte (podľa CC) výstup tsp, t.j. transformovať do požadovanej podoby.
  2. Pridajte samotný tsp a/alebo zásuvné moduly bitrate_monitor a procesora kontinuity, aby bol výsledok výstup v strojovo čitateľnej forme vhodnej pre monitorovací systém.
  3. Napíšte svoju aplikáciu na vrch knižnice tsduck.

Je zrejmé, že pokiaľ ide o náklady na prácu, možnosť 1 je najjednoduchšia, najmä ak vezmeme do úvahy, že samotný tsduck je napísaný v jazyku nízkej úrovne (podľa moderných štandardov) (C++)

Jednoduchý prototyp parseru + agregátora v bash ukázal, že pri toku 10 Mbit/s a 50% strate paketov (najhorší prípad) spotreboval bash proces 3-4 krát viac CPU ako samotný tsp proces. Tento scenár je neprijateľný. V skutočnosti je časť tohto prototypu nižšie

Rezance na bashe

#!/usr/bin/env bash

missingPackets=0
ccErrorSeconds=0
regexMissPackets='^* (.+) - continuity:.*missing ([0-9]+) packets$'
missingPacketsTime=""

ip netns exec P tsp --realtime -t -I ip -b 8388608 "239.0.0.1:1234" -O drop -P bitrate_monitor -p 1 -t 1  -P continuity 2>&1 | 
while read i
do
    #line example:* 2019/12/28 23:41:14 - continuity: packet index: 6,078, PID: 0x0100, missing 5 packets
    #line example 2: * 2019/12/28 23:55:11 - bitrate_monitor: 2019/12/28 23:55:11, TS bitrate: 4,272,864 bits/s
    if [[ "$i" == *continuity:* ]] 
    then
        if [[ "$i" =~ $regexMissPackets ]]
        then
            missingPacketsTimeNew="${BASH_REMATCH[1]}" #timestamp (seconds)
            if [[ "$missingPacketsTime" != "$missingPacketsTimeNew" ]] #new second with CC error
            then
                ((ccErrorSeconds += 1))
            fi
            missingPacketsTime=$missingPacketsTimeNew
            packets=${BASH_REMATCH[2]} #TS missing packets
            ((missingPackets += packets))
        fi
    elif [[ "$i" == *bitrate_monitor:* ]]
    then
        : #...
    fi
done

Okrem toho, že to funguje neprijateľne pomaly, v bash nie sú žiadne normálne vlákna, bashové úlohy sú nezávislé procesy a vedľajším efektom (pri prijímaní správ s bitovou rýchlosťou, ktoré prichádzajú každú sekundu) som musel raz za sekundu napísať hodnotu missingPackets. Výsledkom bolo, že bash zostal sám a bolo rozhodnuté napísať obal (analyzátor + agregátor) v golangu. Spotreba CPU podobného kódu v golang je 4-5 krát menšia ako samotný proces tsp. Zrýchlenie wrapperu nahradením bash golangom bolo približne 16-násobné a celkovo je výsledok prijateľný (režie CPU o 25% v najhoršom prípade). Nachádza sa zdrojový súbor golang tu.

Spustenie obalu

Na spustenie obalu bola vytvorená jednoduchá šablóna služby pre systemd (tu). Predpokladá sa, že samotný obal je skompilovaný do binárneho súboru (go build tsduck-stat.go), ktorý sa nachádza v /opt/tsduck-stat/. Predpokladá sa, že golang sa používa s podporou monotónnych hodín (>=1.9).

Ak chcete vytvoriť inštanciu služby, musíte spustiť príkaz systemctl enable [chránené e-mailom]:1234, potom spustite so štartom systemctl [chránené e-mailom]: 1234.

Objav zo Zabbixu

Aby zabbix mohol objaviť spustené služby, generátor skupinových zoznamov (discovery.sh), vo formáte požadovanom na vyhľadávanie Zabbix, predpokladá sa, že sa nachádza na rovnakom mieste – v /opt/tsduck-stat. Ak chcete spustiť vyhľadávanie prostredníctvom zabbix-agenta, musíte pridať súbor .conf do adresára s konfiguráciami zabbix-agenta, aby ste pridali užívateľský parameter.

Šablóna Zabbix

Vytvorená šablóna (tsduck_stat_template.xml) obsahuje prototypy pravidla autodiscovery, prvku, grafu a spúšťača.

Krátky kontrolný zoznam (čo ak sa ho niekto rozhodne použiť)

  1. Dbajte na to, aby tsp nezahadzoval pakety za „ideálnych“ podmienok (generátor a analyzátor sú pripojené priamo), ak dôjde k poklesu, pozri bod 2 alebo text článku na túto tému.
  2. Vykonajte ladenie maximálnej vyrovnávacej pamäte soketu (net.core.rmem_max=8388608).
  3. Kompilujte tsduck-stat.go (prejdite na zostavenie tsduck-stat.go).
  4. Umiestnite šablónu služby do /lib/systemd/system.
  5. Spustite služby pomocou systemctl, skontrolujte, či sa začali objavovať počítadlá (grep "" /dev/shm/tsduck-stat/*). Počet služieb podľa počtu tokov multicast. Tu možno budete musieť vytvoriť trasu do skupiny multicast, možno vypnúť rp_filter alebo vytvoriť trasu k zdrojovej IP.
  6. Spustite discovery.sh a uistite sa, že generuje json.
  7. Umiestnite konfiguráciu agenta zabbix, reštartujte agenta zabbix.
  8. Nahrajte šablónu na zabbix, aplikujte ju na hostiteľa, na ktorom sa vykonáva monitoring a je nainštalovaný zabbix-agent, počkajte asi 5 minút, kým sa objavia nové dátové prvky, grafy a spúšťače.

Výsledok

Používanie TSDuck na monitorovanie tokov IP (TS).

Pre úlohu identifikácie straty paketov to takmer stačí, prinajmenšom je to lepšie ako žiadne monitorovanie.

V skutočnosti môže dôjsť k „stratám“ CC pri spájaní fragmentov videa (pokiaľ viem, takto sa vložky vyrábajú v miestnych televíznych centrách v Ruskej federácii, t. j. bez prepočítania počítadla CC), na to treba pamätať. V proprietárnych riešeniach sa tento problém čiastočne obchádza detekciou značiek SCTE-35 (ak ich pridáva generátor prúdu).

Z hľadiska monitorovania kvality dopravy nestačí sledovanie jitteru (IAT), pretože TV zariadenia (či už modulátory alebo koncové zariadenia) majú požiadavky na tento parameter a nie vždy je možné nafukovať jitbuffer donekonečna. A jitter môže plávať, keď tranzit používa zariadenie s veľkými vyrovnávacími pamäťami a QoS nie je nakonfigurované alebo nie je dostatočne dobre nakonfigurované na prenos takejto prevádzky v reálnom čase.

Zdroj: hab.com

Pridať komentár