Tinder umskipti yfir í Kubernetes

Athugið. þýð.: Starfsmenn hinnar heimsfrægu Tinder þjónustu deildu nýlega nokkrum tæknilegum upplýsingum um flutning innviða sinna til Kubernetes. Ferlið tók tæp tvö ár og leiddi af sér mjög stóran vettvang á K8s, sem samanstendur af 200 þjónustum sem hýstar eru á 48 þúsund gámum. Hvaða áhugaverðu erfiðleikum lentu verkfræðingar Tinder í og ​​hvaða árangri komust þeir í? Lestu þessa þýðingu.

Tinder umskipti yfir í Kubernetes

Hvers vegna?

Fyrir tæpum tveimur árum ákvað Tinder að flytja vettvang sinn til Kubernetes. Kubernetes myndi leyfa Tinder teyminu að setja í gáma og fara í framleiðslu með lágmarks fyrirhöfn í gegnum óbreytanlega uppsetningu (óbreytanleg dreifing). Í þessu tilviki væri samsetning forrita, dreifing þeirra og innviðirnir sjálfir skilgreindir með kóða.

Við vorum líka að leita að lausn á vandamálinu um sveigjanleika og stöðugleika. Þegar mælikvarði varð mikilvægur þurftum við oft að bíða í nokkrar mínútur þar til ný EC2 tilvik myndu snúast upp. Hugmyndin um að ræsa gáma og byrja að þjóna umferð á nokkrum sekúndum í stað mínútum varð mjög aðlaðandi fyrir okkur.

Ferlið reyndist erfitt. Við flutning okkar snemma árs 2019 náði Kubernetes þyrpingin mikilvægum massa og við fórum að lenda í ýmsum vandamálum vegna umferðarmagns, klasastærðar og DNS. Í leiðinni leystum við mörg áhugaverð vandamál sem tengjast flutningi 200 þjónustu og viðhalda Kubernetes klasa sem samanstendur af 1000 hnútum, 15000 belgjum og 48000 hlaupandi gámum.

Hvernig?

Síðan í janúar 2018 höfum við gengið í gegnum ýmis stig fólksflutninga. Við byrjuðum á því að setja alla þjónustu okkar í gáma og dreifa henni í Kubernetes prófskýjaumhverfi. Frá og með október byrjuðum við að flytja alla þjónustu sem fyrir er til Kubernetes. Í mars á næsta ári kláruðum við flutninginn og nú keyrir Tinder pallurinn eingöngu á Kubernetes.

Byggja myndir fyrir Kubernetes

Við höfum yfir 30 frumkóðageymslur fyrir örþjónustur sem keyra á Kubernetes klasa. Kóðinn í þessum geymslum er skrifaður á mismunandi tungumálum (til dæmis Node.js, Java, Scala, Go) með mörgum keyrsluumhverfi fyrir sama tungumál.

Byggingarkerfið er hannað til að veita fullkomlega sérhannaðar „byggjasamhengi“ fyrir hverja örþjónustu. Það samanstendur venjulega af Dockerfile og lista yfir skel skipanir. Efni þeirra er fullkomlega sérhannaðar og á sama tíma eru öll þessi byggingarsamhengi skrifuð samkvæmt stöðluðu sniði. Stöðlun byggingarsamhengis gerir einu byggingarkerfi kleift að sjá um allar örþjónustur.

Tinder umskipti yfir í Kubernetes
Mynd 1-1. Staðlað byggingarferli í gegnum Builder gám

Til að ná hámarks samræmi milli keyrslutíma (keyrsluumhverfi) sama byggingarferli er notað við þróun og prófun. Við stóðum frammi fyrir mjög áhugaverðri áskorun: við urðum að þróa leið til að tryggja samræmi í byggingarumhverfinu á öllum pallinum. Til að ná þessu fram fara öll samsetningarferli fram í sérstökum íláti. Byggir.

