Uzante TSDuck por Monitori IP(TS) Rojojn

Hodiaŭ, ekzistas pretaj (proprietaj) solvoj por monitorado de IP(TS) riveretoj, ekzemple VB и iQ, ili havas sufiĉe riĉan aron da funkcioj kaj kutime grandaj funkciigistoj traktantaj televidservojn havas tiajn solvojn. Ĉi tiu artikolo priskribas solvon bazitan sur malfermkoda projekto TSDuck, desegnita por minimuma kontrolo de IP (TS) fluoj per CC (kontinueco nombrilo) nombrilo kaj bitrate. Ebla aplikiĝo devas kontroli la perdon de pakaĵetoj aŭ la tutan fluon tra lizita L2-kanalo (kiu ne povas esti monitorita normale, ekzemple, legante perdnombrilojn en atendovicoj).

Tre mallonge pri TSDuck

TSDuck estas malfermfonteca (2-Clause BSD-licenco) programaro (aro de konzolaj utilecoj kaj biblioteko por evoluigi specialadaptitajn ilojn aŭ kromaĵojn) por manipuli TS-riveretojn. Kiel enigo, ĝi povas funkcii kun IP (multicast/unicast), http, hls, dvb-agordiloj, dektec dvb-asi demodulator, ekzistas interna TS-flua generatoro kaj legado de dosieroj. La eligo povas esti skribanta al dosiero, IP (multicast/unicast), hls, dektec dvb-asi kaj HiDes modulatoroj, ludantoj (mplayer, vlc, xine) kaj guto. Diversaj trafikprocesoroj povas esti inkluditaj inter enigo kaj eligo, ekzemple, PID-remapado, miksado/malfrapado, CC-nombrilo analizo, bitrate-kalkulo, kaj aliaj tipaj operacioj por TS-riveretoj.

En ĉi tiu artikolo, IP-fluoj (multicast) estos uzataj kiel enigaĵo, la procesoroj bitrate_monitor (de la nomo estas klare kio ĝi estas) kaj kontinueco (analizo de CC nombriloj) estas uzataj. Vi povas facile anstataŭigi IP-multiron per alia eniga tipo subtenata de TSDuck.

Disponebla oficialaj konstruoj/pakaĵoj TSduck por la plej multaj aktualaj operaciumoj. Ili ne disponeblas por Debian, sed ni sukcesis konstrui ilin sub debian 8 kaj debian 10 senprobleme.

Poste, versio TSDuck 3.19-1520 estas uzata, Linukso estas uzata kiel OS (debian 10 estis uzata por prepari la solvon, CentOS 7 estis uzata por reala uzo)

Preparante TSDuck kaj OS

Antaŭ monitori realajn fluojn, vi devas certigi, ke TSDuck funkcias ĝuste kaj ke ne estas gutoj ĉe la reto-karto aŭ OS (ingo). Ĉi tio estas postulata por ne poste diveni, kie okazis la gutoj - en la reto aŭ "en la servilo". Vi povas kontroli gutojn ĉe la retokarto-nivelo per la komando ethtool -S ethX, agordado estas farita per la sama ethtool (kutime, vi devas pliigi la RX-bufron (-G) kaj foje malŝalti kelkajn elŝutojn (-K)). Kiel ĝenerala rekomendo, oni povas konsili uzi apartan havenon por ricevi la analizitan trafikon, se eble, ĉi tio minimumigas falsajn pozitivojn asociitajn kun la fakto, ke la guto okazis ĝuste sur la analizila haveno pro la ĉeesto de alia trafiko. Se tio ne eblas (mini-komputilo/NUC kun unu haveno estas uzata), tiam estas tre dezirinde agordi la prioritaton de la analizita trafiko rilate al la resto sur la aparato al kiu la analizilo estas konektita. Koncerne virtualajn mediojn, ĉi tie vi devas esti singarda kaj povi trovi pakaĵetojn komencante de fizika haveno kaj finiĝantaj per aplikaĵo ene de virtuala maŝino.

Generacio kaj ricevo de rivereto ene de la gastiganto

Kiel unua paŝo en preparado de TSDuck, ni generos kaj ricevos trafikon ene de ununura gastiganto uzante netns.

Preparado de la medio:

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

La medio estas preta. Ni komencas la trafikan analizilon:

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

kie "-p 1 -t 1" signifas, ke vi devas kalkuli la bitrapidecon ĉiun sekundon kaj montri informojn pri la bitrapideco ĉiun sekundon
Ni startas la trafikan generatoron kun rapido de 10Mbps:

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

kie "-p 7 -e" signifas, ke vi devas paki 7 TS-pakaĵojn en 1 IP-pakaĵon kaj fari ĝin malfacile (-e), t.e. ĉiam atendu 7 TS-pakojn de la lasta procesoro antaŭ ol sendi IP-pakon.

