āKubernetes palielinÄja latentumu 10 reizesā: kurÅ” pie tÄ ir vainÄ«gs?
PiezÄ«me. tulk.: Å is raksts, ko uzrakstÄ«jis Galo Navarro, kurÅ” ieÅem galvenÄ programmatÅ«ras inženiera amatu Eiropas uzÅÄmumÄ Adevinta, ir aizraujoÅ”a un pamÄcoÅ”a āizpÄteā infrastruktÅ«ras darbÄ«bas jomÄ. TÄ oriÄ£inÄlais nosaukums ir nedaudz paplaÅ”inÄts tulkojumÄ iemesla dÄļ, ko autors paskaidro paÅ”Ä sÄkumÄ.
PiezÄ«me no autora: IzskatÄs pÄc Ŕīs ziÅas piesaistÄ«ja daudz vairÄk uzmanÄ«bas, nekÄ gaidÄ«ts. JoprojÄm saÅemu dusmÄ«gus komentÄrus, ka raksta nosaukums ir maldinoÅ”s un daži lasÄ«tÄji ir apbÄdinÄti. Es saprotu notiekoÅ”Ä iemeslus, tÄpÄc, neskatoties uz risku sabojÄt visu intrigu, es vÄlos jums nekavÄjoties pastÄstÄ«t, par ko ir Å”is raksts. Interesanta lieta, ko esmu redzÄjis, komandÄm migrÄjot uz Kubernetes, ir tas, ka ikreiz, kad rodas problÄma (piemÄram, palielinÄts latentums pÄc migrÄcijas), pirmÄ lieta, kas tiek vainota, ir Kubernetes, bet tad izrÄdÄs, ka orÄ·estra vadÄ«tÄjs nav Ä«sti vainot. Å is raksts stÄsta par vienu Å”Ädu gadÄ«jumu. TÄs nosaukums atkÄrto viena mÅ«su izstrÄdÄtÄja izsaukumu (vÄlÄk jÅ«s redzÄsiet, ka Kubernetes ar to nav nekÄda sakara). Å eit jÅ«s neatradÄ«sit pÄrsteidzoÅ”as atklÄsmes par Kubernetes, taÄu jÅ«s varat sagaidÄ«t pÄris labas nodarbÄ«bas par sarežģītÄm sistÄmÄm.
Pirms pÄris nedÄļÄm mana komanda migrÄja vienu mikropakalpojumu uz pamata platformu, kas ietvÄra CI/CD, uz Kubernetes balstÄ«tu izpildlaiku, metriku un citus labumus. PÄrcelÅ”anÄs bija izmÄÄ£inÄjuma raksturs: plÄnojÄm to Åemt par pamatu un tuvÄko mÄneÅ”u laikÄ nodot vÄl aptuveni 150 pakalpojumus. ViÅi visi ir atbildÄ«gi par dažu lielÄko tieÅ”saistes platformu darbÄ«bu SpÄnijÄ (Infojobs, Fotocasa utt.).
PÄc tam, kad mÄs izvietojÄm lietojumprogrammu Kubernetes un novirzÄ«jÄm uz to daļu trafika, mÅ«s gaidÄ«ja satraucoÅ”s pÄrsteigums. KavÄÅ”anÄs (latents) pieprasÄ«jumu skaits Kubernetes bija 10 reizes lielÄks nekÄ EC2. KopumÄ bija nepiecieÅ”ams vai nu rast risinÄjumu Å”ai problÄmai, vai arÄ« atteikties no mikropakalpojuma (un, iespÄjams, arÄ« visa projekta) migrÄcijas.
KÄpÄc Kubernetes latentums ir tik daudz lielÄks nekÄ EC2?
Lai atrastu vÄjo vietu, mÄs apkopojÄm metriku visÄ pieprasÄ«juma ceļÄ. MÅ«su arhitektÅ«ra ir vienkÄrÅ”a: API vÄrteja (Zuul) nosÅ«ta pieprasÄ«jumus mikropakalpojumu gadÄ«jumiem EC2 vai Kubernetes. ProgrammÄ Kubernetes mÄs izmantojam NGINX ieejas kontrolieri, un aizmugursistÄmas ir parasti objekti, piemÄram IzvietoÅ”anas ar JVM lietojumprogrammu Spring platformÄ.
Å Ä·iet, ka problÄma ir saistÄ«ta ar sÄkotnÄjo latentumu aizmugursistÄmÄ (problÄmas apgabalu grafikÄ atzÄ«mÄju kÄ "xx"). EC2 lietojumprogrammas atbilde aizÅÄma aptuveni 20 ms. Kubernetes latentums palielinÄjÄs lÄ«dz 100-200 ms.
MÄs Ätri noraidÄ«jÄm iespÄjamÄs aizdomÄs turamÄs personas, kas bija saistÄ«tas ar izpildlaika maiÅu. JVM versija paliek nemainÄ«ga. ArÄ« konteineru ievietoÅ”anas problÄmÄm ar to nebija nekÄda sakara: lietojumprogramma jau veiksmÄ«gi darbojÄs EC2 konteineros. Vai tiek ielÄdÄts? Bet mÄs novÄrojÄm augstu latentumu pat ar 1 pieprasÄ«jumu sekundÄ. VarÄtu atstÄt novÄrtÄ arÄ« atkritumu savÄkÅ”anas pauzes.
Viens no mÅ«su Kubernetes administratoriem jautÄja, vai lietojumprogrammai nav ÄrÄjas atkarÄ«bas, jo DNS vaicÄjumi iepriekÅ” bija radÄ«juÅ”i lÄ«dzÄ«gas problÄmas.
1. hipotÄze: DNS nosaukuma izŔķirÅ”ana
Katram pieprasÄ«jumam mÅ«su lietojumprogramma vienu lÄ«dz trÄ«s reizes piekļūst AWS Elasticsearch instancei tÄdÄ domÄnÄ kÄ elastic.spain.adevinta.com. MÅ«su konteineros ir Äaula, lai mÄs varÄtu pÄrbaudÄ«t, vai domÄna meklÄÅ”ana patieÅ”Äm aizÅem ilgu laiku.
Å emot vÄrÄ, ka uzmeklÄÅ”ana ilga aptuveni 30 ms, kļuva skaidrs, ka DNS izŔķirtspÄja, piekļūstot Elasticsearch, patieÅ”Äm veicinÄja latentuma palielinÄÅ”anos.
TomÄr tas bija dÄ«vaini divu iemeslu dÄļ:
Mums jau ir daudz Kubernetes lietojumprogrammu, kas mijiedarbojas ar AWS resursiem, necieÅ”ot no liela latentuma. Lai kÄds bÅ«tu iemesls, tas attiecas tieÅ”i uz Å”o gadÄ«jumu.
MÄs zinÄm, ka JVM veic DNS keÅ”atmiÅu atmiÅÄ. MÅ«su attÄlos TTL vÄrtÄ«ba ir ierakstÄ«ta $JAVA_HOME/jre/lib/security/java.security un iestatiet uz 10 sekundÄm: networkaddress.cache.ttl = 10. Citiem vÄrdiem sakot, JVM ir jÄsaglabÄ keÅ”atmiÅÄ visi DNS vaicÄjumi 10 sekundes.
Lai apstiprinÄtu pirmo hipotÄzi, mÄs nolÄmÄm kÄdu laiku pÄrtraukt DNS izsaukÅ”anu un pÄrbaudÄ«t, vai problÄma ir pazudusi. PirmkÄrt, mÄs nolÄmÄm pÄrkonfigurÄt lietojumprogrammu, lai tÄ tieÅ”i sazinÄtos ar Elasticsearch pÄc IP adreses, nevis ar domÄna nosaukumu. Tam bÅ«tu nepiecieÅ”amas koda izmaiÅas un jauna izvietoÅ”ana, tÄpÄc mÄs vienkÄrÅ”i kartÄjÄm domÄnu ar tÄ IP adresi /etc/hosts:
34.55.5.111 elastic.spain.adevinta.com
Tagad konteiners gandrÄ«z uzreiz saÅÄma IP. Tas radÄ«ja nelielus uzlabojumus, taÄu mÄs bijÄm tikai nedaudz tuvÄk paredzamajiem latentuma lÄ«meÅiem. Lai gan DNS atrisinÄÅ”ana prasÄ«ja ilgu laiku, patiesais iemesls mums joprojÄm nav izdevies.
Diagnostika caur tīklu
MÄs nolÄmÄm analizÄt trafiku no konteinera, izmantojot tcpdumplai redzÄtu, kas tieÅ”i notiek tÄ«klÄ:
[root@be-851c76f696-alf8z /]# tcpdump -leni any -w capture.pcap
PÄc tam mÄs nosÅ«tÄ«jÄm vairÄkus pieprasÄ«jumus un lejupielÄdÄjÄm to tverÅ”anu (kubectl cp my-service:/capture.pcap capture.pcap), lai veiktu turpmÄku analÄ«zi Wireshark.
DNS vaicÄjumos nebija nekÄ aizdomÄ«ga (izÅemot vienu sÄ«kumu, par kuru es runÄÅ”u vÄlÄk). TaÄu bija dažas dÄ«vainÄ«bas, kÄ mÅ«su dienests apstrÄdÄja katru pieprasÄ«jumu. TÄlÄk ir redzams tverÅ”anas ekrÄnuzÅÄmums, kurÄ redzams, ka pieprasÄ«jums tiek pieÅemts pirms atbildes sÄkÅ”anas:
Iepakojuma numuri ir parÄdÄ«ti pirmajÄ kolonnÄ. SkaidrÄ«bas labad dažÄdÄs TCP straumes esmu kodÄjis ar krÄsÄm.
ZaÄ¼Ä straume, kas sÄkas ar paketi 328, parÄda, kÄ klients (172.17.22.150) izveidoja TCP savienojumu ar konteineru (172.17.36.147). PÄc sÄkotnÄjÄs rokasspiediena (328-330) atnesa iepakojumu 331 HTTP GET /v1/.. ā mÅ«su dienestam ienÄkoÅ”s pieprasÄ«jums. Viss process aizÅÄma 1 ms.
PelÄkÄ straume (no 339. paketes) parÄda, ka mÅ«su pakalpojums nosÅ«tÄ«ja HTTP pieprasÄ«jumu Elasticsearch instancei (nav TCP rokasspiediena, jo tiek izmantots esoÅ”s savienojums). Tas aizÅÄma 18 ms.
PagaidÄm viss ir kÄrtÄ«bÄ, un laiki aptuveni atbilst paredzamajiem kavÄjumiem (20-30 ms, mÄrot no klienta).
TomÄr zilÄ sadaļa aizÅem 86 ms. Kas tajÄ notiek? Izmantojot paketi 333, mÅ«su pakalpojums nosÅ«tÄ«ja HTTP GET pieprasÄ«jumu uz /latest/meta-data/iam/security-credentials, un tÅ«lÄ«t pÄc tÄ, izmantojot to paÅ”u TCP savienojumu, vÄl viens GET pieprasÄ«jums /latest/meta-data/iam/security-credentials/arn:...
MÄs atklÄjÄm, ka tas atkÄrtojas ar katru pieprasÄ«jumu visÄ trasÄ. DNS izŔķirtspÄja mÅ«su konteineros patieÅ”Äm ir nedaudz lÄnÄka (skaidrojums Å”ai parÄdÄ«bai ir diezgan interesants, bet es to saglabÄÅ”u atseviŔķam rakstam). IzrÄdÄ«jÄs, ka ilgÄs kavÄÅ”anÄs iemesls bija zvani uz AWS instances metadatu pakalpojumu pÄc katra pieprasÄ«juma.
2. hipotÄze: nevajadzÄ«gi izsaukumi uz AWS
Abi galapunkti pieder AWS instances metadatu API. MÅ«su mikropakalpojums izmanto Å”o pakalpojumu Elasticsearch darbÄ«bas laikÄ. Abi zvani ir daļa no pamata autorizÄcijas procesa. Galapunkts, kuram tiek piekļūts pÄc pirmÄ pieprasÄ«juma, izdod ar instanci saistÄ«to IAM lomu.
Klients tos var izmantot Ä«su laiku un periodiski jÄiegÅ«st jauni sertifikÄti (pirms to iegÅ«Å”anas Expiration). Modelis ir vienkÄrÅ”s: droŔības apsvÄrumu dÄļ AWS bieži rotÄ pagaidu atslÄgas, taÄu klienti var tÄs dažas minÅ«tes saglabÄt keÅ”atmiÅÄ, lai kompensÄtu veiktspÄjas sodu, kas saistÄ«ts ar jaunu sertifikÄtu iegÅ«Å”anu.
AWS Java SDK vajadzÄtu uzÅemties atbildÄ«bu par Ŕī procesa organizÄÅ”anu, taÄu kaut kÄdu iemeslu dÄļ tas nenotiek.
PÄc problÄmu meklÄÅ”anas vietnÄ GitHub mÄs saskÄrÄmies ar problÄmu #1921. ViÅa mums palÄ«dzÄja noteikt virzienu, kurÄ āraktā tÄlÄk.
AWS SDK atjaunina sertifikÄtus, ja rodas kÄds no Å”iem nosacÄ«jumiem:
Lai redzÄtu saÅemto sertifikÄtu faktisko derÄ«guma termiÅu, mÄs izpildÄ«jÄm iepriekÅ” minÄtÄs cURL komandas gan no konteinera, gan no EC2 instances. No konteinera saÅemtÄ sertifikÄta derÄ«guma termiÅÅ” izrÄdÄ«jÄs krietni Ä«sÄks: tieÅ”i 15 minÅ«tes.
Tagad viss ir kļuvis skaidrs: par pirmo pieprasÄ«jumu mÅ«su dienests saÅÄma pagaidu sertifikÄtus. TÄ kÄ tie nebija derÄ«gi ilgÄk par 15 minÅ«tÄm, AWS SDK izlems tos atjauninÄt pÄc nÄkamÄ pieprasÄ«juma. Un tas notika ar katru pieprasÄ«jumu.
KÄpÄc sertifikÄtu derÄ«guma termiÅÅ” ir kļuvis Ä«sÄks?
AWS instances metadati ir paredzÄti darbam ar EC2 gadÄ«jumiem, nevis ar Kubernetes gadÄ«jumiem. No otras puses, mÄs negribÄjÄm mainÄ«t lietojumprogrammas saskarni. Å im nolÅ«kam mÄs izmantojÄm KIAM - rÄ«ks, kas, izmantojot aÄ£entus katrÄ Kubernetes mezglÄ, ļauj lietotÄjiem (inženieriem, kas izvieto lietojumprogrammas klasterÄ«) pieŔķirt IAM lomas konteineriem podiÅos tÄ, it kÄ tie bÅ«tu EC2 gadÄ«jumi. KIAM pÄrtver zvanus uz AWS instances metadatu pakalpojumu un apstrÄdÄ tos no keÅ”atmiÅas, iepriekÅ” tos saÅÄmis no AWS. No pielietojuma viedokļa nekas nemainÄs.
KIAM piegÄdÄ pÄkstÄ«m Ä«stermiÅa sertifikÄtus. Tas ir loÄ£iski, Åemot vÄrÄ, ka pÄksts vidÄjais kalpoÅ”anas laiks ir Ä«sÄks nekÄ EC2 eksemplÄram. SertifikÄtu noklusÄjuma derÄ«guma termiÅÅ” vienÄds ar tÄm paÅ”Äm 15 minÅ«tÄm.
TÄ rezultÄtÄ, ja abas noklusÄjuma vÄrtÄ«bas pÄrklÄjat vienu virs otras, rodas problÄma. Katrs pieteikumam iesniegtais sertifikÄts beidzas pÄc 15 minÅ«tÄm. TomÄr AWS Java SDK piespiež atjaunot jebkuru sertifikÄtu, kuram lÄ«dz derÄ«guma termiÅa beigÄm ir atlikuÅ”as mazÄk nekÄ 15 minÅ«tes.
RezultÄtÄ pagaidu sertifikÄts ir spiests atjaunot ar katru pieprasÄ«jumu, kas ietver pÄris izsaukumus uz AWS API un izraisa ievÄrojamu latentuma pieaugumu. AWS Java SDK mÄs atradÄm funkcijas pieprasÄ«jums, kurÄ ir minÄta lÄ«dzÄ«ga problÄma.
RisinÄjums izrÄdÄ«jÄs vienkÄrÅ”s. MÄs vienkÄrÅ”i pÄrkonfigurÄjÄm KIAM, lai pieprasÄ«tu sertifikÄtus ar ilgÄku derÄ«guma termiÅu. Kad tas notika, pieprasÄ«jumi sÄka plÅ«st bez AWS metadatu pakalpojuma lÄ«dzdalÄ«bas, un latentums samazinÄjÄs lÄ«dz pat zemÄkam lÄ«menim nekÄ EC2.
Atzinumi
Balstoties uz mÅ«su pieredzi ar migrÄciju, viens no biežÄkajiem problÄmu avotiem nav Kubernetes vai citu platformas elementu kļūdas. Tas arÄ« nenovÄrÅ” nekÄdus bÅ«tiskus trÅ«kumus mikropakalpojumos, kurus mÄs pÄrnesam. ProblÄmas bieži rodas vienkÄrÅ”i tÄpÄc, ka mÄs apvienojam dažÄdus elementus.
MÄs sajaucam kopÄ sarežģītas sistÄmas, kuras nekad iepriekÅ” nav bijuÅ”as mijiedarbÄ«bÄ, sagaidot, ka tÄs kopÄ veidos vienotu, lielÄku sistÄmu. DiemžÄl, jo vairÄk elementu, jo vairÄk kļūdu, jo lielÄka ir entropija.
MÅ«su gadÄ«jumÄ lielais latentums nebija Kubernetes, KIAM, AWS Java SDK vai mÅ«su mikropakalpojuma kļūdu vai sliktu lÄmumu rezultÄts. Tas tika iegÅ«ts, apvienojot divus neatkarÄ«gus noklusÄjuma iestatÄ«jumus: vienu KIAM, otru AWS Java SDK. AtseviŔķi Åemti vÄrÄ abi parametri: aktÄ«vÄ sertifikÄtu atjaunoÅ”anas politika AWS Java SDK un sertifikÄtu Ä«sais derÄ«guma termiÅÅ” KAIM. Bet, tos saliekot kopÄ, rezultÄti kļūst neparedzami. Diviem neatkarÄ«giem un loÄ£iskiem risinÄjumiem nav jÄbÅ«t jÄgas, ja tos apvieno.
PS no tulka
Varat uzzinÄt vairÄk par KIAM utilÄ«ta arhitektÅ«ru AWS IAM integrÄÅ”anai ar Kubernetes vietnÄ Å is raksts no tÄ veidotÄjiem.