Innleiðing gáma hans krafðist háþróaðrar Docker tækni. Builder erfir staðbundið notendaauðkenni og leyndarmál (svo sem SSH lykil, AWS skilríki osfrv.) sem þarf til að fá aðgang að einka Tinder geymslum. Það setur upp staðbundnar möppur sem innihalda heimildir til að náttúrulega geyma byggingargripi. Þessi aðferð bætir afköst vegna þess að hún útilokar þörfina á að afrita byggingargripi á milli Builder gámsins og hýsilsins. Hægt er að endurnýta geymda smíðisgripi án viðbótarstillingar.

Fyrir sumar þjónustur þurftum við að búa til annan gám til að kortleggja söfnunarumhverfið við keyrsluumhverfið (til dæmis býr Node.js bcrypt bókasafnið til vettvangssértæka tvöfalda gripi við uppsetningu). Í samantektarferlinu geta kröfur verið mismunandi milli þjónustu og endanleg Dockerfile er safnað saman á flugi.

Kubernetes klasaarkitektúr og fólksflutningar

Stýring klasastærðar

Við ákváðum að nota kúbe-aws fyrir sjálfvirka klasadreifingu á Amazon EC2 tilvikum. Strax í upphafi virkaði allt í einum sameiginlegum hópi hnúta. Við áttum okkur fljótt á nauðsyn þess að aðgreina vinnuálag eftir stærð og gerð tilvika til að nýta tilföng á skilvirkari hátt. Rökfræðin var sú að keyrsla á nokkrum hlaðnum fjölþráðum belgjum reyndist vera fyrirsjáanlegri hvað varðar frammistöðu en sambúð þeirra við mikinn fjölda einþráða belg.

Að lokum komumst við að:

  • m5.4xstór — til eftirlits (Prometheus);
  • c5.4xstór - fyrir Node.js vinnuálag (einþráða vinnuálag);
  • c5.2xstór - fyrir Java og Go (fjölþráða vinnuálag);
  • c5.4xstór — fyrir stjórnborðið (3 hnútar).

Flutningur

