Qrator-filtrering nettverkskonfigurasjon styringssystem

Qrator-filtrering nettverkskonfigurasjon styringssystem

TL; DR: Beskrivelse av klient-server-arkitekturen til vårt interne nettverkskonfigurasjonsadministrasjonssystem, QControl. Den er basert på en to-lags transportprotokoll som fungerer med gzip-pakkede meldinger uten dekompresjon mellom endepunkter. Distribuerte rutere og endepunkter mottar konfigurasjonsoppdateringer, og selve protokollen tillater installasjon av lokaliserte mellomreléer. Systemet er bygget på prinsippet differensiell backup ("nylig-stabil", forklart nedenfor) og bruker JMESpath-spørringsspråket sammen med Jinja-malmotoren for å gjengi konfigurasjonsfiler.

Qrator Labs driver et globalt distribuert angrepsreduserende nettverk. Nettverket vårt opererer etter anycast-prinsippet, og undernett annonseres via BGP. Som et BGP anycast-nettverk som er fysisk lokalisert i flere regioner på jorden, kan vi behandle og filtrere illegitim trafikk nærmere kjernen av Internett - Tier-1-operatører.

På den annen side er det ikke lett å være et geografisk distribuert nettverk. Kommunikasjon mellom nettverkspunkter er avgjørende for at sikkerhetstjenesteleverandøren skal ha en konsistent konfigurasjon av alle nettverksnoder, og oppdatere dem i tide. Derfor, for å kunne tilby høyest mulig nivå av kjernetjenester til forbrukeren, trengte vi å finne en måte å pålitelig synkronisere konfigurasjonsdata på tvers av kontinenter.

I begynnelsen var Ordet. Det ble raskt en kommunikasjonsprotokoll som trengte en oppdatering.


Hjørnesteinen i QControls eksistens, og samtidig hovedårsaken til å bruke en betydelig mengde tid og ressurser på å bygge denne typen protokoller, er behovet for å skaffe en enkelt autoritativ konfigurasjonskilde og til slutt synkronisere våre tilstedeværelsespunkter. med det. Selve lagringen var bare ett av flere krav under utviklingen av QControl. I tillegg trengte vi også integrasjoner med eksisterende og planlagte tjenester ved tilstedeværelsespunkter (POP), smarte (og tilpassbare) metoder for datavalidering, samt tilgangskontroll. Foruten dette ønsket vi også å kontrollere et slikt system ved å bruke kommandoer i stedet for å gjøre endringer i filer. Før QControl ble data sendt til punkter nesten manuelt. Hvis et av tilstedeværelsespunktene var utilgjengelig og vi glemte å oppdatere det senere, ville konfigurasjonen ende opp usynkronisert, og vi måtte kaste bort tid på å få den opp å kjøre igjen.

Som et resultat kom vi opp med følgende opplegg:
Qrator-filtrering nettverkskonfigurasjon styringssystem
Konfigurasjonsserveren er ansvarlig for datavalidering og lagring; ruteren har flere endepunkter som mottar og kringkaster konfigurasjonsoppdateringer fra klienter og støtteteam til serveren, og fra serveren til tilstedeværelsespunkter.

Internett-tilkoblingskvaliteten varierer fortsatt mye rundt om i verden - for å illustrere dette poenget, la oss se på en enkel MTR fra Praha, Tsjekkia til Singapore og Hong Kong.

Qrator-filtrering nettverkskonfigurasjon styringssystem
MTR fra Praha til Singapore

Qrator-filtrering nettverkskonfigurasjon styringssystem
Samme med Hong Kong

Høy latens betyr lavere hastighet. I tillegg kommer pakketap. Kanalbredde kompenserer ikke for dette problemet, som alltid må tas i betraktning ved bygging av desentraliserte systemer.

Den fullstendige konfigurasjonen av et tilstedeværelse er en betydelig mengde data som må sendes til mange mottakere over upålitelige tilkoblinger. Heldigvis, selv om konfigurasjonen endres hele tiden, skjer det i små trinn.

Nylig stabil design

Vi kan si at å bygge et distribuert nettverk basert på prinsippet om inkrementelle oppdateringer er en ganske åpenbar løsning. Men det er mange problemer med diff. Vi må lagre alle forskjellene mellom referansepunktene, og også kunne sende dem på nytt i tilfelle noen gikk glipp av en del av dataene. Hver destinasjon må bruke dem i en strengt spesifisert rekkefølge. Vanligvis, ved flere destinasjoner, kan en slik operasjon ta lang tid. Mottakeren må også kunne be om de manglende delene, og selvfølgelig må den sentrale delen svare på en slik forespørsel på riktig måte, og kun sende de manglende dataene.

Som et resultat kom vi til en ganske interessant løsning - vi har bare ett referanselag, fast, la oss kalle det stabilt, og bare en diff for det - nylig. Hver siste er basert på den sist genererte stallen og er tilstrekkelig til å gjenoppbygge konfigurasjonsdataene. Så snart den ferske siste når destinasjonen, er den gamle ikke lenger nødvendig.

Alt som gjenstår er å sende en ny stabil konfigurasjon fra tid til annen, for eksempel fordi nylig har blitt for stor. Det som også er viktig her er at vi sender ut alle disse oppdateringene i en kringkasting/multicast-modus, uten å bekymre oss for individuelle mottakere og deres evne til å sette sammen databiter. Når vi er sikre på at alle har den riktige stallen, sender vi bare nye nylige. Er det verdt å presisere at dette fungerer? Virker. Stable er bufret på konfigurasjonsserveren og mottakere, nylig opprettes etter behov.

