Moderni podatkovni centri imaju stotine instaliranih aktivnih uređaja koji su obuhvaćeni različitim vrstama nadzora. Ali čak i idealan inženjer sa savršenim nadzorom u rukama moći će ispravno odgovoriti na kvar mreže u samo nekoliko minuta. U izvješću na konferenciji Next Hop 2020 predstavio sam metodologiju dizajna DC mreže, koja ima jedinstvenu značajku - podatkovni centar se sam ozdravi u milisekundama. Točnije, inženjer mirno otkloni problem, dok servisi to jednostavno ne primijete.
Za mnoge mrežne inženjere, mreža podatkovnog centra počinje, naravno, s ToR-om, s prekidačem u stalku. ToR obično ima dvije vrste poveznica. Mali idu na servere, drugi - njih je N puta više - idu prema kralježnicama prve razine, odnosno njenim uplinkovima. Uplinkovi se obično smatraju jednakim, a promet između uplinkova je uravnotežen na temelju hash-a iz 5-torke, koji uključuje proto, src_ip, dst_ip, src_port, dst_port. Ovdje nema iznenađenja.
Zatim, kako izgleda arhitektura plana? Bodlje prve razine nisu međusobno povezane, već su povezane preko superspina. Slovo X bit će odgovorno za superspine; to je gotovo poput križne veze.
I jasno je da su, s druge strane, tori povezani sa svim kralježnicama prve razine. Što je važno na ovoj slici? Ako imamo interakciju unutar stalka, onda interakcija, naravno, ide kroz ToR. Ako se interakcija događa unutar modula, tada se interakcija događa kroz kralježnice prve razine. Ako je interakcija intermodularna - kao ovdje, ToR 1 i ToR 2 - tada će interakcija ići kroz kralježnice i prve i druge razine.
U teoriji, takva je arhitektura lako skalabilna. Ako imamo kapacitet priključka, rezervni prostor u podatkovnom centru i unaprijed postavljena vlakna, tada se broj traka uvijek može povećati, čime se povećava ukupni kapacitet sustava. To je vrlo lako učiniti na papiru. U životu bi bilo ovako. Ali današnja priča nije o tome.
Želim da se donesu pravi zaključci. Imamo mnogo puteva unutar podatkovnog centra. Uvjetno su neovisni. Jedan put unutar podatkovnog centra moguć je samo unutar ToR-a. Unutar modula imamo broj staza jednak broju traka. Broj staza između modula jednak je umnošku broja ravnina i broja superspina u svakoj ravnini. Da bi bilo jasnije, da biste dobili dojam o razmjerima, dat ću brojke koje vrijede za jedan od Yandex podatkovnih centara.
Postoji osam ravnina, svaka ravnina ima 32 superspina. Kao rezultat toga, ispada da unutar modula postoji osam staza, a međumodulnom interakcijom već ih ima 256.
Odnosno, ako razvijamo Kuharicu, pokušavajući naučiti kako izgraditi podatkovne centre otporne na pogreške koji se sami liječe, tada je planarna arhitektura pravi izbor. Rješava problem skaliranja i u teoriji je jednostavan. Postoji mnogo neovisnih puteva. Ostaje pitanje: kako takva arhitektura preživljava neuspjehe? Ima raznih kvarova. I o tome ćemo sada razgovarati.
Neka se “razboli” jedan od naših superspina. Ovdje sam se vratio na dvoravninsku arhitekturu. Držat ćemo se ovih kao primjera jer ćemo jednostavno lakše vidjeti što se događa s manje pokretnih dijelova. Neka se X11 razboli. Kako će to utjecati na usluge koje žive unutar podatkovnih centara? Mnogo ovisi o tome kako neuspjeh zapravo izgleda.
Ako je kvar dobar, uhvaćen je na razini automatizacije istog BFD-a, automatizacija sretno postavlja problematične spojeve i izolira problem, onda je sve u redu. Imamo mnogo putova, promet se odmah preusmjerava na alternativne pravce, a službe neće ništa primijetiti. Ovo je dobar scenarij.
Loš scenarij je ako imamo stalne gubitke, a automatika ne uočava problem. Da bismo razumjeli kako to utječe na aplikaciju, morat ćemo potrošiti malo vremena na raspravu o tome kako TCP radi.
Nadam se da neću nikoga šokirati ovom informacijom: TCP je protokol za potvrdu prijenosa. To jest, u najjednostavnijem slučaju, pošiljatelj šalje dva paketa i prima kumulativnu potvrdu za njih: "Primio sam dva paketa."
Nakon toga će poslati još dva paketa i situacija će se ponoviti. Unaprijed se ispričavam zbog pojednostavljenja. Ovaj scenarij je točan ako je prozor (broj paketa u letu) dva. Naravno, u općem slučaju to nije nužno slučaj. Ali veličina prozora ne utječe na kontekst prosljeđivanja paketa.
Što se događa ako izgubimo paket 3? U ovom slučaju primatelj će primiti pakete 1, 2 i 4. I on će eksplicitno poručiti pošiljatelju pomoću SACK opcije: “Znate, stigla su tri, ali je srednji izgubljen”. Kaže, "Ack 2, SACK 4."
U ovom trenutku pošiljatelj bez problema ponavlja točno onaj paket koji je izgubljen.
Ali ako se zadnji paket u prozoru izgubi, situacija će izgledati potpuno drugačije.
Primatelj prima prva tri paketa i prvi počinje čekati. Zahvaljujući nekim optimizacijama u TCP stogu Linux kernela, čekat će na upareni paket osim ako zastavice izričito ne pokazuju da je to posljednji paket ili nešto slično. Pričekat će dok ne istekne odgođeni ACK timeout i zatim poslati potvrdu za prva tri paketa. Ali sada će pošiljatelj čekati. Ne zna je li četvrti paket izgubljen ili će tek stići. A kako ne bi preopteretio mrežu, pokušat će pričekati izričitu naznaku da je paket izgubljen ili da istekne RTO timeout.
Što je RTO timeout? Ovo je maksimum RTT-a izračunat TCP stogom i nekom konstantom. Kakva je to konstanta, sada ćemo razgovarati.
Ali važno je da ako opet nemamo sreće i četvrti paket se opet izgubi, tada se RTO udvostručuje. Odnosno, svaki neuspješan pokušaj znači udvostručenje timeouta.
Sada da vidimo čemu je ova baza jednaka. Prema zadanim postavkama minimalni RTO je 200 ms. Ovo je minimalni RTO za podatkovne pakete. Za SYN pakete je drugačije, 1 sekunda. Kao što vidite, čak i prvi pokušaj ponovnog slanja paketa trajat će 100 puta dulje od RTT-a unutar podatkovnog centra.
Sada se vratimo našem scenariju. Što se događa s uslugom? Usluga počinje gubiti pakete. Neka servis prvo ima uvjetno sreće i izgubi nešto usred prozora, onda primi SACK i ponovno pošalje pakete koji su izgubljeni.
Ali ako se loša sreća ponovi, onda imamo RTO. Što je tu važno? Da, imamo mnogo staza u našoj mreži. Ali TCP promet jedne određene TCP veze nastavit će prolaziti kroz isti prekinuti stog. Gubici paketa, pod uvjetom da se ovaj naš čarobni X11 ne gasi sam od sebe, ne dovode do slijevanja prometa u područja koja nisu problematična. Pokušavamo isporučiti paket kroz isti pokvareni stog. To dovodi do kaskadnog kvara: podatkovni centar je skup aplikacija koje međusobno djeluju, a neke od TCP veza svih tih aplikacija počinju degradirati - jer superspine općenito utječe na sve aplikacije koje se nalaze unutar podatkovnog centra. Kako se kaže: ako konja nisi potkovao, konj je šepao; konj je šepao - izvještaj nije dostavljen; izvještaj nije dostavljen – izgubili smo rat. Samo što se ovdje broji u sekundama od trenutka nastanka problema do stupnja degradacije koji usluge počnu osjećati. To znači da korisnici možda negdje nešto propuštaju.
Dva su klasična rješenja koja se međusobno nadopunjuju. Prvi su servisi koji pokušavaju ubaciti slamke i riješiti problem ovako: “Idemo podesiti nešto u TCP stacku. Napravimo vremensko ograničenje na razini aplikacije ili dugotrajnih TCP sesija s internim provjerama zdravlja.” Problem je što takva rješenja: a) uopće ne skaliraju; b) vrlo su slabo provjereni. Odnosno, čak i ako usluga slučajno konfigurira TCP stog na način koji ga čini boljim, prvo, malo je vjerojatno da će biti primjenjivo za sve aplikacije i sve podatkovne centre, a drugo, najvjerojatnije, neće shvatiti da je to učinjeno ispravno, a što ne. Odnosno, radi, ali radi loše i ne skalira se. A ako postoji problem s mrežom, tko je kriv? Naravno, NOC. Što radi NOC?
Mnoge službe vjeruju da se u radu NOC-a događa ovako nešto. Ali da budem iskren, ne samo to.
NOC u klasičnoj shemi bavi se razvojem mnogih sustava nadzora. To su i crna kutija i bijela kutija za praćenje. O primjeru praćenja kralježnice crne kutije
Što biste zaista željeli primiti? Imamo toliko načina. A problemi nastaju upravo zato što TCP tokovi koji nemaju sreće nastavljaju koristiti istu rutu. Trebamo nešto što će nam omogućiti korištenje više ruta unutar jedne TCP veze. Čini se da imamo rješenje. Postoji TCP, koji se zove multipath TCP, odnosno TCP za više staza. Istina, razvijen je za potpuno drugačiji zadatak - za pametne telefone koji imaju nekoliko mrežnih uređaja. Kako bi se povećao prijenos ili napravio primarni/rezervni način rada, razvijen je mehanizam koji stvara više niti (sesija) transparentno za aplikaciju i omogućuje vam prebacivanje između njih u slučaju kvara. Ili, kao što sam rekao, povećajte niz.
Ali ovdje postoji nijansa. Da bismo razumjeli što je to, morat ćemo pogledati kako se niti uspostavljaju.
Niti se instaliraju sekvencijalno. Prvo se instalira prva nit. Sljedeće niti se zatim postavljaju pomoću kolačića koji je već dogovoren unutar te niti. I tu je problem.
Problem je u tome što ako se prva nit sama ne uspostavi, druga i treća nit se nikada neće pojaviti. To jest, multipath TCP ne rješava gubitak SYN paketa u prvom toku. A ako se SYN izgubi, multipath TCP se pretvara u regularni TCP. To znači da nam u okruženju podatkovnog centra neće pomoći riješiti problem gubitaka u tvornici i naučiti koristiti više putanja u slučaju kvara.
Što nam može pomoći? Neki od vas su već iz naslova pogodili da će važno polje u našoj daljnjoj priči biti polje zaglavlja oznake protoka IPv6. Dapače, ovo je polje koje se pojavljuje u v6, nema ga u v4, zauzima 20 bita, a oko njegove upotrebe već se dugo vode polemike. Ovo je vrlo zanimljivo - bilo je sporova, nešto je popravljeno unutar RFC-a, a istovremeno se pojavila implementacija u Linux kernelu, koja nije nigdje dokumentirana.
Pozivam te da pođeš sa mnom u malu istragu. Pogledajmo što se događalo u Linux kernelu u posljednjih nekoliko godina.
godina 2014. Inženjer iz jedne velike i cijenjene tvrtke dodaje funkcionalnosti Linux kernela ovisnost vrijednosti oznake toka o hash-u socketa. Što su pokušavali popraviti ovdje? Ovo je povezano s RFC 6438, koji raspravlja o sljedećem problemu. Unutar podatkovnog centra, IPv4 je često enkapsuliran u IPv6 pakete, jer je sama tvornica IPv6, ali IPv4 se mora nekako dati izvana. Dugo je bilo problema sa switchevima koji nisu mogli pogledati ispod dva IP zaglavlja da bi došli do TCP ili UDP i tamo pronašli src_ports, dst_ports. Pokazalo se da je hash, ako pogledate prva dva IP zaglavlja, ispao gotovo fiksan. Kako bi se to izbjeglo, tako da balansiranje ovog enkapsuliranog prometa radi ispravno, predloženo je dodavanje hash-a enkapsuliranog paketa od 5 tuple vrijednosti polja oznake toka. Otprilike ista stvar je učinjena za druge sheme enkapsulacije, za UDP, za GRE, potonji je koristio polje GRE Key. Na ovaj ili onaj način, ciljevi su ovdje jasni. I barem su u tom trenutku bili korisni.
2015. dolazi nova zakrpa od istog cijenjenog inženjera. On je vrlo zanimljiv. Kaže sljedeće - mi ćemo nasumično rasporediti hash u slučaju negativnog događaja usmjeravanja. Što je negativni događaj usmjeravanja? Ovo je RTO o kojem smo ranije govorili, odnosno gubitak repa prozora je događaj koji je doista negativan. Istina, relativno je teško pogoditi da je to to.
2016, još jedna renomirana tvrtka, također velika. Rastavlja posljednje štake i čini tako da se hash, koji smo prethodno napravili nasumičnim, sada mijenja za svaki SYN ponovni prijenos i nakon svakog RTO timeout-a. I u ovom pismu, po prvi i posljednji put, naveden je krajnji cilj - osigurati da promet u slučaju gubitaka ili zagušenja kanala ima mogućnost mekog preusmjeravanja i korištenja više putanja. Naravno, nakon ovoga bilo je puno publikacija, lako ih možete pronaći.
Iako ne, ne možete, jer nije objavljena niti jedna publikacija na ovu temu. Ali znamo!
A ako ne razumijete u potpunosti što je učinjeno, reći ću vam sada.
Što je učinjeno, koja je funkcionalnost dodana Linux kernelu? txhash se mijenja u slučajnu vrijednost nakon svakog RTO događaja. Ovo je vrlo negativan rezultat usmjeravanja. Hash ovisi o ovom txhash-u, a oznaka protoka ovisi o skb hash-u. Ovdje se nalaze neki proračuni funkcija; svi detalji se ne mogu staviti na jedan slajd. Ako je netko znatiželjan, može proći kroz kod kernela i provjeriti.
Što je tu važno? Vrijednost polja oznake toka mijenja se u nasumični broj nakon svakog RTO. Kako to utječe na naš nesretni TCP tok?
Ako se dogodi SACK, ništa se ne mijenja jer pokušavamo ponovno poslati poznati izgubljeni paket. Zasada je dobro.
Ali u slučaju RTO-a, pod uvjetom da smo dodali oznaku toka hash funkciji na ToR-u, promet može ići drugom rutom. A što je više traka, to je veća šansa da će pronaći stazu na koju ne utječe kvar na određenom uređaju.
Ostaje jedan problem - RTO. Naravno, postoji i drugi put, ali na ovaj se gubi puno vremena. 200 ms je puno. Drugi je potpuno divlji. Ranije sam govorio o vremenskim ograničenjima za koje su usluge konfigurirane. Dakle, sekunda je timeout, koji obično konfigurira servis na razini aplikacije, au tome će servis čak biti relativno u pravu. Štoviše, ponavljam, pravi RTT unutar modernog podatkovnog centra je oko 1 milisekunde.
Što možete učiniti s RTO timeoutima? Timeout, koji je odgovoran za RTO u slučaju gubitka paketa podataka, može se konfigurirati relativno jednostavno iz korisničkog prostora: postoji IP uslužni program, a jedan od njegovih parametara sadrži isti rto_min. Uzimajući u obzir da RTO, naravno, treba prilagoditi ne globalno, već za dane prefikse, takav mehanizam izgleda prilično izvodljiv.
Istina, sa SYN_RTO sve je nešto gore. Prirodno je zabijen. Kernel ima fiksnu vrijednost od 1 sekunde, i to je to. Tamo ne možete doći iz korisničkog prostora. Postoji samo jedan način.
eBPF priskače u pomoć. Pojednostavljeno rečeno, to su mali C programi. Mogu se umetnuti u hookove na različitim mjestima u izvršavanju kernel stack-a i TCP stack-a, s kojima možete promijeniti vrlo velik broj postavki. Općenito, eBPF je dugoročni trend. Umjesto rezanja desetaka novih sysctl parametara i proširenja IP uslužnog programa, pokret se kreće prema eBPF-u i širi njegovu funkcionalnost. Koristeći eBPF, možete dinamički mijenjati kontrole zagušenja i razne druge TCP postavke.
Ali važno nam je da se može koristiti za promjenu vrijednosti SYN_RTO. Štoviše, postoji javno objavljen primjer:
Što već znamo? Činjenica da ravna arhitektura dopušta skaliranje, pokazalo se da je izuzetno korisno za nas kada omogućimo oznaku protoka na ToR-u i dobijemo mogućnost protoka oko problematičnih područja. Najbolji način za smanjenje RTO i SYN-RTO vrijednosti je korištenje eBPF programa. Ostaje pitanje: je li sigurno koristiti oznaku protoka za balansiranje? I tu postoji jedna nijansa.
Pretpostavimo da na svojoj mreži imate uslugu koja živi u anycastu. Nažalost, nemam vremena ulaziti u detalje o tome što je anycast, ali to je distribuirana usluga s različitim fizičkim poslužiteljima dostupnima preko iste IP adrese. I evo mogućeg problema: RTO događaj se može dogoditi ne samo kada promet prolazi kroz tkaninu. Može se dogoditi i na razini ToR međuspremnika: kada se dogodi incast događaj, može se dogoditi čak i na hostu kada host nešto prolije. Kada se RTO događaj dogodi i promijeni oznaku toka. U tom slučaju promet može ići na drugu anycast instancu. Pretpostavimo da je ovo anycast s statusom, sadrži stanje veze - to bi mogao biti L3 Balancer ili neka druga usluga. Tada nastaje problem jer nakon RTO-a TCP veza dolazi na server koji ne zna ništa o toj TCP vezi. A ako nemamo dijeljenje stanja između anycast poslužitelja, tada će takav promet biti prekinut i TCP veza će biti prekinuta.
Što možete učiniti ovdje? Unutar vašeg kontroliranog okruženja, gdje ste omogućili balansiranje oznake toka, morate zabilježiti vrijednost oznake toka kada pristupate bilo kojim poslužiteljima. Najlakši način je to učiniti kroz isti eBPF program. Ali ovdje je vrlo važna stvar - što učiniti ako ne upravljate mrežom podatkovnog centra, ali ste telekom operater? Ovo je i vaš problem: počevši od određenih verzija Junipera i Ariste, oni prema zadanim postavkama uključuju oznaku toka u svoje hash funkcije - iskreno, iz razloga koji mi nije jasan. To može uzrokovati prekid TCP veza korisnika koji prolaze kroz vašu mrežu. Stoga preporučujem da ovdje provjerite postavke usmjerivača.
Na ovaj ili onaj način, čini mi se da smo spremni prijeći na eksperimente.
Kada smo omogućili oznaku toka na ToR-u, pripremili eBPF agenta, koji sada živi na hostovima, odlučili smo ne čekati sljedeći veliki kvar, već provesti kontrolirane eksplozije. Uzeli smo ToR, koji ima četiri uplinka, i postavili spustove na jednom od njih. Izvukli su pravilo i rekli - sada gubite sve pakete. Kao što vidite lijevo, imamo praćenje po paketu, što je palo na 75%, odnosno gubi se 25% paketa. Desno su grafikoni usluga koje stoje iza ovog ToR-a. U biti, to su grafikoni prometa sučelja s poslužiteljima unutar stalka. Kao što vidite, potonuli su još niže. Zašto su pali niže - ne za 25%, nego u nekim slučajevima za 3-4 puta? Ako TCP veza nije sretna, ona nastavlja pokušavati doći kroz pokvareni spoj. Ovo je pogoršano tipičnim ponašanjem servisa unutar DC-a - za jedan korisnički zahtjev generira se N zahtjeva za interne servise, a odgovor će stići korisniku ili kada svi izvori podataka odgovore ili kada nastupi vremensko ograničenje u aplikaciji. razinu, koju još treba konfigurirati. Odnosno, sve je jako, jako loše.
Sada isti eksperiment, ali s omogućenom vrijednošću oznake toka. Kao što vidite, s lijeve strane naš nadzor serije pao je za istih 25%. To je apsolutno točno, jer ne zna ništa o retransmitima, šalje pakete i jednostavno broji omjer broja isporučenih i izgubljenih paketa.
A desno je raspored servisa. Ovdje nećete pronaći učinak problematičnog zgloba. U istim tim milisekundama, promet je tekao iz problematičnog područja prema tri preostale uzlazne veze na koje problem nije utjecao. Imamo mrežu koja se sama liječi.
Ovo je moj posljednji slajd, vrijeme je da rezimiram. Sada se nadam da znate kako izgraditi samoozdravljujuću mrežu podatkovnog centra. Nećete morati prolaziti kroz arhivu Linux kernela i tamo tražiti posebne zakrpe, znate da oznaka Flow u ovom slučaju rješava problem, ali morate pažljivo pristupiti ovom mehanizmu. I još jednom naglašavam da ako ste telekom operater, ne biste trebali koristiti flow label kao hash funkciju, inače ćete ometati sesije svojih korisnika.
Mrežni inženjeri moraju doživjeti konceptualnu promjenu: mreža ne počinje s ToR-om, ne s mrežnim uređajem, već s hostom. Prilično upečatljiv primjer je kako koristimo eBPF i za promjenu RTO-a i za popravljanje oznake toka prema bilo kojim uslugama.
Mehanika oznake toka svakako je prikladna za druge primjene unutar kontroliranog administrativnog segmenta. To može biti promet između podatkovnih centara ili možete koristiti takve mehanike na poseban način za upravljanje odlaznim prometom. Ali o ovome ću vam pričati, nadam se, sljedeći put. Hvala vam puno na pažnji.
Izvor: www.habr.com