Tinder Iwwergank zu Kubernetes

Note. iwwersat.: Mataarbechter vum weltberühmten Tinder Service hunn viru kuerzem e puer technesch Detailer gedeelt fir hir Infrastruktur op Kubernetes ze migréieren. De Prozess huet bal zwee Joer gedauert an huet zum Start vun enger ganz grousser Plattform op K8s gefouert, besteet aus 200 Servicer op 48 Tausend Container gehost. Wéi eng interessant Schwieregkeeten hunn d"Tinder Ingenieuren begéint a wéi eng Resultater koumen se? Liest dës Iwwersetzung.

Tinder Iwwergank zu Kubernetes

Firwat?

Viru bal zwee Joer huet Tinder decidéiert seng Plattform op Kubernetes ze plënneren. Kubernetes géif erlaben d'Tinder Team ze containeriséieren an op d'Produktioun mat minimalem Effort duerch onverännerbar Deployment ze plënneren (onverännerbar Deployment). An dësem Fall wieren d'Assemblée vun Uwendungen, hir Deployment, an d'Infrastruktur selwer eenzegaarteg duerch Code definéiert.

Mir hunn och no enger Léisung fir de Problem vun der Skalierbarkeet a Stabilitéit gesicht. Wann d'Skaléierung kritesch gouf, hu mir dacks e puer Minutten misse waarden fir nei EC2 Instanzen ze spinnen. D'Iddi fir Container ze lancéieren an Traffic a Sekonnen ze servéieren anstatt Minutte gouf fir eis ganz attraktiv.

De Prozess huet sech als schwéier erausgestallt. Wärend eiser Migratioun am fréien 2019 huet de Kubernetes Cluster kritesch Mass erreecht a mir hunn ugefaang verschidde Probleemer ze begéinen wéinst Trafficvolumen, Clustergréisst an DNS. Ënnerwee hu mir vill interessant Probleemer geléist am Zesummenhang mat der Migratioun vun 200 Servicer an Erhalen vun engem Kubernetes Cluster besteet aus 1000 Noden, 15000 Pods a 48000 Lafen Container.

Wéi?

Zënter Januar 2018 si mir duerch verschidden Etappe vun der Migratioun gaangen. Mir hunn ugefaang mat all eise Servicer ze containeriséieren an se op Kubernetes Testwollekëmfeld z'installéieren. Vun Oktober un hu mir ugefaang all existent Servicer op Kubernetes methodesch ze migréieren. Vum Mäerz vum Joer duerno hu mir d'Migratioun ofgeschloss an elo leeft d'Tinder Plattform exklusiv op Kubernetes.

Bauen Biller fir Kubernetes

Mir hunn iwwer 30 Quellcode Repositories fir Mikroservicer déi op engem Kubernetes Cluster lafen. De Code an dëse Repositories ass a verschiddene Sprooche geschriwwe (zum Beispill Node.js, Java, Scala, Go) mat multiple Runtime-Ëmfeld fir déiselwecht Sprooch.

De Build System ass entwéckelt fir e komplett personaliséierbare "Build Kontext" fir all Mikroservice ze bidden. Et besteet normalerweis aus engem Dockerfile an enger Lëscht vun Shell Kommandoen. Hiren Inhalt ass komplett personaliséierbar, a gläichzäiteg sinn all dës Baukontexter no engem standardiséierte Format geschriwwe ginn. Standardiséierung vum Baukontext erlaabt engem eenzege Bausystem all Mikroservicer ze handhaben.

Tinder Iwwergank zu Kubernetes
Figur 1-1. Standardiséierte Bauprozess iwwer Builder Container

Fir maximal Konsequenz tëscht Runtimes z'erreechen (Runtime Ëmfeld) dee selwechte Bauprozess gëtt während der Entwécklung an Testen benotzt. Mir hunn eng ganz interessant Erausfuerderung konfrontéiert: mir hu misse e Wee entwéckelen fir d'Konsistenz vum Bauëmfeld op der ganzer Plattform ze garantéieren. Fir dëst z'erreechen, ginn all Montageprozesser an engem speziellen Container duerchgefouert. Builder.

