Tinder Kubernetesera trantsizioa

Ohar. itzul.: Mundu osoko Tinder zerbitzu ospetsuko langileek duela gutxi euren azpiegitura Kubernetesera migratzeko xehetasun tekniko batzuk partekatu dituzte. Prozesuak ia bi urte iraun zuen eta K8etan eskala handiko plataforma bat abian jarri zen, 200 mila edukiontzitan ostatatutako 48 zerbitzuz osatua. Zein zailtasun interesgarri aurkitu zituzten Tinder-eko ingeniariek eta zein emaitza lortu zituzten?Irakurri itzulpen hau.

Tinder Kubernetesera trantsizioa

Zergatik?

Duela ia bi urte, Tinder-ek bere plataforma Kubernetesera eramatea erabaki zuen. Kubernetes-ek Tinder taldeari edukiontziak edukitzea eta produkziora pasatzea ahalbidetuko luke esfortzu minimoarekin inplementazio aldaezinaren bidez (inplementazio aldaezina). Kasu honetan, aplikazioen muntaia, haien hedapena eta azpiegitura bera kodearen bidez definituko lirateke.

Eskalagarritasunaren eta egonkortasunaren arazoari ere irtenbide bat bilatzen ari ginen. Eskalatzea kritiko bihurtu zenean, askotan minutu batzuk itxaron behar izan genituen EC2 instantzia berriak abiarazteko. Ontziak abiarazi eta trafikoa minututan beharrean segundotan zerbitzatzen hastea oso erakargarria egin zitzaigun.

Prozesua zaila izan zen. 2019 hasieran egin genuen migrazioan, Kubernetes klusterrak masa kritikoa lortu zuen eta hainbat arazo aurkitzen hasi ginen trafiko-bolumenaren, klusterren tamainaren eta DNSren ondorioz. Bide horretan, 200 zerbitzu migratzearekin eta 1000 nodoz, 15000 podez eta martxan dauden 48000 edukiontziz osatutako Kubernetes kluster bat mantentzearekin lotutako arazo interesgarri asko konpondu genituen.

Nola?

2018ko urtarriletik aurrera, migrazioaren hainbat fase igaro ditugu. Gure zerbitzu guztiak edukiontzietan jarri eta Kubernetes probako hodeiko inguruneetan zabaltzen hasi ginen. Urrian hasita, lehendik zeuden zerbitzu guztiak Kubernetesera metodikoki migratzen hasi ginen. Hurrengo urteko martxorako, migrazioa amaitu genuen eta orain Tinder plataforma Kubernetes-en bakarrik exekutatzen da.

Kubernetesentzako irudiak eraikitzen

Kubernetes kluster batean exekutatzen diren mikrozerbitzuetarako 30 iturburu-kode biltegi baino gehiago ditugu. Biltegi horietako kodea hizkuntza desberdinetan idatzita dago (adibidez, Node.js, Java, Scala, Go) hizkuntza bererako exekuzio-ingurune anitzekin.

Eraikuntza-sistema mikrozerbitzu bakoitzerako "eraikitze-testuingurua" guztiz pertsonalizagarria eskaintzeko diseinatuta dago. Normalean Dockerfile bat eta shell komandoen zerrendaz osatuta dago. Euren edukia guztiz pertsonalizagarria da, eta, aldi berean, eraikuntza-testuinguru hauek guztiak formatu estandarizatu baten arabera idazten dira. Eraikuntza-testuinguruak estandarizatzeari esker, eraikuntza-sistema bakar batek mikrozerbitzu guztiak kudeatzen ditu.

Tinder Kubernetesera trantsizioa
1-1 irudia. Eraikitze-prozesu estandarizatua Builder edukiontziaren bidez

Exekuzio-denboren arteko koherentzia handiena lortzeko (exekuzio-inguruneak) eraikuntza-prozesu bera erabiltzen da garapenean eta probetan. Oso erronka interesgarri bati aurre egin genion: plataforma osoan eraikitzeko ingurunearen koherentzia bermatzeko modu bat garatu behar genuen. Hori lortzeko, muntaketa prozesu guztiak edukiontzi berezi baten barruan egiten dira. Eraikitzailea.