Arkitektur av to-nivå transport

Hvorfor bygget vi transporten vår på to nivåer? Svaret er ganske enkelt – vi ønsket å koble ruting fra logikk på høyt nivå, og hentet inspirasjon fra OSI-modellen med dens transport- og applikasjonslag. Vi brukte Thrift for rollen til transportprotokollen, og msgpack-serialiseringsformatet for høynivåformatet for kontrollmeldinger. Dette er grunnen til at ruteren (som utfører multicast/kringkasting/relé) ikke ser inn i msgpack, ikke pakker ut eller pakker innholdet tilbake, og bare videresender data.

Thrift (fra engelsk - "thrift", uttales [θrift]) er et grensesnittbeskrivelsesspråk som brukes til å definere og lage tjenester for forskjellige programmeringsspråk. Det er et rammeverk for eksterne prosedyreanrop (RPC). Kombinerer en programvarepipeline med en kodegenereringsmotor for å utvikle tjenester som fungerer mer eller mindre effektivt og enkelt mellom språk.

Vi valgte Thrift-rammeverket på grunn av RPC og støtte for mange språk. Som vanlig var de enkle delene klienten og serveren. Ruteren viste seg imidlertid å være en tøff nøtt å knekke, blant annet på grunn av mangelen på en ferdig løsning under utviklingen vår.

Qrator-filtrering nettverkskonfigurasjon styringssystemDet finnes andre alternativer, for eksempel protobuf / gRPC, men da vi startet prosjektet vårt var gRPC ganske nytt og vi turte ikke å ta det om bord.

Selvfølgelig kunne vi (og burde faktisk ha) bygget vår egen sykkel. Det ville være lettere å lage en protokoll for det vi trenger fordi klient-server-arkitekturen er relativt enkel å implementere sammenlignet med å bygge en ruter på Thrift. På en eller annen måte er det en tradisjonell skjevhet mot selvskrevne protokoller og implementeringer av populære biblioteker (med god grunn); i tillegg kommer alltid spørsmålet under diskusjoner: "Hvordan skal vi overføre dette til andre språk?" Så vi kastet umiddelbart ut ideen om en sykkel.

Msgpack ligner på JSON, men raskere og mindre. Det er et binært dataserialiseringsformat som lar data utveksles mellom flere språk.

På det første nivået har vi Thrift med minimumsinformasjonen som er nødvendig for at ruteren skal kunne videresende meldingen. På det andre nivået er det pakkede msgpack-strukturer.

Vi valgte msgpack fordi den er raskere og mer kompakt sammenlignet med JSON. Men enda viktigere, det støtter tilpassede datatyper, slik at vi kan bruke kule funksjoner som å sende rå binærfiler eller spesielle objekter som indikerer fravær av data, noe som var viktig for vårt "nylig stabile" opplegg.

JMESPath
JMESPath er et JSON-spørringsspråk.
Det er akkurat slik beskrivelsen vi får fra den offisielle JMESPath-dokumentasjonen ser ut, men faktisk gjør den mye mer enn det. JMESPath lar deg søke og filtrere undertrær i en vilkårlig trestruktur, og bruke endringer på data på farten. Den lar deg også legge til spesielle filtre og datatransformasjonsprosedyrer. Selv om det selvfølgelig krever hjerneinnsats for å forstå.

Jinja
For noen forbrukere må vi gjøre konfigurasjonen om til en fil - så vi bruker en malmotor og Jinja er det åpenbare valget. Med dens hjelp genererer vi en konfigurasjonsfil fra malen og data mottatt på destinasjonen.

For å generere en konfigurasjonsfil trenger vi en JMESPath-forespørsel, en mal for filplasseringen i FS og en mal for selve konfigurasjonen. Det er også en god idé på dette stadiet å avklare filtillatelsene. Alt dette ble vellykket kombinert i én fil - før starten av konfigurasjonsmalen la vi en overskrift i YAML-format som beskriver resten.

For eksempel:

---
selector: "[@][[email protected]._meta.version == `42`] | items([0].fft_config || `{}`)"
destination_filename: "fft/{{ match[0] }}.json"
file_mode: 0644
reload_daemons: [fft] ...
{{ dict(match[1]) | json(indent=2, sort_keys=True) }}

For å lage en konfigurasjonsfil for en ny tjeneste, legger vi kun til en ny malfil. Ingen endringer i kildekoden eller programvaren på tilstedeværelsespunkter er nødvendig.

Hva har endret seg siden QControl ble publisert? Det første og viktigste er konsistent og pålitelig levering av konfigurasjonsoppdateringer til alle noder i nettverket. Den andre er å motta et kraftig verktøy for å sjekke konfigurasjonen og gjøre endringer i den av vårt supportteam, så vel som av forbrukere av tjenesten.

Vi var i stand til å gjøre alt dette ved å bruke det nylig stabile oppdateringsskjemaet for å forenkle kommunikasjonen mellom konfigurasjonsserveren og konfigurasjonsmottakerne. Bruke en to-lags protokoll for å støtte en innholdsuavhengig måte å rute data på. Vellykket integrert en Jinja-basert konfigurasjonsgenereringsmotor i et distribuert filtreringsnettverk. Dette systemet støtter et bredt spekter av konfigurasjonsmetoder for våre distribuerte og heterogene perifere enheter.

Takk for hjelpen med å skrive materialet. VolanDamrod, serenheit, Ikke.

engelsk versjon post.

Kilde: www.habr.com

Legg til en kommentar