Seng Containerimplementatioun erfuerdert fortgeschratt Docker Techniken. Builder ierft déi lokal Benotzer ID a Geheimnisser (wéi SSH Schlëssel, AWS Umeldungsinformatiounen, etc.) néideg fir Zougang zu privaten Tinder Repositories. Et montéiert lokal Verzeichnisser mat Quelle fir natierlech Artefakte opzebauen. Dës Approche verbessert d'Performance well et d'Noutwendegkeet eliminéiert fir Bauartefakter tëscht dem Builder Container an dem Host ze kopéieren. Gelagert Bauartefakte kënnen ouni zousätzlech Konfiguratioun weiderbenotzt ginn.

Fir e puer Servicer musse mir en anere Container erstellen fir d'Kompilatiounsëmfeld an d'Runtime-Ëmfeld ze mapen (zum Beispill d'Node.js bcrypt-Bibliothéik generéiert plattformspezifesch binär Artefakte während der Installatioun). Wärend dem Kompiléierungsprozess kënnen Ufuerderunge tëscht Servicer variéieren, an déi lescht Dockerfile gëtt op der Flucht kompiléiert.

Kubernetes Cluster Architektur a Migratioun

Cluster Gréisst Gestioun

Mir hu beschloss ze benotzen kube-aws fir automatiséiert Cluster Deployment op Amazon EC2 Instanzen. Ganz am Ufank huet alles an engem gemeinsame Pool vu Wirbelen geschafft. Mir hu séier gemierkt datt d'Aarbechtslaascht no Gréisst an Instanztyp getrennt ass fir méi effizient Notzung vu Ressourcen ze maachen. D'Logik war datt e puer gelueden Multi-threaded Pods laafen méi prévisibel wat d'Leeschtung ugeet wéi hir Zesummeliewe mat enger grousser Unzuel vun Single-threaded Pods.

Um Enn hu mir eis op:

  • m5.4x grouss - fir Iwwerwaachung (Prometheus);
  • c5.4x grouss - fir Node.js Aarbechtslaascht (Single-threaded Aarbechtslaascht);
  • c5.2x grouss - fir Java a Go (Multithreaded Aarbechtslaascht);
  • c5.4x grouss - fir d'Kontrollpanel (3 Wirbelen).

D'Migratioun

Ee vun de Virbereedungsschrëtt fir d'Migratioun vun der aler Infrastruktur op Kubernetes war déi existent direkt Kommunikatioun tëscht Servicer op déi nei Lastbalancer (Elastic Load Balancers (ELB) ze redirectéieren. Si goufen op engem spezifesche Subnet vun enger virtueller privater Wollek (VPC) erstallt. Dëst Subnet gouf mat engem Kubernetes VPC verbonnen. Dëst huet eis erlaabt Moduler graduell ze migréieren, ouni déi spezifesch Uerdnung vu Serviceabhängegkeeten ze berücksichtegen.

Dës Endpunkte goufen erstallt mat gewiichtte Sätze vun DNS-Records, déi CNAMEs op all nei ELB weisen. Fir ze wiesselen, hu mir en neien Entrée bäigefüügt, deen op den neien ELB vum Kubernetes Service weist mat engem Gewiicht vun 0. Mir hunn dann d'Time To Live (TTL) vum Entrée op 0 gesat. Duerno goufen déi al an déi nei Gewiichter. lues ugepasst, a schlussendlech 100% vun der Laascht op en neie Server geschéckt. Nodeems de Wiessel ofgeschloss ass, ass den TTL Wäert op e méi adäquate Niveau zréck.

D'Java Moduler déi mir haten konnten mat nidderegen TTL DNS eens ginn, awer d'Node Uwendungen konnten net. Ee vun den Ingenieuren huet en Deel vum Verbindungspoolcode nei geschriwwen an et an engem Manager gewéckelt, deen d'Pools all 60 Sekonnen aktualiséiert huet. Déi gewielte Approche huet ganz gutt geschafft an ouni merkbar Leeschtungsverschlechterung.

D'Lektiounen

D'Limite vum Netzwierk Stoff

Am fréie Moien vum 8. Januar 2019 ass d'Tinder Plattform onerwaart erofgefall. Als Äntwert op eng onofhängeg Erhéijung vun der Plattformlatenz fréier dee Moien ass d'Zuel vun de Pods an Noden am Cluster eropgaang. Dëst huet verursaacht datt den ARP-Cache op all eise Wirbelen erschöpft ass.

Et ginn dräi Linux Optiounen am Zesummenhang mam ARP Cache:

Tinder Iwwergank zu Kubernetes
(Quell)

gc_thresh3 - dëst ass eng schwéier Limite. D'Erscheinung vun "Nopesch Dësch Iwwerfloss" Entréen am Logbicher bedeit datt och no der Synchroner Müllsammlung (GC) net genuch Plaz am ARP Cache war fir d'Nopeschentrée ze späicheren. An dësem Fall huet de Kernel de Paket einfach komplett verworf.

Mir benotzen Flannel als Reseau Stoff an Kubernetes. Pakete ginn iwwer VXLAN iwwerdroen. VXLAN ass en L2-Tunnel, deen uewen op engem L3-Netz opgehuewe gëtt. D'Technologie benotzt MAC-an-UDP (MAC Adress-an-User Datagram Protocol) Encapsulation an erlaabt Expansioun vu Layer 2 Netzwierksegmenter. Den Transportprotokoll am kierperlechen Datenzenternetz ass IP plus UDP.

Tinder Iwwergank zu Kubernetes
Bild 2-1. Flanell Diagramm (Quell)

Tinder Iwwergank zu Kubernetes
Figur 2-2. VXLAN Package (Quell)

All Kubernetes Aarbechter Node verdeelt e virtuellen Adressraum mat enger /24 Mask aus engem gréisseren /9 Block. Fir all Node ass dëst bedeit eng Entrée an der Routing Dësch, eng Entrée an der ARP Dësch (op der flannel.1 Interface), an eng Entrée an der schalt Dësch (FDB). Si ginn bäigefüügt déi éischte Kéier datt en Aarbechter Node gestart gëtt oder all Kéier wann en neien Node entdeckt gëtt.

Zousätzlech, Node-Pod (oder Pod-Pod) Kommunikatioun geet schlussendlech duerch d'Interface eth0 (wéi am Flanell Diagramm uewen gewisen). Dëst resultéiert an eng zousätzlech Entrée an der ARP Tabelle fir all entspriechend Quell an Destinatioun Host.

An eiser Ëmwelt ass dës Zort vu Kommunikatioun ganz heefeg. Fir Serviceobjekter a Kubernetes gëtt en ELB erstallt a Kubernetes registréiert all Node mam ELB. D'ELB weess näischt iwwer Pods an de gewielte Node ass vläicht net d'Finale Destinatioun vum Paket. De Punkt ass datt wann e Node e Paket vun der ELB kritt, et betruecht datt et d'Regele berücksichtegt Iteef fir e spezifesche Service a wielt zoufälleg e Pod op engem aneren Node.

Zu der Zäit vum Echec waren et 605 Wirbelen am Cluster. Aus den uewe genannte Grënn war dëst genuch fir d'Bedeitung ze iwwerwannen gc_thresh3, wat de Standard ass. Wann dat passéiert, fänken net nëmmen Paketen erof ze falen, mee de ganze Flannel virtuelle Adressraum mat enger /24 Mask verschwënnt aus der ARP Dësch. Node-Pod Kommunikatioun an DNS Ufroe ginn ënnerbrach (DNS gëtt an engem Cluster gehost; liest méi spéit an dësem Artikel fir Detailer).

Fir dëse Problem ze léisen, musst Dir d'Wäerter erhéijen gc_thresh1, gc_thresh2 и gc_thresh3 a restart Flannel fir déi fehlend Netzwierker nei z'registréieren.

Onerwaart DNS Skaléieren

Wärend dem Migratiounsprozess hu mir aktiv DNS benotzt fir den Traffic ze managen a lues a lues Servicer vun der aler Infrastruktur op Kubernetes ze transferéieren. Mir setzen relativ niddereg TTL Wäerter fir assoziéiert RecordSets an Route53. Wann déi al Infrastruktur op EC2 Instanzen leeft, huet eis Resolverkonfiguratioun op Amazon DNS gewisen. Mir hunn dat selbstverständlech geholl an den Impakt vum nidderegen TTL op eis Servicer an Amazon Servicer (wéi DynamoDB) ass gréisstendeels onnotéiert gaang.

Wéi mir Servicer op Kubernetes migréiert hunn, hu mir festgestallt datt DNS 250 Tausend Ufroe pro Sekonn veraarbecht huet. Als Resultat hunn d'Applikatiounen ugefaang konstante a seriöse Timeouts fir DNS Ufroen ze erliewen. Dëst ass geschitt trotz onheemlechen Efforten fir den DNS-Provider op CoreDNS ze optimiséieren an ze wiesselen (wat bei der Spëtzbelaaschtung 1000 Pods erreecht huet, déi op 120 Cores lafen).

Wärend aner méiglech Ursaachen a Léisungen fuerschen, hu mir entdeckt Artikel, beschreift d'Rassebedéngungen déi de Paketfilterkader beaflossen Netfilter am Linux. D'Timeouts déi mir observéiert hunn, gekoppelt mat engem ëmmer méi Konter insert_failed an der Flanell-Interface waren konsequent mat den Erkenntnisser vum Artikel.

De Problem geschitt op der Etapp vun der Quell an Destinatioun Network Adress Iwwersetzung (SNAT an DNAT) a spéider Entrée an den Dësch Konter. Ee vun de Léisungen intern diskutéiert a proposéiert vun der Gemeinschaft war den DNS op den Aarbechter Node selwer ze réckelen. An dësem Fall:

  • SNAT ass net néideg well de Verkéier am Node bleift. Et muss net duerch den Interface geréckelt ginn eth0.
  • DNAT ass net gebraucht well d'Destinatioun IP lokal zum Node ass, an net e zoufälleg ausgewielte Pod no de Reegelen Iteef.

Mir hu beschloss mat dëser Approche ze halen. CoreDNS gouf als DaemonSet a Kubernetes agesat a mir hunn e lokalen Node DNS Server an resolve.conf all Pod andeems Dir e Fändel setzt --cluster-dns Kommandoen kubelet . Dës Léisung huet sech effektiv fir DNS Timeouts erausgestallt.

Mir hunn awer nach ëmmer Paketverloscht an eng Erhéijung vum Konter gesinn insert_failed an der Flanell-Interface. Dëst ass weidergaang nodeems d'Léisung ëmgesat gouf well mir SNAT an / oder DNAT nëmme fir den DNS-Traffic eliminéiere konnten. Race Konditiounen goufen fir aner Zorte vu Verkéier preservéiert. Glécklecherweis sinn déi meescht vun eise Pakete TCP, a wann e Problem optrieden, gi se einfach nei iwwerdroen. Mir probéieren nach eng gëeegent Léisung fir all Zorte vu Verkéier ze fannen.

Benotzt Envoy fir Besser Load Balancing

Wéi mir Backend-Servicer op Kubernetes migréiert hunn, hu mir ugefaang un onbalancéiert Belaaschtung tëscht Pods ze leiden. Mir hunn erausfonnt datt HTTP Keepalive verursaacht huet datt ELB Verbindungen un den éischte fäerdege Pods vun all Deployment hänke bleiwen. Sou ass de gréissten Deel vum Traffic duerch e klenge Prozentsaz vu verfügbare Pods gaang. Déi éischt Léisung, déi mir getest hunn, war de MaxSurge op 100% op nei Deployementer fir schlëmmste Fall Szenarie setzen. Den Effet huet sech als onbedeitend an net villverspriechend a punkto gréisseren Deployementer erausgestallt.

Eng aner Léisung, déi mir benotzt hunn, war d'Ressourceufroe fir kritesch Servicer kënschtlech ze erhéijen. An dësem Fall hu Pods, déi an der Géigend plazéiert sinn, méi Spillraum am Verglach mat anere schwéiere Pods. Et géif op laang Siicht och net funktionnéieren, well et wier eng Verschwendung vu Ressourcen. Zousätzlech waren eis Node Uwendungen eenzeg-threaded a konnten deementspriechend nëmmen ee Kär benotzen. Déi eenzeg richteg Léisung war besser Belaaschtung ze benotzen.

Mir wëllen laang voll appréciéieren spécial. Déi aktuell Situatioun huet eis erlaabt et op eng ganz limitéiert Manéier z'installéieren an direkt Resultater ze kréien. Envoy ass en High-Performance, Open-Source, Layer-XNUMX Proxy entworf fir grouss SOA Uwendungen. Et kann fortgeschratt Laaschtbalancéierungstechniken implementéieren, dorënner automatesch Retries, Circuit Breaker, a global Tariflimitéierung. (Note. iwwersat.: Dir kënnt méi iwwer dëst liesen an dësen Artikel iwwer Istio, deen op Envoy baséiert.)

Mir sinn mat der folgender Konfiguratioun komm: hunn en Envoy Sidecar fir all Pod an eng eenzeg Streck, a verbënnt de Cluster mat dem Container lokal iwwer Hafen. Fir potenziell Kaskadéierung ze minimiséieren an e klengen Hitradius z'erhalen, hu mir eng Flott vun Envoy Front-Proxy Pods benotzt, een pro Disponibilitéitszone (AZ) fir all Service. Si hunn op en einfachen Service Entdeckungsmotor ugewisen, geschriwwen vun engem vun eisen Ingenieuren, deen einfach eng Lëscht vu Pods an all AZ fir e bestëmmte Service zréckginn.

Service Front-Envoys benotzt dann dëse Service Entdeckungsmechanismus mat engem Upstream Cluster a Route. Mir setzen adäquat Timeouts, erhéicht all Circuit Breaker Astellungen, a bäigefüügt eng minimal Retry Konfiguratioun fir mat eenzele Feeler ze hëllefen a glat Deployementer ze garantéieren. Mir hunn en TCP ELB virun all eenzel vun dësen Service Front-Envoys gesat. Och wann de Keepalive vun eiser Haaptproxy Schicht op e puer Envoy Pods hänke bliwwen ass, konnten se nach ëmmer d'Laascht vill besser handhaben a ware konfiguréiert fir duerch least_request am Backend ze balanséieren.

Fir den Ofbau hu mir den PreStop Hook op béide Applikatiouns-Pods a Sidecar Pods benotzt. Den Hook huet e Feeler ausgeléist beim Iwwerpréift vum Status vum Admin Endpunkt um Sidecar Container an ass fir eng Zäit schlofen fir aktiv Verbindungen z'erméiglechen.

Ee vun de Grënn, datt mir sou séier konnte plënneren, ass wéinst den detailléierte Metriken, déi mir einfach an eng typesch Prometheus Installatioun konnten integréieren. Dëst erlaabt eis genau ze gesinn wat geschitt wärend mir d'Konfiguratiounsparameter ugepasst hunn an de Verkéier ëmverdeelt hunn.

D'Resultater waren direkt an offensichtlech. Mir hunn ugefaang mat den onequilibréiertsten Servicer, an am Moment fonctionnéiert se virun den 12 wichtegste Servicer am Cluster. Dëst Joer plangen mir en Iwwergang zu engem vollen Service Mesh mat méi fortgeschratt Service Entdeckung, Circuit Break, Outlier Detektioun, Taux limitéieren an Tracing.

Tinder Iwwergank zu Kubernetes
Bild 3-1. CPU Konvergenz vun engem Service während dem Iwwergank zu Envoy

Tinder Iwwergank zu Kubernetes

Tinder Iwwergank zu Kubernetes

Schlussresultat

Duerch dës Erfahrung an zousätzlech Fuerschung hu mir e staarkt Infrastrukturteam mat staarke Fäegkeeten gebaut fir grouss Kubernetes Cluster ze designen, z'installéieren an ze bedreiwen. All Tinder Ingenieuren hunn elo d'Wëssen an d'Erfahrung fir Container ze packen an Uwendungen op Kubernetes z'installéieren.

Wann de Besoin fir zousätzlech Kapazitéit op der aler Infrastruktur entstanen ass, hu mir e puer Minutten misse waarden bis nei EC2 Instanzen gestart goufen. Elo fänken d'Container un ze lafen a fänken de Traffic bannent Sekonnen anstatt Minutten ze veraarbecht. Multiple Container op enger eenzeger EC2 Instanz ze plangen bitt och eng verbessert horizontal Konzentratioun. Als Resultat prognostéiere mir eng bedeitend Reduktioun vun den EC2019 Käschten am Joer 2 am Verglach zum leschte Joer.

D'Migratioun huet bal zwee Joer gedauert, awer mir hunn et am Mäerz 2019 ofgeschloss. De Moment leeft d'Tinder Plattform exklusiv op engem Kubernetes Cluster besteet aus 200 Servicer, 1000 Noden, 15 Pods an 000 Lafen Container. Infrastruktur ass net méi dat eenzegt Domän vun Operatiounsteams. All eis Ingenieuren deelen dës Verantwortung a kontrolléieren de Prozess fir hir Uwendungen ze bauen an z'installéieren nëmme mat Code.

PS vum Iwwersetzer

Liest och eng Serie vun Artikelen op eisem Blog:

Source: will.com

Setzt e Commentaire