Bere edukiontzien ezarpenak Docker teknika aurreratuak behar zituen. Builder-ek Tinder biltegi pribatuetara sartzeko beharrezkoak diren erabiltzailearen ID lokala eta sekretuak (adibidez, SSH gakoa, AWS kredentzialak, etab.) heredatzen ditu. Iturburuak dituzten tokiko direktorioak muntatzen ditu eraikuntzako artefaktuak modu naturalean gordetzeko. Ikuspegi honek errendimendua hobetzen du, Builder edukiontziaren eta ostalariaren artean eraikitze-artefaktuak kopiatzeko beharra ezabatzen duelako. Biltegiratutako eraikuntza-artefaktuak konfigurazio gehigarririk gabe berrerabili daitezke.

Zenbait zerbitzutarako, beste edukiontzi bat sortu behar izan dugu konpilazio-ingurunea exekuzio-ingurunearekin mapatzeko (adibidez, Node.js bcrypt liburutegiak plataformarako berariazko artefaktu bitar sortzen ditu instalazioan). Konpilazio prozesuan, eskakizunak zerbitzuen artean alda daitezke, eta azken Dockerfile bat-batean biltzen da.

Kubernetes kluster arkitektura eta migrazioa

Klusterraren tamainaren kudeaketa

erabiltzea erabaki dugu kube-aws Amazon EC2 instantzietan kluster inplementazio automatizaturako. Hasieran, dena nodo multzo komun batean funtzionatu zuen. Azkar konturatu ginen lan-kargak tamainaren eta instantzia-motaren arabera bereizi beharra zegoela baliabideen erabilera eraginkorrago egiteko. Logika zen hari anitzeko kargatutako hainbat pod exekutatzen errendimendu aldetik aurreikusgarriagoa izan zela hari bakarreko pod kopuru handi batekin elkarbizitza baino.

Azkenean, honako hau finkatu genuen:

  • m5.4xhandia β€” monitorizaziorako (Prometheus);
  • c5.4xhandia - Node.js lan-kargarako (hari bakarreko lan-karga);
  • c5.2xhandia - Java eta Gorako (hari anitzeko lan-karga);
  • c5.4xhandia β€” kontrol panelerako (3 nodo).

Migrazioa

Azpiegitura zaharretik Kubernetesera migratzeko prestaketa-urratsetako bat zerbitzuen arteko zuzeneko komunikazioa karga-orekatzaile berrietara birbideratzea izan zen (ELB). Hodei pribatu birtual baten (VPC) azpisare zehatz batean sortu ziren. Azpisare hau Kubernetes VPC batera konektatuta zegoen. Honek moduluak pixkanaka migratzeko aukera eman zigun, zerbitzuen mendekotasunen ordena zehatza kontuan hartu gabe.

Amaiera-puntu hauek ELB berri bakoitzari seinalatzen duten CNAMEak zituzten DNS erregistroen multzo haztatuen bidez sortu ziren. Aldatzeko, Kubernetes zerbitzuko ELB berrira seinalatzen duen sarrera berri bat gehitu dugu 0 pisuarekin. Ondoren, ezarrita dagoen sarreraren Time To Live (TTL) 0-n ezarri dugu. Horren ondoren, pisu zaharrak eta berriak izan ziren. poliki-poliki egokitu zen, eta azkenean kargaren % 100 zerbitzari berri batera bidali zen. Aldaketa amaitu ondoren, TTL balioa maila egokiago batera itzuli zen.

Geuk genituen Java moduluek TTL DNS baxuei aurre egin ziezaieketen, baina Node aplikazioek ezin. Ingeniarietako batek konexio-igerilekuaren kodearen zati bat berridatzi zuen eta igerilekuak 60 segundoro eguneratzen zituen kudeatzaile batean bildu zuen. Aukeratutako ikuspegiak oso ondo funtzionatu zuen eta errendimenduaren degradazio nabarmenik gabe.

Ikasgaiak

Sare-ehunaren mugak

8ko urtarrilaren 2019ko goizaldean, Tinder plataformak ustekabean erori zen. Goizean goiz hartan plataformako latentziaren zerikusirik ez duen igoerari erantzunez, klusterreko lekak eta nodo kopuruak gora egin zuen. Honek gure nodo guztietan ARP cachea agortzea eragin zuen.

Hiru Linux aukera daude ARP cachearekin lotuta:

Tinder Kubernetesera trantsizioa
(iturri)

