TSDucki kasutamine IP(TS) voogude jälgimiseks

Tänapäeval on näiteks IP(TS) voogude jälgimiseks olemas valmislahendused VB и iQ, on neil küllaltki rikkalik funktsioonide komplekt ja tavaliselt on sellised lahendused suurtel teleteenustega tegelevatel operaatoritel. Selles artiklis kirjeldatakse avatud lähtekoodiga projektil põhinevat lahendust TSDuck, mis on loodud IP(TS) voogude minimaalseks juhtimiseks CC (pidevuse loenduri) loenduri ja bitikiirusega. Võimalik rakendus on pakettide kadumise või kogu voo juhtimine renditud L2 kanali kaudu (mida ei saa normaalselt jälgida näiteks järjekordades olevaid kadude loendureid lugedes).

Väga lühidalt TSDuckist

TSDuck on avatud lähtekoodiga (2-klausliline BSD-litsents) tarkvara (konsooliutiliitide komplekt ja kohandatud utiliitide või pistikprogrammide arendamiseks mõeldud teek) TS-voogude manipuleerimiseks. Sisendina saab töötada IP (multicast/unicast), http, hls, dvb tuuneritega, dektec dvb-asi demodulaatoriga, olemas on sisemine TS-stream generaator ja failidest lugemine. Väljund võib olla faili kirjutamine, IP (multicast/unicast), hls, dektec dvb-asi ja HiDes modulaatorid, mängijad (mplayer, vlc, xine) ja drop. Sisend- ja väljundi vahele saab lisada mitmesuguseid liiklusprotsessoreid, näiteks PID-i ümberjaotamine, skrambleerimine / deskrambleerimine, CC loenduri analüüs, bitikiiruse arvutamine ja muud tüüpilised TS-voogude toimingud.

Selles artiklis kasutatakse sisendina IP-vooge (multicast), protsessoreid bitrate_monitor (nimest selgub, mis see on) ja järjepidevust (CC-loendurite analüüs). Saate hõlpsasti asendada IP multisaate mõne muu sisenditüübiga, mida TSDuck toetab.

On olemas ametlikud ehitused/paketid TSDuck enamiku praeguste operatsioonisüsteemide jaoks. Need pole Debiani jaoks saadaval, kuid meil õnnestus need ilma probleemideta ehitada versioonide debian 8 ja debian 10 alla.

Järgmisena kasutatakse versiooni TSDuck 3.19-1520, OS-ina Linuxit (lahenduse ettevalmistamiseks kasutati debian 10, reaalseks kasutamiseks CentOS 7)

TSDucki ja OS-i ettevalmistamine

Enne reaalsete voogude jälgimist peate veenduma, et TSDuck töötab õigesti ja võrgukaardi või OS-i (pesa) tasemel pole langusi. See on vajalik selleks, et mitte hiljem arvata, kus kukkumised toimusid - võrgus või "serveris". Võrgukaardi taseme langusi saab kontrollida käsuga ethtool -S ethX, häälestamine toimub sama ethtool’iga (tavaliselt tuleb RX puhvrit suurendada (-G) ja vahel ka mõned mahalaadimised (-K) keelata). Üldise soovitusena võib soovitada analüüsitava liikluse vastuvõtmiseks kasutada eraldi porti, kui võimalik, see minimeerib valepositiivseid juhtumeid, mis on seotud sellega, et kukkumine toimus täpselt analüsaatori pordis muu liikluse olemasolu tõttu. Kui see pole võimalik (kasutatakse ühe pordiga miniarvutit/NUC-d), siis on väga soovitav seadistada analüüsitava liikluse prioritiseerimine ülejäänud osas seadmel, millega analüsaator on ühendatud. Virtuaalkeskkondade osas tuleb siin olla ettevaatlik ja osata leida pakettaknad alates füüsilisest pordist ja lõpetades rakendusega virtuaalmasinas.

Voo genereerimine ja vastuvõtmine hosti sees

TSDucki ettevalmistamise esimese sammuna genereerime ja võtame vastu liiklust ühes hostis, kasutades netnsi.

Keskkonna ettevalmistamine:

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

Keskkond on valmis. Käivitame liikluse analüsaatori:

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

kus "-p 1 -t 1" tähendab, et peate arvutama bitikiiruse iga sekund ja kuvama teavet bitikiiruse kohta iga sekund
Käivitame liiklusgeneraatori kiirusega 10Mbps:

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

kus "-p 7 -e" tähendab, et tuleb 7 TS paketti pakkida 1 IP paketti ja teha seda kõvasti (-e), st. alati ootama 7 TS paketti viimasest protsessorist enne IP-paketi saatmist.

