A TSDuck használata az IP(TS) folyamok figyelésére

Ma már léteznek kész (védett) megoldások például az IP(TS) áramlások figyelésére VB и iQ, meglehetősen gazdag funkciókészlettel rendelkeznek, és általában a tévészolgáltatásokkal foglalkozó nagy szolgáltatók is hasonló megoldásokkal rendelkeznek. Ez a cikk egy nyílt forráskódú projekten alapuló megoldást ír le TSDuck, amelyet az IP(TS) folyamok minimális vezérlésére terveztek a CC (folytonosságszámláló) számláló és bitsebesség használatával. Egy lehetséges alkalmazás a csomagok elvesztésének vagy a teljes áramlás figyelése egy bérelt L2 csatornán keresztül (amit nem lehet normálisan figyelni, például a várólistákban lévő veszteségszámlálók kiolvasásával).

Nagyon röviden a TSDuck-ról

A TSDuck egy nyílt forráskódú (2-clause BSD licenc) szoftver (konzol segédprogramok készlete és könyvtár a saját segédprogramok vagy bővítmények fejlesztéséhez) a TS adatfolyamok manipulálására. Bemenetként működik IP (multicast/unicast), http, hls, dvb tuner, dektec dvb-asi demodulátor, van belső TS stream generátor és fájlokból olvasás. A kimenet lehet rögzítés fájlba, IP (multicast/unicast), hls, dektec dvb-asi és HiDes modulátorok, lejátszók (mplayer, vlc, xine) és drop. A bemenet és a kimenet között különféle forgalmi processzorokat engedélyezhet, például PID-ek újraleképezését, titkosítást/dekódolást, CC-számlálók elemzését, bitráta kiszámítását és egyéb, a TS streamekre jellemző műveleteket.

Ebben a cikkben IP streameket (multicast) használunk bemenetként, bitrate_monitor processzorokat (a névből kiderül, hogy mi ez) és folytonossági (CC számlálóanalízis) processzorokat. Probléma nélkül lecserélheti az IP multicast másik, a TSDuck által támogatott bemeneti típusra.

Vannak hivatalos építmények/csomagok TSDuck a legtöbb jelenlegi operációs rendszerhez. Debianra nincs, de Debian 8-ra és Debian 10-re gond nélkül sikerült lefordítani őket.

Ezután a TSDuck 3.19-1520-as verzióját használjuk, operációs rendszerként a Linuxot (a megoldás előkészítéséhez a Debian 10-et, a tényleges használathoz a CentOS 7-et használtuk)

TSDuck és OS előkészítése

A valós áramlások figyelése előtt meg kell győződnie arról, hogy a TSDuck megfelelően működik-e, és hogy a hálózati kártya vagy az operációs rendszer (aljzat) szintjén nem történik-e csökkenés. Erre azért van szükség, hogy később ne kelljen kitalálnia, hol történt a visszaesés – a hálózaton vagy „a szerveren belül”. A hálózati kártya szintű leeséseket az ethtool -S ethX paranccsal tudod ellenőrizni, a hangolást ugyanaz az ethtool végzi (általában növelni kell az RX puffert (-G) és néha le kell tiltani néhány offload-ot (-K)). Általános javaslatként célszerű külön portot használni az elemzett forgalom fogadására, ez lehetőség szerint minimalizálja a téves pozitívumot, amely abból adódik, hogy az analizátor porton egyidejűleg más forgalom miatti csökkenés következett be. Ha ez nem lehetséges (egy porttal rendelkező miniszámítógépet/NUC-t használ), akkor nagyon célszerű az elemzett forgalom prioritását a többihez képest konfigurálni azon az eszközön, amelyre az analizátor csatlakozik. Ami a virtuális környezetet illeti, itt óvatosnak kell lennie, és meg kell tudnia találni a csomagledobásokat a fizikai porttól kezdve a virtuális gépen belüli alkalmazásig.

Stream generálása és fogadása a gazdagépen belül

A TSDuck előkészítésének első lépéseként egy gazdagépen belül forgalmat generálunk és fogadunk a netns segítségével.

A környezet előkészítése:

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

A környezet készen áll. Indítsa el a forgalomelemzőt:

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

ahol a "-p 1 -t 1" azt jelenti, hogy másodpercenként ki kell számítania a bitrátát, és másodpercenként meg kell jelenítenie a bitrátát
10 Mbit/s sebességű forgalomgenerátort indítunk:

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

ahol a „-p 7 -e” azt jelenti, hogy 7 TS csomagot kell 1 IP csomagba csomagolni, és ezt keményen (-e) kell megtenni, pl. mindig várjon 7 TS csomagot az utolsó processzortól, mielőtt elküldi az IP-csomag képzését.

Az analizátor elkezdi megjeleníteni a várt üzeneteket:

* 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

Most adjunk hozzá néhány cseppet:

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

és ehhez hasonló üzenetek jelennek meg:

* 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 

ami várható. Letiltjuk a csomagvesztést (ip netns exec P iptables -F), és megpróbáljuk a generátor bitsebességét 100 Mbit/s-ra növelni. Az analizátor egy csomó CC hibát jelez, és 75 helyett körülbelül 100 Mbit/s. Próbáljuk kitalálni, hogy ki a hibás - a generátor nem tart, vagy nincs benne a probléma, ehhez elkezdünk generálni egy fix számú csomag (700000 100000 TS csomag = XNUMX XNUMX IP csomag):

# 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

Mint látható, pontosan 100000 151925460 IP-csomag jött létre (151825460-1). Tehát kitaláljuk, mi történik az analizátorral, ehhez ellenőrizzük a veth0 RX számlálójával, ez szigorúan megegyezik a vethXNUMX TX számlálójával, majd megnézzük, mi történik a socket szintjén:

# 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 

Itt láthatja a cseppek számát = 24355. TS csomagokban ez 170485 vagy 24.36% a 700000 25-ből, tehát azt látjuk, hogy az elveszett bitrátának ugyanaz a XNUMX%-a az UDP socketben. Az UDP socket leesése általában pufferhiány miatt következik be, nézzük meg, mi az alapértelmezett socket pufferméret és a maximális socket pufferméret:

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

Így ha az alkalmazások nem kérik kifejezetten a puffer méretét, akkor a socketek 208 KB-os pufferrel jönnek létre, de ha többet kérnek, akkor sem kapják meg, amit kértek. Mivel a tsp-ben beállíthatja az IP-bemenet pufferméretét (--buffer-size), nem érintjük meg az alapértelmezett socket-méretet, hanem csak a maximális socket-pufferméretet állítjuk be, és a puffer méretét a tsp argumentumokkal kifejezetten megadjuk:

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

A socket puffer ezen hangolásával a jelentett bitsebesség körülbelül 100 Mbps, nincs CC hiba.

Maga a tsp alkalmazás CPU-fogyasztása alapján. Az egymagos i5-4260U 1.40 GHz-es CPU esetében a 10 Mbit/s-os áramlás elemzéséhez a CPU 3-4%-ára lesz szükség, 100 Mbit/s - 25%, 200 Mbit/s - 46%. A % csomagvesztés beállításakor a CPU terhelés gyakorlatilag nem nő (de csökkenhet).

A termelékenyebb hardvereken probléma nélkül lehetett 1 Gb/s-nál nagyobb adatfolyamokat generálni és elemezni.

Tesztelés valódi hálózati kártyákon

A veth páron végzett tesztelés után vegyen két gazdagépet vagy egy gazdagép két portját, kösse össze a portokat egymással, futtassa az egyiken a generátort, a másikon pedig az analizátort. Itt nem volt meglepetés, de igazából minden a hardveren múlik, minél gyengébb, annál érdekesebb lesz itt.

A felügyeleti rendszer (Zabbix) által kapott adatok felhasználása

A tsp nem rendelkezik olyan géppel olvasható API-val, mint az SNMP vagy hasonló. A CC üzeneteket legalább 1 másodpercenként kell összesíteni (nagy arányú csomagvesztés esetén a bitrátától függően több száz/ezer/tízezer is lehet másodpercenként).

Így az információk mentésére és a CC hibákra és a bitrátára vonatkozó grafikonok megrajzolására, valamint bizonyos balesetek további előidézésére a következő lehetőségek állnak rendelkezésre:

  1. Elemezze és összesítse (CC-vel) a tsp kimenetet, azaz. alakítsa át a kívánt formába.
  2. Adja hozzá magát a tsp-t és/vagy a bitrate_monitor és a folytonossági processzor beépülő moduljait, hogy az eredmény a felügyeleti rendszernek megfelelő, géppel olvasható formában kerüljön kiadásra.
  3. Írja be az alkalmazását a tsduck könyvtár tetejére.

Nyilvánvalóan a munkaerőköltség szempontjából az 1. lehetőség a legegyszerűbb, főleg, ha maga a tsduck egy alacsony szintű (modern mércével mérve) nyelven (C++) van írva.

Az elemző + aggregátor egyszerű prototípusa bashban azt mutatta, hogy 10 Mbit/s áramlásnál és 50%-os csomagvesztésnél (legrosszabb esetben) a bash folyamat 3-4-szer több CPU-t fogyaszt, mint maga a tsp folyamat. Ez a forgatókönyv elfogadhatatlan. Valójában ennek a prototípusnak egy darabja lent

Tészta bashán

#!/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