gc_thresh3 - Hau muga gogorra da. Erregistroan "neighbor table overflow" sarrerak agertzeak esan nahi zuen zabor-bilketa sinkronikoa (GC) egin ondoren ere, ez zegoela ARP cachean aldameneko sarrera gordetzeko behar adina leku. Kasu honetan, nukleoak paketea guztiz baztertu zuen.

Erabiltzen dugu flannel Kubernetes-en sare-ehun gisa. Paketeak VXLAN bidez transmititzen dira. VXLAN L2 sare baten gainean altxatutako L3 tunel bat da. Teknologiak MAC-in-UDP (MAC Address-in-User Datagram Protocol) enkapsulazioa erabiltzen du eta Layer 2 sareko segmentuak hedatzea ahalbidetzen du. Datu zentro fisikoen sareko garraio-protokoloa IP gehi UDP da.

Tinder Kubernetesera trantsizioa
2-1 irudia. Flanela diagrama (iturri)

Tinder Kubernetesera trantsizioa
2-2 irudia. VXLAN paketea (iturri)

Kubernetes-eko langile-nodo bakoitzak helbide birtual bat esleitzen du /24 maskara batekin /9 bloke handiago batetik. Nodo bakoitzeko hau da esan nahi du sarrera bat bideratze-taulan, sarrera bat ARP taulan (flanel.1 interfazean) eta sarrera bat kommutazio-taulan (FDB). Langile-nodo bat abiarazten den lehen aldian edo nodo berri bat aurkitzen den bakoitzean gehitzen dira.

Gainera, nodo-pod (edo pod-pod) komunikazioa azken finean interfazearen bidez doa eth0 (Goiko Flannel diagraman erakusten den bezala). Honek ARP taulan sarrera gehigarri bat sortzen du dagokion iturri eta helmuga ostalari bakoitzeko.

Gure ingurunean, komunikazio mota hau oso ohikoa da. Kubernetes-eko zerbitzu-objektuetarako, ELB bat sortzen da eta Kubernetes-ek nodo bakoitza ELBrekin erregistratzen du. ELBk ez daki ezer podi buruz eta baliteke aukeratutako nodoa ez izatea paketearen azken helmuga. Kontua da nodo batek ELBtik pakete bat jasotzen duenean, arauak kontuan hartuta hartzen duela kontuan iptables zerbitzu zehatz baterako eta ausaz aukeratzen du pod bat beste nodo batean.

Porrotaren unean, klusterrean 605 nodo zeuden. Goian esandako arrazoiengatik, nahikoa izan da hori garrantzia gainditzeko gc_thresh3, lehenetsia dena. Hori gertatzen denean, paketeak botatzen hasten ez ezik, /24 maskara duen Flannel helbide birtual osoa desagertzen da ARP taulatik. Nodo-pod komunikazioa eta DNS kontsultak eten egiten dira (DNS kluster batean dago ostatatuta; irakurri artikulu honetan geroago xehetasunetarako).

Arazo hau konpontzeko, balioak handitu behar dituzu gc_thresh1, gc_thresh2 ΠΈ gc_thresh3 eta berrabiarazi Flannel falta diren sareak berriro erregistratzeko.

Ustekabeko DNS eskalatzea

Migrazio prozesuan, DNS aktiboki erabili dugu trafikoa kudeatzeko eta pixkanaka azpiegitura zaharretik Kubernetesera zerbitzuak transferitzeko. Route53-n erlazionatutako RecordSets-etarako TTL balio nahiko baxuak ezarri ditugu. Azpiegitura zaharra EC2 instantzietan exekutatzen ari zenean, gure ebazteko konfigurazioak Amazon DNSra seinalatzen zuen. Hori gauzatzat hartu genuen eta TTL baxuaren eragina gure zerbitzuetan eta Amazon zerbitzuetan (adibidez, DynamoDB) oharkabean pasatu zen.

Zerbitzuak Kubernetesera migratu ahala, DNS segundoko 250 mila eskaera prozesatzen ari zela ikusi genuen. Ondorioz, aplikazioek DNS kontsultetarako denbora-muga etengabe eta larriak izaten hasi ziren. DNS hornitzailea CoreDNS-ra optimizatzeko eta aldatzeko ahalegin izugarriak egin arren gertatu zen (karga gorenean 1000 nukleotan exekutatzen ziren 120 podsetara iritsi zen).