Analüsaator hakkab väljastama oodatud teateid:

* 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

Nüüd lisage mõned tilgad:

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

ja ilmuvad sellised teated:

* 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 

mida oodatakse. Keelake paketikadu (ip netns exec P iptables -F) ja proovige suurendada generaatori bitikiirust 100 Mbps-ni. Analüsaator teatab hunniku CC vigu ja 75 asemel umbes 100 Mbps. Üritame välja selgitada, kes on süüdi - generaatoril pole aega või probleem pole selles, selleks hakkame genereerima kindlat arvu paketid (700000 100000 TS paketti = XNUMX XNUMX IP-paketti):

# 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

Nagu näete, genereeriti täpselt 100000 151925460 IP-paketti (151825460-1). Nii et mõelgem välja, mis analüsaatoriga toimub, selleks kontrollime veth0 RX-loenduriga, see on rangelt võrdne vethXNUMX TX-loenduriga, seejärel vaatame, mis juhtub pistikupesa tasemel:

# 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 

Siin näete languste arvu = 24355. TS-pakettides on see 170485 ehk 24.36% 700000-st, seega näeme, et need samad 25% kadunud bitikiirusest on udp-pesas olevad tilgad. UDP-pesa kukkumised tekivad tavaliselt puhvri puudumise tõttu, vaadake vaikepesa puhvri suurust ja pesapuhvri maksimaalset suurust:

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

Seega, kui rakendused ei nõua selgesõnaliselt puhvri suurust, luuakse soklid puhvriga 208 KB, kuid kui nad nõuavad rohkem, ei saa nad ikkagi seda, mida taotleti. Kuna saate IP-sisendi jaoks määrata puhvri suuruse tsp-s (-buffer-size), siis me ei puuduta vaikepesa suurust, vaid määrame ainult maksimaalse pesa puhvri suuruse ja määrame puhvri suuruse selgelt tsp argumentide kaudu:

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

Selle pesapuhvri häälestamise korral on nüüd teatatud bitikiirus umbes 100 Mbps, CC vigu pole.

Vastavalt tsp-rakenduse enda protsessori tarbimisele. Võrreldes ühetuumalise i5-4260U protsessoriga @ 1.40 GHz, vajab 10 Mbps vooanalüüs 3–4% CPU-d, 100 Mbps - 25%, 200 Mbps - 46%. % Packet Loss määramisel protsessori koormus praktiliselt ei suurene (aga võib väheneda).

Tootlikuma riistvara korral oli võimalik ilma probleemideta genereerida ja analüüsida vooge kiirusega üle 1 Gb / s.

Testimine päris võrgukaartidel

Pärast veth-paaril testimist peate võtma kaks hosti või ühe hosti kaks porti, ühendama pordid üksteisega, käivitama ühel generaatori ja teisel analüsaatori. Siin ei olnud üllatusi, aga tegelikult oleneb kõik rauast, mida nõrgem, seda huvitavam siin läheb.

Seiresüsteemi (Zabbix) poolt vastuvõetud andmete kasutamine

tsp-l pole masinloetavat API-d, nagu SNMP vms. CC-sõnumid peavad olema agregeeritud vähemalt 1 sekund (suure pakettkao protsendi korral võib neid olla sadu/tuhandeid/kümneid tuhandeid sekundis, olenevalt bitikiirusest).

Seega, nii teabe salvestamiseks kui ka CC vigade ja bitikiiruse graafikute joonistamiseks ja teatud tüüpi õnnetuste tegemiseks võivad olla järgmised võimalused:

  1. Parsi ja agregeeri (CC järgi) tsp väljund, st. teisendage see soovitud kujule.
  2. Lõpeta tsp ise ja/või protsessori pluginad bitrate_monitor ja continuity, et tulemus oleks antud seiresüsteemile sobival masinloetaval kujul.
  3. Kirjutage oma taotlus tsducki teegi kohale.

Ilmselgelt on valik 1 pingutuse mõttes kõige lihtsam, eriti kui arvestada, et tsduck ise on kirjutatud madalal tasemel (tänapäevaste standardite järgi) keeles (C ++)

Lihtne bash parser+agregaatori prototüüp näitas, et 10Mbps voo ja 50% pakettkao korral (halvimal juhul) kulutas bash protsess 3-4 korda rohkem protsessorit kui tsp protsess ise. See stsenaarium on vastuvõetamatu. Tegelikult tükk sellest prototüübist allpool