La analizilo komencas eligi la atendatajn mesaĝojn:

* 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

Nun aldonu kelkajn gutojn:

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

kaj mesaĝoj kiel ĉi aperas:

* 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 

kiu estas atendita. Malebligu pakperdon (ip netns exec P iptables -F) kaj provu pliigi la generatoran bitrapidecon al 100Mbps. La analizilo raportas amason da CC-eraroj kaj ĉirkaŭ 75 Mbps anstataŭ 100. Ni provas eltrovi, kiu kulpas - la generatoro ne havas tempon aŭ la problemo ne estas en ĝi, por tio ni komencas generi fiksan nombron da pakoj (700000 TS-pakoj = 100000 IP-pakoj):

# 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

Kiel vi povas vidi, ĝuste 100000 IP-pakoj estis generitaj (151925460-151825460). Do ni eltrovu, kio okazas kun la analizilo, por tio ni kontrolas per la RX-nombrilo sur veth1, ĝi estas strikte egala al la TX-nombrilo sur veth0, tiam ni rigardas kio okazas ĉe la ingo-nivelo:

# 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 

Ĉi tie vi povas vidi la nombron da gutoj = 24355. En TS-pakoj, ĉi tio estas 170485 aŭ 24.36% de 700000, do ni vidas, ke tiuj samaj 25% de la perdita bitrate estas gutoj en la udp-ingo. Gutoj en UDP-bufro kutime okazas pro manko de bufro, rigardu la defaŭltan ingan bufrograndecon kaj la maksimuman ingan bufrograndecon:

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

Tiel, se aplikaĵoj ne eksplicite petas bufrograndecon, ingoj estas kreitaj kun bufro de 208 KB, sed se ili petas pli, ili ankoraŭ ne ricevos tion, kio estis petita. Ĉar vi povas agordi la bufrograndecon en tsp por la IP-enigo (-buffer-size), ni ne tuŝos la defaŭltan ingan grandecon, sed nur starigos la maksimuman bufran grandecon kaj specifos la bufrograndon eksplicite per la tsp-argumentoj:

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

Kun ĉi tiu agordo de la inga bufro, nun la raportita bitrateco estas ĉirkaŭ 100Mbps, ne estas CC-eraroj.

Laŭ la CPU-konsumo de la tsp-aplikaĵo mem. Rilate al unu kerno i5-4260U CPU @ 1.40GHz, 10Mbps flua analizo postulos 3-4% CPU, 100Mbps - 25%, 200Mbps - 46%. Kiam oni fiksas la % Paketperdon, la ŝarĝo sur la CPU preskaŭ ne pliiĝas (sed povas malpliiĝi).

Sur pli produktiva aparataro, eblis generi kaj analizi fluojn de pli ol 1Gb/s sen problemoj.

Testado sur realaj retaj kartoj

Post testado sur veth-paro, vi devas preni du gastigantojn aŭ du havenojn de unu gastiganto, konekti la havenojn unu al la alia, komenci la generatoron sur unu, kaj la analizilon sur la dua. Ĉi tie ne estis surprizoj, sed fakte ĉio dependas de la fero, ju pli malforta, des pli interesa ĝi estos ĉi tie.

Uzante la ricevitajn datumojn de la monitora sistemo (Zabbix)

tsp ne havas ajnan maŝinlegeblan API kiel SNMP aŭ simila. CC-mesaĝoj devas esti kunigitaj dum almenaŭ 1 sekundo (kun alta procento de paka perdo, povas esti centoj/miloj/dekoj da miloj je sekundo, depende de la bitrapideco).

Tiel, por konservi kaj informojn kaj desegni grafikaĵojn por CC-eraroj kaj bitrate kaj fari ian akcidentojn, povas esti la sekvaj opcioj:

  1. Analizu kaj agregu (per CC) la produktadon de tsp, t.e. konverti ĝin al la dezirata formo.
  2. Finu tsp mem kaj/aŭ procesorajn kromaĵojn bitrate_monitor kaj kontinuecon, por ke la rezulto estu donita en maŝinlegebla formo taŭga por la monitora sistemo.
  3. Skribu vian kandidatiĝon sur la tsduck-biblioteko.

Evidente, opcio 1 estas la plej facila laŭ penado, precipe konsiderante, ke tsduck mem estas skribita en malaltnivela (laŭ modernaj normoj) lingvo (C++)

Simpla bash-analizilo+agregator-prototipo montris, ke sur 10Mbps-rivereto kaj 50% paka perdo (plej malbona kazo), la bash-procezo konsumis 3-4 fojojn pli da CPU ol la tsp-procezo mem. Ĉi tiu scenaro estas neakceptebla. Fakte peco de ĉi tiu prototipo sube