Beste arrazoi eta irtenbide posible batzuk ikertzen ari ginen bitartean, aurkitu genuen artikulu bat, paketeak iragazteko esparruari eragiten dioten lasterketa-baldintzak deskribatuz netfilter Linux-en. Behatu ditugun denbora-mugeak, gero eta kontagailu handiagoarekin batera txertatu_huts egin Flannel interfazean artikuluko aurkikuntzekin bat datoz.

Arazoa Iturburuko eta Helmugako Sareko Helbideen Itzulpenaren (SNAT eta DNAT) eta ondorengo taulan sartzean gertatzen da. kontrajarri. Barruan eztabaidatu eta komunitateak iradokitako konponbideetako bat DNS langile-nodora eramatea izan zen. Kasu honetan:

  • SNAT ez da beharrezkoa trafikoa nodoaren barruan geratzen delako. Ez da interfazearen bidez bideratu behar eth0.
  • DNAT ez da beharrezkoa helmuga IP nodoaren lokala baita, eta ez ausaz hautatutako pod bat arauen arabera. iptables.

Ikuspegi honekin jarraitzea erabaki genuen. CoreDNS DaemonSet gisa zabaldu zen Kubernetes-en eta tokiko nodoen DNS zerbitzari bat inplementatu genuen. ebatzi.konf leka bakoitza bandera bat ezarriz --cluster-dns komandoak kubeletβ€Š. Irtenbide hau eraginkorra izan da DNS denbora-mugarako.

Hala ere, oraindik paketeen galera eta kontagailua handitzea ikusi genuen txertatu_huts egin Flannel interfazean. Honek konponbidea inplementatu ondoren jarraitu zuen SNAT eta/edo DNAT DNS trafikorako soilik ezabatu ahal izan genituelako. Lasterketa-baldintzak beste trafiko mota batzuetarako gorde ziren. Zorionez, gure pakete gehienak TCP dira, eta arazoren bat gertatzen bada, berriro igortzen dira. Trafiko mota guztietarako irtenbide egoki bat bilatzen saiatzen ari gara oraindik.

Envoy erabiliz karga orekatzeko

Backend zerbitzuak Kubernetesera migratu ahala, poden arteko karga desorekatua jasaten hasi ginen. Aurkitu dugu HTTP Keepalive-k ELB konexioak zintzilikatu zituela zabaldutako inplementazio bakoitzaren lehen gailu prestetan. Horrela, trafikoaren zatirik handiena erabilgarri dauden poden ehuneko txiki batetik igaro zen. Probatu genuen lehen irtenbidea MaxSurge % 100ean ezartzea izan zen inplementazio berrietan kasu txarrenetarako. Efektua hutsala eta itxaropentsua izan zen hedapen handiagoei dagokienez.

Erabili genuen beste irtenbide bat zerbitzu kritikoetarako baliabide-eskaerak artifizialki handitzea izan zen. Kasu honetan, ondoan jarritako lekak maniobratzeko tarte gehiago izango lukete beste lekak astunekin alderatuta. Epe luzera ere ez luke balioko, baliabideak xahutzea litzatekeelako. Horrez gain, gure Node aplikazioak hari bakarrekoak ziren eta, horren arabera, nukleo bakarra erabil zezaketen. Benetako irtenbide bakarra karga orekatze hobea erabiltzea zen.

Aspalditik guztiz estimatu nahi genuen Jesukristo. Egungo egoerak oso modu mugatuan zabaldu eta berehalako emaitzak lortzeko aukera eman digu. Envoy errendimendu handiko, kode irekiko, XNUMX geruzako proxy bat da, SOA aplikazio handietarako diseinatua. Karga orekatzeko teknika aurreratuak ezar ditzake, berriro saiakuntza automatikoak, etengailuak eta tasa-muga globala barne. (Ohar. itzul.: Honi buruz gehiago irakur dezakezu hemen Artikulu honetan Istio-ri buruz, Envoy-en oinarritutakoa.)

