Netværkskonfigurationsstyringssystemet Qrator

Netværkskonfigurationsstyringssystemet Qrator

TL;DR: Beskrivelse af klient-server-arkitekturen i vores interne netværkskonfigurationsstyringssystem, QControl. I bunden ligger en to-niveau transportprotokol, der arbejder med gzip-pakkede beskeder uden dekomprimering mellem endepunkterne. Distribuerede routere og endepunkter modtager konfigurationsopdateringer, og selve protokollen muliggør installation af lokaliserede mellemliggende relæer. Systemet er bygget efter princippet differential backup (“recent-stable”, beskrevet nedenfor) og bruger JMESpath forespørgselsprog sammen med Jinja skabelonmotoren til rendering af konfigurationsfiler.

Qrator Labs driver et globalt distribueret netværk til neutralisering af angreb. Vores netværk fungerer efter anycast-princippet, og subnettene annonceres via BGP. Som en BGP anycast-netværk, fysisk beliggende i flere regioner på Jorden, kan vi behandle og filtrere illegitim trafik nærmere internettets kerne — Tier-1 operatører.

På den anden side er det ikke nemt at være et geografisk distribueret netværk. Kommunikation mellem netværkspunkterne er kritisk for en sikkerhedsudbyder for at have en konsistent konfiguration af alle netværkets noder, så de kan opdateres rettidigt. Derfor, for at kunne levere det maksimale mulige niveau af kerneydelsen til forbrugeren, måtte vi finde en måde at sikre pålideligt at synkronisere konfigurationsdataene mellem kontinenter.

I begyndelsen var Ordet. Det blev hurtigt til en kommunikationsprotokol, der havde brug for en opdatering.


Grundpillerne i QControl's eksistens og samtidig den primære årsag til at bruge betydelig tid og ressourcer på at udvikle en sådan protokol er behovet for at få en enhed, som er den autoritative kilde til konfiguration, og i sidste ende synkronisere vores tilstedeværelsespunkter med den. Selve lagringsstedet var kun et af flere krav under udviklingen af QControl. Derudover var vi også nødt til at have integrationer med eksisterende og planlagte tjenester på tilstedeværelsespunkterne (TP), intelligente (og tilpassede) måder at validere data på, samt adskillelse af adgang. Derudover ville vi også styre et sådant system via kommandoer og ikke ved at ændre filer. Før QControl blev data sendt til tilstedeværelsespunkterne stort set manuelt. Hvis et af tilstedeværelsespunkterne var utilgængeligt, og vi glemte at opdatere det senere, var konfigurationen ikke længere synkroniseret — det krævede tid at få det tilbage i drift.

Resultatet blev, at vi udviklede følgende skema:
Netværkskonfigurationsstyringssystemet Qrator
Konfigurationsserveren er ansvarlig for datavalidation og opbevaring, routeren har flere endpoints, der modtager og transmitterer konfigurationsopdateringer fra kunder og supportteam til serveren og fra serveren til tilstedeværelsespunkterne.

Kvaliteten af internetforbindelsen varierer stadig betydeligt i forskellige dele af verden — for at illustrere dette punkt, lad os tage et simpelt MTR fra Prag, Tjekkiet til Singapore og Hongkong.

Netværkskonfigurationsstyringssystemet Qrator
MTR fra Prag til Singapore

Netværkskonfigurationsstyringssystemet Qrator
Det samme til Hongkong

Høje latenser betyder lavere hastighed. Desuden er der pakketab. Bredbåndet kompenserer ikke for dette problem, som altid bør tages i betragtning ved opbygning af decentrale systemer.

Den samlede konfiguration for et tilstedeværelsespunkt er en betydelig mængde data, der skal sendes til mange modtagere via usikre forbindelser. Heldigvis, selvom konfigurationen ændrer sig konstant, sker det i små portioner.

Design recent-stable

Man kan sige, at opbygningen af et distribueret netværk baseret på inkrementelle opdateringer er en ret indlysende løsning. Men der er mange problemer forbundet med diffs. Vi skal gemme alle diffs mellem referencepunkter og være i stand til at sende dem, hvis nogen har mistet dele af dataene. Hver destination skal anvende dem i en strengt fastlagt rækkefølge. Normalt kan en sådan operation tage lang tid, når der er flere destinationer. Modtageren skal også være i stand til at anmode om manglende dele, og selvfølgelig skal centralen svare korrekt på en sådan anmodning ved kun at sende de manglende data.

Resultatet er, at vi er kommet frem til en ret interessant løsning — vi har kun ét fast referencelag, som vi kalder stable, og kun én diff for det — recent. Hver recent er baseret på den senest dannede stable og er tilstrækkelig til at rekonstruere konfigurationsdata. Så snart en frisk recent når sin destination, er den gamle ikke længere nødvendig.

Det er kun nødvendigt at sende den friske stable-konfiguration fra tid til anden, for eksempel fordi recent er blevet for stor. Det er også vigtigt, at vi sender alle disse opdateringer i broadcast/multicast-tilstand uden at bekymre os om individuelle modtagere og deres evne til at samle datadumperne sammen. Så snart vi har bekræftet, at alle har korrekt stable — sender vi kun nye recent. Skal det understreges, at dette virker? Det virker. Stable caches på konfigurationsserveren og hos modtagerne, og recent genereres efter behov.

To-niveaus transportarkitektur