Peal nuudlid

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

Lisaks sellele, et see on lubamatult aeglane, pole bashis normaalseid lõime, bashi tööd on eraldiseisvad protsessid ja kõrvalefekti (bitikiirusega sõnumite saamisel, mis tulevad iga sekund) juurde pidin kord sekundis kirjutama puuduvate pakettide väärtuse. Selle tulemusena jäeti bash rahule ja otsustati kirjutada golangi ümbris (parser + agregaator). Sarnase golangi koodi CPU tarbimine on 4-5 korda väiksem kui tsp protsess ise. Ümbrise kiirenemine bashi asendamise tõttu golangiga osutus umbes 16-kordseks ja üldiselt on tulemus vastuvõetav (CPU ülekulu halvimal juhul 25%). Golangi lähtefail asub siin.

Käivitage ümbris

Ümbrise käivitamiseks tehti süsteemi jaoks lihtsaim teenindusmall ( siin). Ümbris ise peaks olema kompileeritud binaarfailiks (go build tsduck-stat.go), mis asub /opt/tsduck-stat/. Eeldatakse, et kasutate golangi monotoonse kella toega (>=1.9).

Teenuse eksemplari loomiseks peate käivitama käsu systemctl enable [meiliga kaitstud]:1234 seejärel käivitage systemctl start [meiliga kaitstud]: 1234.

Avastus Zabbixilt

Selleks, et zabbix saaks jooksvaid teenuseid avastada, seda tehakse rühmaloendi generaator (discovery.sh), Zabbixi avastamiseks vajalikus vormingus eeldatakse, et see asub samas kohas - kaustas /opt/tsduck-stat. Avastamise käivitamiseks zabbix-agendi kaudu peate lisama .conf faili kasutajaparameetri lisamiseks zabbix-agendi konfiguratsioonikataloogi.

Zabbixi mall

Loodud mall (tsduck_stat_template.xml) sisaldab automaattuvastuse reeglit, üksuste prototüüpe, graafikuid ja käivitajaid.

Lühike kontrollnimekiri (noh, mis siis, kui keegi otsustab seda kasutada)

  1. Veenduge, et tsp ei kukuks pakette "ideaalsetes" tingimustes (generaator ja analüsaator on otse ühendatud), kui neid on, vaadake lõiku 2 või selleteemalise artikli teksti.
  2. Muutke häälestamine maksimaalseks pesapuhvriks (net.core.rmem_max=8388608).
  3. Kompileerige fail tsduck-stat.go (mine loo tsduck-stat.go).
  4. Pange teenusemall kausta /lib/systemd/system.
  5. Käivitage teenused süsteemiga systemctl, kontrollige, kas loendurid on hakanud ilmuma (grep "" /dev/shm/tsduck-stat/*). Teenuste arv multisaadete voogude arvu järgi. Siin võib tekkida vajadus luua marsruut multisaadete rühma, võib-olla keelata rp_filter või luua marsruut lähte-ip-le.
  6. Käivitage discovery.sh ja veenduge, et see genereerib json-i.
  7. Lisage zabbix agendi konfiguratsioon, taaskäivitage zabbix agent.
  8. Laadige mall zabbixisse üles, rakendage see jälgitavale hostile ja zabbix-agent on installitud, oodake umbes 5 minutit, vaadake, kas on uusi üksusi, graafikuid ja käivitajaid.

Tulemus

TSDucki kasutamine IP(TS) voogude jälgimiseks

Pakettide kadumise tuvastamise ülesandeks on see peaaegu piisav, vähemalt see on parem kui jälgimata jätmine.

Tõepoolest, videofragmentide liitmisel võivad tekkida CC-kaod (minu teada tehakse Vene Föderatsiooni kohalikes telekeskustes nii, s.t. ilma CC-loendurit ümber arvutamata), seda tuleb meeles pidada. Patenditud lahendused väldivad seda probleemi osaliselt, tuvastades SCTE-35 sildid (kui need on voogeneraatori poolt lisatud).

Transpordikvaliteedi monitooringu osas on puudu jitter monitooringust (IAT). Teleriseadmetel (olgu selleks modulaatorid või lõppseadmed) on sellele parameetrile nõuded ja alati pole võimalik jitpuhvrit lõpmatuseni täis puhuda. Ja värin võib hõljuda, kui transiidi ajal kasutatakse suurte puhvritega seadmeid ja QoS pole konfigureeritud või ei ole sellise reaalajas liikluse edastamiseks piisavalt konfigureeritud.

Allikas: www.habr.com

Lisa kommentaar