Konfigurazio hau sortu genuen: Envoy sidecar bat eduki ontzi bakoitzeko eta ibilbide bakar bat, eta klusterra edukiontziarekin konektatu lokalean portu bidez. Kaskada potentziala minimizatzeko eta arrakasta-erradio txiki bat mantentzeko, Envoy front-proxy pod-en flota bat erabili dugu, zerbitzu bakoitzeko Erabilgarritasun Zona bakoitzeko (AZ). Gure ingeniari batek idatzitako zerbitzu-aurkikuntza-motor sinple batean oinarritzen ziren, zerbitzu jakin baterako AZ bakoitzean leka-zerrenda bat besterik gabe itzultzen zuena.

Zerbitzuaren aurrean-Envoys-ek zerbitzuaren aurkikuntza-mekanismo hau erabili zuten upstream kluster eta ibilbide batekin. Denbora-muga egokiak ezarri ditugu, etengailuen ezarpen guztiak handitu ditugu eta gutxieneko saiakera-konfigurazioa gehitu dugu hutsegite bakarrean laguntzeko eta inplementazio egokiak bermatzeko. TCP ELB bat jarri genuen zerbitzu-frontal-Envoys horietako bakoitzaren aurrean. Gure proxy geruza nagusiko keepalive Envoy pod batzuetan itsatsita egon bazen ere, karga askoz hobeto kudeatzeko gai izan ziren eta backend-eko minimum_request bidez orekatzeko konfiguratuta zeuden.

Inplementatzeko, preStop amua erabili dugu aplikazio-podetan eta sidecar-en kakoetan. Amuak errore bat eragin du sidecar-eko edukiontzian kokatutako administratzailearen amaiera-puntuaren egoera egiaztatzean eta pixka bat lo egin zuen konexio aktiboak amai zezaten.

Hain azkar mugitzeko gai izan ginen arrazoietako bat Prometheus instalazio tipiko batean erraz integratzeko gai izan ginen neurketa zehatzak direla eta. Honi esker, zehazki zer gertatzen ari zen ikusi ahal izan genuen konfigurazio-parametroak doitzen genituen bitartean eta trafikoa birbanatzen genuen bitartean.

Emaitzak berehalakoak eta agerikoak izan ziren. Zerbitzu desorekatuenekin hasi ginen, eta momentuz klusterreko 12 zerbitzu garrantzitsuenen aurrean jarduten du. Aurten zerbitzu osoko sare baterako trantsizioa planifikatzen ari gara, zerbitzuen aurkikuntza aurreratuagoarekin, zirkuitu-hausturarekin, kanpoan detektatzeko, tasa mugatzeko eta trazatzeko.

Tinder Kubernetesera trantsizioa
3-1 irudia. Zerbitzu baten CPU konbergentzia Envoy-era igarotzean

Tinder Kubernetesera trantsizioa

Tinder Kubernetesera trantsizioa

Azken emaitza

Esperientzia honen eta ikerketa gehigarrien bidez, azpiegitura talde sendo bat eraiki dugu, Kubernetes kluster handiak diseinatzeko, inplementatzeko eta ustiatzeko trebetasun sendoak dituena. Tinder ingeniari guztiek edukiontziak paketatzeko eta aplikazioak Kubernetesen inplementatzeko ezagutza eta esperientzia dute orain.

Azpiegitura zaharrean gaitasun gehigarriaren beharra sortu zenean, zenbait minutu itxaron behar izan genuen EC2 instantzia berriak abiarazteko. Orain edukiontziak martxan hasten dira eta trafikoa prozesatzen hasten dira segundotan minututan beharrean. EC2 instantzia bakarrean hainbat edukiontzi programatzeak kontzentrazio horizontala hobetzen du. Ondorioz, 2019an EC2 kostuen murrizketa nabarmena aurreikusten dugu iazkoarekin alderatuta.

Migrazioak ia bi urte behar izan zituen, baina 2019ko martxoan amaitu genuen. Gaur egun, Tinder plataforma 200 zerbitzuz, 1000 nodoz, 15 pod eta 000 edukiontziz osatutako Kubernetes kluster batean exekutatzen da soilik. Azpiegitura jada ez da operazio-taldeen eremu bakarra. Gure ingeniari guztiek erantzukizun hori partekatzen dute eta beren aplikazioak eraikitzeko eta inplementatzeko prozesua kontrolatzen dute kodea erabiliz soilik.

PS itzultzailetik

Irakurri ere gure blogean artikulu sorta bat:

Iturria: www.habr.com

Gehitu iruzkin berria