Eitt af undirbúningsskrefum fyrir flutning frá gamla innviði til Kubernetes var að beina núverandi beinu samskiptum milli þjónustu yfir á nýju álagsjafnarana (Elastic Load Balancers (ELB). Þau voru búin til á ákveðnu undirneti sýndar einkaskýs (VPC). Þetta undirnet var tengt við Kubernetes VPC. Þetta gerði okkur kleift að flytja einingar smám saman, án þess að huga að sérstakri röð þjónustuháðra.

Þessir endapunktar voru búnir til með því að nota vegið sett af DNS færslum sem höfðu CNAME sem vísuðu á hvert nýtt ELB. Til að skipta yfir bættum við við nýrri færslu sem vísar á nýja ELB Kubernetes þjónustunnar með þyngdina 0. Við stilltum síðan Time To Live (TTL) færslunnar sem var stilltur á 0. Eftir þetta voru gamla og nýja lóðin aðlagast hægt og að lokum var 100% af álaginu sent á nýjan netþjón. Eftir að skiptingunni var lokið fór TTL gildið aftur á viðunandi stigi.

Java einingarnar sem við höfðum gátu ráðið við lágt TTL DNS, en Node forritin gátu það ekki. Einn verkfræðinganna endurskrifaði hluta af kóða tengingarlaugarinnar og pakkaði honum inn í stjórnanda sem uppfærði laugarnar á 60 sekúndna fresti. Valin nálgun virkaði mjög vel og án merkjanlegrar skerðingar á frammistöðu.

Kennslustundir

Takmörk netkerfisins

Snemma morguns 8. janúar 2019 hrundi Tinder pallurinn óvænt. Til að bregðast við ótengdri aukningu á biðtíma vettvangs fyrr um morguninn, fjölgaði belgjum og hnútum í þyrpingunni. Þetta olli því að ARP skyndiminni var uppurið á öllum hnútum okkar.

Það eru þrír Linux valkostir sem tengjast ARP skyndiminni:

Tinder umskipti yfir í Kubernetes
(uppspretta)

gc_thresh3 - þetta eru erfið mörk. Útlit „nágrannaborðsflæðis“ færslna í skránni þýddi að jafnvel eftir samstillta sorphirðu (GC), var ekki nóg pláss í ARP skyndiminni til að geyma nærliggjandi færslu. Í þessu tilviki fleygði kjarninn pakkanum einfaldlega alveg.

Við notum Flannel sem netkerfi í Kubernetes. Pakkar eru sendir yfir VXLAN. VXLAN eru L2 göng reist ofan á L3 net. Tæknin notar MAC-in-UDP (MAC Address-in-User Datagram Protocol) hjúpun og leyfir stækkun á Layer 2 nethlutum. Flutningssamskiptareglur á efnislegu gagnaveraneti er IP plús UDP.

Tinder umskipti yfir í Kubernetes
Mynd 2–1. Flanell skýringarmynd (uppspretta)

Tinder umskipti yfir í Kubernetes
Mynd 2-2. VXLAN pakki (uppspretta)

Hver Kubernetes vinnuhnút úthlutar sýndar heimilisfangsrými með /24 grímu úr stærri /9 blokk. Fyrir hvern hnút er þetta þýðir ein færsla í leiðartöflunni, ein færsla í ARP töfluna (á flannel.1 viðmótinu) og ein færsla í skiptitöflunni (FDB). Þeim er bætt við í fyrsta skipti sem vinnuhnútur er ræstur eða í hvert skipti sem nýr hnútur uppgötvast.

Að auki fara hnút-belgur (eða fræbelgur) samskipti að lokum í gegnum viðmótið eth0 (eins og sýnt er á flannel skýringarmyndinni hér að ofan). Þetta leiðir til viðbótarfærslu í ARP töflunni fyrir hvern samsvarandi uppruna- og áfangahýsil.

Í umhverfi okkar eru slík samskipti mjög algeng. Fyrir þjónustuhluti í Kubernetes er ELB búin til og Kubernetes skráir hvern hnút hjá ELB. ELB veit ekkert um belg og valinn hnútur gæti ekki verið lokaáfangastaður pakkans. Málið er að þegar hnútur tekur á móti pakka frá ELB, þá telur hann það taka tillit til reglna iptables fyrir tiltekna þjónustu og velur af handahófi fræbelgur á öðrum hnút.

Þegar bilunin varð voru 605 hnútar í þyrpingunni. Af framangreindum ástæðum nægði þetta til að vinna bug á þýðingunni gc_thresh3, sem er sjálfgefið. Þegar þetta gerist byrjar ekki aðeins að sleppa pökkum, heldur hverfur allt Flannel sýndarvistfangarýmið með /24 grímu úr ARP töflunni. Node-pod samskipti og DNS fyrirspurnir eru truflaðar (DNS er hýst í þyrping; lestu síðar í þessari grein til að fá nánari upplýsingar).

Til að leysa þetta vandamál þarftu að auka gildin gc_thresh1, gc_thresh2 и gc_thresh3 og endurræstu Flannel til að endurskrá þau net sem vantar.

Óvænt DNS mælikvarði

Í flutningsferlinu notuðum við virkan DNS til að stjórna umferð og flytja smám saman þjónustu frá gamla innviði til Kubernetes. Við setjum tiltölulega lág TTL gildi fyrir tengd RecordSets í Route53. Þegar gamli uppbyggingin var í gangi á EC2 tilvikum benti uppsetning lausnarans á Amazon DNS. Við tókum þetta sem sjálfsögðum hlut og áhrif lágs TTL á þjónustu okkar og Amazon þjónustu (eins og DynamoDB) fóru að mestu fram hjá okkur.

Þegar við fluttum þjónustu til Kubernetes komumst við að því að DNS var að vinna úr 250 þúsund beiðnum á sekúndu. Þess vegna fóru forrit að upplifa stöðuga og alvarlega tímamörk fyrir DNS fyrirspurnir. Þetta gerðist þrátt fyrir ótrúlega viðleitni til að fínstilla og skipta DNS-veitunni yfir í CoreDNS (sem við hámarksálag náði 1000 belg sem keyrðu á 120 kjarna).

Við rannsóknir á öðrum mögulegum orsökum og lausnum uppgötvuðum við grein, sem lýsir keppnisaðstæðum sem hafa áhrif á pakkasíuramma netsía í Linux. Tímamörkin sem við horfðum á, ásamt vaxandi teljara insert_failed í Flannel viðmótinu voru í samræmi við niðurstöður greinarinnar.

Vandamálið kemur upp á stigi uppruna- og áfangastaðanetfangsþýðingar (SNAT og DNAT) og síðari innsláttar í töfluna samband. Ein af lausnunum sem rætt var um innanhúss og lagt til af samfélaginu var að færa DNS yfir á vinnuhnútinn sjálfan. Í þessu tilfelli:

  • SNAT er ekki þörf vegna þess að umferðin er inni í hnútnum. Það þarf ekki að beina því í gegnum viðmótið eth0.
  • DNAT er ekki þörf þar sem IP áfangastaðurinn er staðbundinn við hnútinn og ekki valinn belg af handahófi samkvæmt reglunum iptables.

Við ákváðum að halda okkur við þessa nálgun. CoreDNS var notað sem DaemonSet í Kubernetes og við innleiddum staðbundinn DNS-netþjón í resolve.conf hvern belg með því að setja fána --þyrping-dns teymi kúbelet . Þessi lausn reyndist árangursrík fyrir DNS tímamörk.

Hins vegar sáum við enn pakkatap og aukningu á teljara insert_failed í Flannel viðmótinu. Þetta hélt áfram eftir að lausnin var innleidd vegna þess að við gátum útrýmt SNAT og/eða DNAT fyrir DNS umferð eingöngu. Kappakstursskilyrði voru varðveitt fyrir aðra umferð. Sem betur fer eru flestir pakkarnir okkar TCP og ef vandamál koma upp eru þeir einfaldlega endursendir. Við erum enn að reyna að finna viðeigandi lausn fyrir allar tegundir umferðar.

Notkun Envoy fyrir betri álagsjafnvægi

Þegar við fluttum bakendaþjónustu til Kubernetes, fórum við að þjást af ójafnvægi á milli belg. Við komumst að því að HTTP Keepalive olli því að ELB tengingar héngu á fyrstu tilbúnu belgjunum í hverri dreifingu sem var rúllað út. Þannig fór meginhluti umferðarinnar í gegnum lítið hlutfall af tiltækum belgjum. Fyrsta lausnin sem við prófuðum var að setja MaxSurge á 100% á nýjum dreifingum fyrir versta tilvik. Áhrifin reyndust óveruleg og óvænleg hvað varðar stærri útfærslur.

Önnur lausn sem við notuðum var að auka tilbúnar beiðnir um auðlindir fyrir mikilvæga þjónustu. Í þessu tilviki myndu belg sem eru settir nálægt hafa meira svigrúm til að hreyfa sig samanborið við aðra þunga belg. Það myndi heldur ekki virka til lengri tíma litið því það væri sóun á auðlindum. Að auki voru Node forritin okkar einþráður og gátu því aðeins notað einn kjarna. Eina raunverulega lausnin var að nota betri álagsjafnvægi.

Við höfum lengi langað til að meta að fullu Sendiherra. Núverandi ástand gerði okkur kleift að beita því á mjög takmarkaðan hátt og fá niðurstöður strax. Envoy er afkastamikið, opinn uppspretta, lag-XNUMX umboð hannað fyrir stór SOA forrit. Það getur innleitt háþróaða álagsjöfnunartækni, þar á meðal sjálfvirkar tilraunir, aflrofar og alþjóðlega hraðatakmörkun. (Athugið. þýð.: Þú getur lesið meira um þetta í Þessi grein um Istio, sem er byggt á Envoy.)

Við komumst með eftirfarandi uppsetningu: hafa sendiboða hliðarvagn fyrir hvern belg og eina leið og tengdu þyrpinguna við gáminn á staðnum í gegnum höfn. Til að lágmarka hugsanlega straumhvörf og viðhalda litlum höggradíus, notuðum við flota sendiboða í fremstu röð, einn fyrir hvert framboðssvæði (AZ) fyrir hverja þjónustu. Þeir treystu á einfalda þjónustuuppgötvunarvél skrifuð af einum af verkfræðingum okkar sem skilaði einfaldlega lista yfir belg í hverju AZ fyrir tiltekna þjónustu.

Þjónustuframboðsmenn notuðu síðan þessa þjónustuuppgötvunarkerfi með einum andstreymisþyrpingum og leið. Við stilltum fullnægjandi tímamörk, hækkuðum allar stillingar aflrofa og bættum við lágmarksstillingum fyrir endurreynslu til að hjálpa við stakar bilanir og tryggja hnökralausa uppsetningu. Við settum TCP ELB fyrir framan hvern af þessum þjónustuframboðum. Jafnvel þó að keepalive frá aðal proxy-laginu okkar væri fastur á sumum Envoy belgjum, þá gátu þeir samt höndlað álagið miklu betur og voru stilltir til að halda jafnvægi í gegnum least_request í bakendanum.

Til að dreifa, notuðum við preStop krókinn á bæði notkunarbelg og hliðarvagna. Krókurinn kveikti villu við að athuga stöðu stjórnendaendastaðar sem staðsettur er á hliðarvagnsílátinu og fór að sofa um stund til að leyfa virkum tengingum að hætta.

Ein af ástæðunum fyrir því að við gátum hreyft okkur svo hratt er vegna nákvæmra mælikvarða sem við gátum auðveldlega fellt inn í dæmigerða Prometheus uppsetningu. Þetta gerði okkur kleift að sjá nákvæmlega hvað var að gerast á meðan við breyttum stillingarbreytum og endurdreifðum umferð.

Niðurstöðurnar voru strax og augljósar. Við byrjuðum á ójafnvægustu þjónustunni og í augnablikinu starfar hún fyrir framan 12 mikilvægustu þjónustuna í klasanum. Á þessu ári erum við að skipuleggja umskipti yfir í heildarþjónustunet með fullkomnari þjónustuuppgötvun, rafrásarrof, fráviksgreiningu, hraðatakmörkun og rakningu.

Tinder umskipti yfir í Kubernetes
Mynd 3–1. CPU samleitni einnar þjónustu við umskipti yfir í Envoy

Tinder umskipti yfir í Kubernetes

Tinder umskipti yfir í Kubernetes

Lokaniðurstaða

Í gegnum þessa reynslu og viðbótarrannsóknir höfum við byggt upp öflugt innviðateymi með sterka færni í að hanna, dreifa og reka stóra Kubernetes klasa. Allir verkfræðingar Tinder hafa nú þekkingu og reynslu til að pakka gámum og dreifa forritum á Kubernetes.

Þegar þörfin fyrir viðbótargetu kom upp á gamla innviðina þurftum við að bíða í nokkrar mínútur eftir að ný EC2 tilvik kæmu í notkun. Nú byrja gámar að keyra og byrja að vinna úr umferð innan nokkurra sekúndna í stað mínútna. Að skipuleggja marga ílát á einu EC2 tilviki veitir einnig betri lárétta styrk. Fyrir vikið spáum við umtalsverðri lækkun á EC2019 kostnaði árið 2 miðað við síðasta ár.

Flutningurinn tók tæp tvö ár en við kláruðum hana í mars 2019. Eins og er, keyrir Tinder pallurinn eingöngu á Kubernetes klasa sem samanstendur af 200 þjónustum, 1000 hnútum, 15 belgjum og 000 hlaupandi gámum. Innviðir eru ekki lengur einir svið rekstrarteyma. Allir verkfræðingar okkar deila þessari ábyrgð og stjórna ferlinu við að smíða og dreifa forritum sínum með því að nota eingöngu kóða.

PS frá þýðanda

Lestu líka röð greina á blogginu okkar:

Heimild: www.habr.com

Bæta við athugasemd