Hvorfor byggede vi vores transport på to niveauer? Svaret er ret enkelt — vi ønskede at adskille routing fra den højniveau logik ved at hente inspiration fra OSI-modellen med dens transportniveau og applikationsniveau. Som transportprotokol valgte vi Thrift, og til det højniveau format af kontrolmeddelelser valgte vi msgpack serialiseringsformatet. Derfor ser routeren (der udfører multicast/broadcast/relay) ikke ind i msgpack, pakker ikke ud eller pakket indholdet tilbage og udfører kun videresendelsen af data.

Thrift (fra engelsk - 'besparelse', udtales som [θrift]) er et interface-beskrivelsessprog, der bruges til at definere og oprette tjenester på tværs af forskellige programmeringssprog. Det fungerer som en ramme til fjernprocedureopkald (RPC). Det kombinerer en programmeringspipeline med en kodegenereringsmotor til udvikling af tjenester, der fungerer effektivt og nemt mellem sprog i en eller anden grad.

Vi valgte Thrift-rammen på grund af RPC og understøttelsen af mange sprog. Som sædvanligt var klienten og serveren de lette dele. Routeren var dog en hård nødd, delvist på grund af manglen på en løsning til rådighed under vores udvikling.

Netværkskonfigurationsstyringssystemet QratorDer er også andre muligheder, såsom protobuf / gRPC, men da vi begyndte vores projekt, var gRPC stadig relativt nyt, og vi turde ikke tage det om bord.

Selvfølgelig kunne vi (og faktisk burde vi have gjort det) have skabt vores egen cykel. Det ville have været lettere at skabe en protokol til det, vi havde brug for, fordi klient-server-arkitekturen er relativt ligetil at implementere sammenlignet med at bygge en router på Thrift. På den ene eller anden måde er der en traditionel fordom mod hjemmelavede protokoller og implementeringer af populære biblioteker (ikke uden grund), og der opstår altid spørgsmålet: 'Hvordan vil vi portere dette til andre sprog?'. Derfor kassede vi straks idéerne om cyklen.

Msgpack er et alternativ til JSON, men hurtigere og mere kompakt. Det er et binært data serialiseringsformat, der muliggør datadeling mellem mange sprog.

På det første niveau har vi Thrift med det minimale nødvendige information til routeren for at sende beskeder. På det andet niveau er der de pakkede strukturer fra msgpack.

Vi valgte msgpack, fordi det er hurtigere og mere kompakt sammenlignet med JSON. Men hvad der er endnu vigtigere, det understøtter brugerdefinerede datatyper, hvilket gør det muligt for os at bruge seje funktioner som at overføre rå binære filer eller specielle objekter, der angiver fraværet af data, hvilket var vigtigt for vores skema 'recent-stable'.

JMESPath
JMESPath er et forespørgselsprog for JSON.
Sådan ser beskrivelsen ud, som vi får fra den officielle dokumentation for JMESPath, men den tilbyder faktisk meget mere. JMESPath giver mulighed for at søge og filtrere undertræer i vilkårlige træstrukturer samt anvende ændringer på dataene i realtid. Desuden gør det muligt at tilføje specielle filtre og datatransformationsprocedurer. Selvom det naturligvis kræver en del mental anstrengelse at forstå.

Jinja
For nogle brugere er det nødvendigt at omdanne konfigurationen til en fil — derfor bruger vi en templating-motor, og Jinja er et oplagt valg. Med den genererer vi konfigurationsfilen fra skabelonen og de data, der modtages på destinationen.

For at generere konfigurationsfilen har vi brug for en JMESPath-forespørgsel, en skabelon til filens placering i filsystemet samt en skabelon til selve konfigurationen. Det er også på dette tidspunkt en god idé at præcisere filens adgangsrettigheder. Alt dette er blevet heldigt kombineret i én fil — før vi begynder på konfigurationsskabelonen, tilføjer vi en header i YAML-format, der beskriver resten.

For eksempel:

---
vælger: "[@][?@.fft._meta.version == `42`] | items([0].fft_config || `{}`)"
destination_filename: "fft/{{ match[0] }}.json"
fil_tilstand: 0644
genindlæs_daemoner: [fft]
...
{{ dict(match[1]) | json(indent=2, sort_keys=True) }}

For at lave en konfigurationsfil til en ny service tilføjer vi blot en ny skabelonfil. Ingen ændringer kræves i kildekoden eller softwaren på tilstedeværelsesstederne.

Hvad er ændret efter introduktionen af QControl i driftsaktiviteterne? Det vigtigste er en ensartet og pålidelig levering af konfigurationsopdateringer til alle netværkets noder. For det andet får vores supportteam samt tjenesteyderne et kraftfuldt værktøj til at kontrollere og ændre konfigurationen.

Vi har formået at opnå alt dette ved at bruge recent-stable opdateringsskemaet for at forenkle kommunikationen mellem konfigurationsserveren og modtagerne af konfigurationen. Ved at bruge et to-niveau protokol, der understøtter en indholds-uafhængig data routing metode. Vi har succesfuldt integreret en Jinja-baseret konfiguration generator motor i et distribueret filtreringsnetværk. Dette system understøtter et bredt sæt konfigurationsmetoder for vores distribuerede og varierede periferi.

Tak for hjælpen med at skrive materialet VolanDamrod, serenheit, NoN.

Engelsk version indlæg.

Kilde: habr.com

Køb pålidelig webhosting med DDoS-beskyttelse, VPS VDS-servere 🔥 Køb pålidelig webhosting med DDoS-beskyttelse, VPS VDS-servere | ProHoster