Amellett, hogy ez elfogadhatatlanul lassan működik, a bash-ban nincsenek normális szálak, a bash jobok független folyamatok, és a mellékhatásra (másodpercenként érkező bitsebességű üzenetek fogadásakor) másodpercenként egyszer kellett ráírnom a lostPackets értéket. Ennek eredményeként a bash magára maradt, és úgy döntöttek, hogy egy wrappert (elemző + aggregátor) írnak golang nyelven. A golang hasonló kódjának CPU-fogyasztása 4-5-ször kevesebb, mint maga a tsp folyamat. A wrapper gyorsulása a bash golangra cserélésével körülbelül 16-szoros volt, és összességében az eredmény elfogadható (a CPU többletterhelése a legrosszabb esetben 25%). A golang forrásfájl található itt.

A csomagolóanyag elindítása

A burkoló elindításához egy egyszerű szolgáltatássablon készült a systemd számára (itt). Feltételezzük, hogy maga a wrapper egy bináris fájlba van fordítva (go build tsduck-stat.go), amely az /opt/tsduck-stat/ könyvtárban található. Feltételezhető, hogy golangot használsz, amely támogatja a monoton órát (>=1.9).

Szolgáltatáspéldány létrehozásához futtassa a systemctl enable parancsot [e-mail védett]:1234, majd futtassa a systemctl starttal [e-mail védett]: 1234.

A Zabbix felfedezése

Hogy a zabbix felfedezze a futó szolgáltatásokat, csoportlista generátor (discovery.sh), a Zabbix felfedezéséhez szükséges formátumban feltételezzük, hogy ugyanazon a helyen található - az /opt/tsduck-stat könyvtárban. A felderítés zabbix-agenten keresztüli futtatásához hozzá kell adnia .conf fájl a zabbix-agent konfigurációkkal rendelkező könyvtárba felhasználói paraméter hozzáadásához.

Zabbix sablon

Létrehozva sablon (tsduck_stat_template.xml) tartalmazza az automatikus felfedezési szabályt, az elemet, a grafikont és a trigger prototípusait.

Egy rövid ellenőrző lista (mi van, ha valaki úgy dönt, hogy használja)

  1. Ügyeljen arra, hogy a tsp ne dobjon ki csomagokat „ideális” körülmények között (a generátor és az analizátor közvetlenül csatlakozik), ha vannak cseppek, lásd a 2. pontot vagy az ezzel kapcsolatos cikk szövegét.
  2. Hangolja be a maximális socket puffert (net.core.rmem_max=8388608).
  3. Fordítsa le a tsduck-stat.go fájlt (hajtja a tsduck-stat.go buildet).
  4. Helyezze el a szolgáltatássablont a /lib/systemd/system könyvtárba.
  5. Indítsa el a szolgáltatásokat a systemctl használatával, ellenőrizze, hogy elkezdtek-e megjelenni a számlálók (grep "" /dev/shm/tsduck-stat/*). A szolgáltatások száma a multicast folyamok számával. Itt létre kell hoznia egy útvonalat a csoportos küldési csoporthoz, esetleg le kell tiltania az rp_filtert, vagy létre kell hoznia egy útvonalat a forrás IP-címéhez.
  6. Futtassa a discovery.sh fájlt, és győződjön meg arról, hogy az generálja a json-t.
  7. Adja hozzá a zabbix agent konfigurációt, indítsa újra a zabbix agentet.
  8. Töltsd fel a sablont a zabbix-ra, alkalmazd arra a gazdagépre, amelyen a monitorozás történik és a zabbix-agent telepítve van, várj kb. 5 percet, és nézd meg, hogy megjelennek-e új adatelemek, grafikonok és triggerek.

Eredmény

A TSDuck használata az IP(TS) folyamok figyelésére

A csomagvesztés azonosításának feladatához ez majdnem elég, legalábbis jobb, mint a figyelés hiánya.

Valójában a CC „veszteségei” előfordulhatnak a videórészletek illesztésénél (tudtommal az Orosz Föderáció helyi televíziós központjaiban így készülnek a betétek, vagyis a CC-számláló újraszámítása nélkül), ezt emlékezni kell. A szabadalmaztatott megoldásokban ez a probléma részben megkerülhető az SCTE-35 címkék észlelésével (ha az adatfolyam-generátor hozzáadja azokat).

A szállítási minőség monitorozása szempontjából a jitter monitoring (IAT) nem elegendő, mert A TV-berendezések (akár modulátorok, akár végberendezések) megkövetelik ezt a paramétert, és nem mindig lehetséges a jitbuffer korlátlanul felfújása. És a jitter lebeghet, ha a tranzit nagy pufferrel rendelkező berendezéseket használ, és a QoS nincs konfigurálva, vagy nincs megfelelően konfigurálva az ilyen valós idejű forgalom továbbításához.

Forrás: will.com

Hozzászólás