Nudeloj sur la supro

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

Krom esti neakcepteble malrapida, ekzistas neniuj normalaj fadenoj en bash, bash-laboroj estas apartaj procezoj kaj mi devis skribi la valoron de missingPackets unufoje sekundon sur la kromefiko (kiam ricevo de bitrate mesaĝoj kiuj venas ĉiun sekundon). Kiel rezulto, bash estis lasita sola kaj estis decidite skribi envolvaĵon (analizanto + agregador) en golang. La CPU-konsumo de simila golangkodo estas 4-5 fojojn malpli ol la tsp-procezo mem. La rapidigo de la envolvaĵo pro la anstataŭigo de bash kun golango rezultis proksimume 16 fojojn kaj ĝenerale la rezulto estas akceptebla (CPU-superkompeto je 25% en la plej malbona kazo). La golang fontdosiero troviĝas tie.

Kuru envolvaĵon

Por komenci la envolvaĵon, la plej simpla serva ŝablono por systemd estis farita (tie). La envolvaĵo mem supozeble estas kompilita en binaran dosieron (iru konstrui tsduck-stat.go) situantan en /opt/tsduck-stat/. Oni supozas, ke vi uzas golangon kun subteno por monotona horloĝo (>=1.9).

Por krei ekzemplon de la servo, vi devas ruli la systemctl enable komandon [retpoŝte protektita]:1234 tiam rulu kun systemctl start [retpoŝte protektita]: 1234.

Malkovro de Zabbix

Por ke zabbix povu malkovri kurantajn servojn, ĝi estas farita gruplistgeneratoro (discovery.sh), en la formato postulata por Zabbix-malkovro, oni supozas, ke ĝi situas en la sama loko - en /opt/tsduck-stat. Por ruli malkovron per zabbix-agent, vi devas aldoni .conf dosiero al la zabbix-agent-agorda dosierujo por aldoni la uzantparametron.

Zabbix ŝablono

Kreita ŝablono (tsduck_stat_template.xml) enhavas la aŭtomalkovran regulon, eronprototipojn, grafikaĵojn kaj ellasilon.

Mallonga kontrolo (nu, kio se iu decidas uzi ĝin)

  1. Certiĝu, ke tsp ne faligas pakojn sub "idealaj" kondiĉoj (generatoro kaj analizilo estas rekte konektitaj), se estas gutoj, vidu paragrafon 2 aŭ la tekston de la artikolo pri ĉi tiu afero.
  2. Faru agordi la maksimuman ingan bufron (net.core.rmem_max=8388608).
  3. Kompilu tsduck-stat.go (iru konstrui tsduck-stat.go).
  4. Metu la servoŝablonon en /lib/systemd/system.
  5. Komencu servojn per systemctl, kontrolu, ke nombriloj komencis aperi (grep "" /dev/shm/tsduck-stat/*). La nombro da servoj laŭ la nombro da multirolantaro-riveretoj. Ĉi tie vi eble bezonos krei itineron al la multirolantaro, eble malŝalti rp_filter aŭ krei itineron al la fonta ip.
  6. Rulu discovery.sh, certigu, ke ĝi generas json.
  7. Aldonu zabbix-agentan agordon, rekomencu zabbix-agenton.
  8. Alŝutu la ŝablonon al zabbix, apliku ĝin al la gastiganto, kiu estas monitorita kaj la zabbix-agento estas instalita, atendu ĉirkaŭ 5 minutojn, vidu ĉu estas novaj eroj, grafikaĵoj kaj ellasiloj.

rezulto

Uzante TSDuck por Monitori IP(TS) Rojojn

Por la tasko detekti pakaĵperdon, ĝi preskaŭ sufiĉas, almenaŭ ĝi estas pli bona ol neniu monitorado.

Efektive, CC "perdoj" povas okazi dum kunfandado de videofragmentoj (laŭ mi scias, jen kiel enmetoj estas faritaj ĉe lokaj televidcentroj en la Rusa Federacio, t.e. sen rekalkuli la CC-nombrilon), tion oni devas memori. Propraj solvoj parte evitas ĉi tiun problemon detektante SCTE-35-etikedojn (se aldonite de la fluogeneratoro).

Koncerne al transportkvalita monitorado, ekzistas manko de jittermonitorado (IAT). Televidekipaĵo (ĉu ĝi estas modulatoroj aŭ finaj aparatoj) havas postulojn por ĉi tiu parametro kaj ne ĉiam estas eble ŝveligi la jitbuffer al senfineco. Kaj tremo povas flosi kiam ekipaĵo kun grandaj bufroj estas uzata en trafiko kaj QoS ne estas agordita aŭ ne sufiĉe bone agordita por transdoni tian realtempan trafikon.

fonto: www.habr.com

Aldoni komenton