MÀrkus tÔlke kohta.: See artikkel, mille autor on Galo Navarro, Euroopa ettevÔtte Adevinta peamine tarkvarainsener, on pÔnev ja hariv "uurimine" infrastruktuuri haldamise valdkonnas. Selle algne pealkiri on tÔlkes mÔnevÔrra tÀiendatud pÔhjusel, mille selgitab autor artikli alguses.

Autori mĂ€rkus: Tundub, et see postitus palju rohkem tĂ€helepanu, kui oodatud. Ma saan endiselt pahaseid kommentaare selle kohta, et artikli pealkiri on eksitav ja et mĂ”ned lugejad on kurvad. Ma mĂ”istan, mis toimub, seetĂ”ttu, hoolimata riski kaotada kogu intrigeerivus, tahan kohe rÀÀkida, millest see artikkel rÀÀgib. Kui meeskonnad liiguvad Kubernetesesse, nĂ€en huvitavat asja: igal korral, kui tekib probleem (nĂ€iteks viivituste suurenemine pĂ€rast migratsiooni), sĂŒĂŒdistatakse esmalt Kuberneteset, kuid hiljem selgub, et orkestraator pole tegelikult sĂŒĂŒdi. See artikkel rÀÀgib ĂŒhest sellisest juhtumist. Selle pealkiri kordab ĂŒhte meie arendaja hĂŒĂŒatust (hiljem saate veenduda, et Kubernetes pole siin sugugi sĂŒĂŒdi). Siit leiate mitte ĂŒllatavaid Ă€ratundeid Kubernetesest, kuid vĂ”ite oodata paar head Ă”ppetundi keeruliste sĂŒsteemide kohta.
Paari nĂ€dala eest tegeles mu meeskond ĂŒhe mikroteenuse migreerimisega peamisele platvormile, mis hĂ”lmab CI/CD, Kubernetesel pĂ”hinevat töökeskkonda, mÔÔdikuid ja muid kasulikke funktsioone. Veebisait oli katsekorral: plaanisime selle aluseks vĂ”tta ja migreerida veel umbes 150 teenust jĂ€rgnevate kuude jooksul. KĂ”ik need teenused vastutavad mĂ”nede suurimate Interneti-platvormide nagu Infojobs, Fotocasa jne toimimise eest.
PĂ€rast rakenduse kĂ€ivitamist Kuberneteses ja osa liikluse suunamist selle suunas ootab meid murettekitav ĂŒllatus. Viivitus (latency) Kuberneteses oli 10 korda kĂ”rgem, kui EC2-s. Ăldiselt oli vajalik kas selle probleemi lahendamine vĂ”i mikroteenusest loobumine (ja vĂ”ib-olla ka kogu projektist).
Miks on viivitus Kuberneteses nii palju kÔrgem kui EC2-s?
Selle kitsaskoha leidmiseks kogusime mÔÔdikud kogu pĂ€ringu teekonnalt. Meie arhitektuur on lihtne: API-lĂ€bipÀÀs (Zuul) vahendab pĂ€ringud mikroteenuse eksemplaridele EC2-s vĂ”i Kuberneteses. Kuberneteses kasutame NGINX Ingress Controllerit, samas kui taustsĂŒsteemid koosnevad tavalistest objektidest, millel on JVM-rakendus Springi platvormil.
EC2
+---------------+
| +---------+ |
| | | |
+-------> BACKEND | |
| | | | |
| | +---------+ |
| +---------------+
+------+ |
Public | | |
-------> ZUUL +--+
traffic | | | Kubernetes
+------+ | +-----------------------------+
| | +-------+ +---------+ |
| | | | xx | | |
+-------> NGINX +------> BACKEND | |
| | | xx | | |
| +-------+ +---------+ |
+-----------------------------+Tundus, et probleem oli seotud algse tööfaasi viivitusega backend'is (markeerisin probleemse ala graafikul kui Â«Ń Ń Â»). EC2-s oli rakenduse vastus umbes 20 ms. Kuberneteses kasvas viivitus 100â200 ms-eni.
Viskasime kiiresti kĂ”rvale kahtlusalused, mis olid seotud teostuskeskkonna vahetamisega. JVM versioon jĂ€i muutumatuks. Konteinerimise probleemid ei olnud samuti mĂ€ngus: rakendus töötas juba edukalt konteinerites EC2-s. Koormus? Aga me mĂ€rkasime kĂ”rgeid viivitusi isegi 1 pĂ€ringu sekundis. Pausid prĂŒgikogu kogumise ajal saadi samuti vĂ€listada.
Ăks meie Kubernetes administraatoreid kĂŒsis, kas rakendusel on vĂ€liseid sĂ”ltuvusi, kuna minevikus on DNS pĂ€ringud tekitanud sarnaseid probleeme.
HĂŒpotees 1: DNS-nimede lahendamine
Iga pĂ€ringu korral pöördub meie rakendus ĂŒks kuni kolm korda AWS Elasticsearch instantsi poole domeenis, mis nĂ€eb vĂ€lja nagu elastic.spain.adevinta.com. Konteinerite sees on meil , seega saame kontrollida, kas domeeni otsimine tĂ”epoolest vĂ”tab kaua aega.
DNS-pÀringud konteinerist:
[root@be-851c76f696-alf8z \/]# while true; do dig "elastic.spain.adevinta.com" | grep time; sleep 2; done
;; KĂŒsitav aeg: 22 msec
;; KĂŒsitav aeg: 22 msec
;; KĂŒsitav aeg: 29 msec
;; KĂŒsitav aeg: 21 msec
;; KĂŒsitav aeg: 28 msec
;; KĂŒsitav aeg: 43 msec
;; KĂŒsitav aeg: 39 msecSarnased pĂ€ringud ĂŒhest EC2 instantsist, kus rakendus töötab:
bash-4.4# while true; do dig "elastic.spain.adevinta.com" | grep time; sleep 2; done
;; KĂŒsitav aeg: 77 msec
;; KĂŒsitav aeg: 0 msec
;; KĂŒsitav aeg: 0 msec
;; KĂŒsitav aeg: 0 msec
;; KĂŒsitav aeg: 0 msecArvestades, et otsimine kestab umbes 30 ms, sai selgeks, et DNS lahendamine Elasticsearch'i poole pöördumisel panustab tĂ”esti viivituse suurenemisse.
Kuid see oli kummaline kahel pÔhjusel:
- Meil on juba palju Kubernetes'i rakendusi, mis suhtlevad AWS-i ressurssidega, kuid ei kannata suuri viivitusi. ĂkskĂ”ik, mis pĂ”hjus see ka ei oleks, on see seotud just selle juhtumiga.
- Teame, et JVM rakendab DNS-i mÀluvahehoidu. Meie piltides on TTL vÀÀrtus mÀÀratud
$JAVA_HOME/jre/lib/security/java.securityja see on seatud 10 sekundiks:networkaddress.cache.ttl = 10. TeisisÔnu peab JVM kÔik DNS-i pÀringud 10 sekundiks vahemÀllu salvestama.
Esimese hĂŒpoteesi kinnitamiseks otsustasime ajutiselt loobuda DNS-i kĂ”nedest ja vaadata, kas probleem kaob. Esmalt otsustasime rakendust ĂŒmber seadistada, et see suhtleks Elasticsearch'iga otse IP-aadressi kaudu, mitte domeeninime kaudu. See nĂ”uaks koodi muutmist ja uut juurutamist, seega lihtsalt sidusime domeeni selle IP-aadressiga /etc/hosts:
34.55.5.111 elastic.spain.adevinta.comNĂŒĂŒd sai konteiner IP-aadressi peaaegu koheselt. See tĂ”i kaasa mĂ”ningase paranemise, kuid olime vaid veidi lĂ€henenud oodatud viivituse tasemele. Kuigi DNS-i lahendamine vĂ”ttis palju aega, jĂ€i tĂ”eline pĂ”hjus endiselt meilt varjatuks.
VÔrgu diagnostika
Otsustasime analĂŒĂŒsida liiklust konteinerist, kasutades tcpdump, et jĂ€lgida, mis vĂ”rgus tĂ€pselt toimub:
[root@be-851c76f696-alf8z \/]# tcpdump -leni any -w capture.pcap SeejĂ€rel saatsime mĂ”ned pĂ€ringud ja allalaadisime nende andmed (kubectl cp my-service:\/capture.pcap capture.pcap) edasiseks analĂŒĂŒsiks .
DNS-i pĂ€ringutes ei olnud kahtlast (vĂ€lja arvatud ĂŒks pisiasi, millest rÀÀgin hiljem). Kuid meie teenuse kĂ€itlemisel igas pĂ€ringus oli teatud kĂ”rvalekaldeid. Allpool on ekraanipilt kajastusest, mis nĂ€itab pĂ€ringu vastuvĂ”ttu enne vastuse algust:

Pakettide numbrid on esimeses veerus. Selguse huvides olen erinevad TCP voolud vÀrviga esile tÔstnud.
Roheline voog, mis algab 328. paketist, nĂ€itab, kuidas klient (172.17.22.150) kehtestas TCP-ĂŒhenduse konteineriga (172.17.36.147). PĂ€rast esialgset kĂ€epigistust (328-330) tĂ”i pakett 331 HTTP GET \/v1\/.. â sisenev pĂ€ring meie teenusele. Kogu protsess vĂ”ttis aega 1 ms.
Hall voog (paketist 339) nĂ€itab, et meie teenus saatis HTTP-pĂ€ringu Elasticsearchi eksemplarile (TCP-kĂ€epigistus puudub, kuna kasutatakse juba olemasolevat ĂŒhendust). Selleks kulus 18 ms.
Praegu on kĂ”ik korras ja ajad vastavad enam-vĂ€hem oodatud viivitustele (20â30 ms kliendi mÔÔtmiste puhul).
Kuid sinine sektsioon vĂ”tab aega 86 ms. Mis selles toimub? Paketi 333 puhul saatis meie teenus HTTP GET-pĂ€ringu /latest/meta-data/iam/security-credentials, ning kohe pĂ€rast seda, sama TCP-ĂŒhenduse kaudu, veel ĂŒhe GET-pĂ€ringu /latest/meta-data/iam/security-credentials/arn:...
Me leidsime, et see kordub iga pÀringu, mis saadeti jÀlgimise kÀigus. DNS-i lahendamine on tÔepoolest meie konteinerites veidi aeglasem (selle fenomeni selgitamine on vÀga huvitav, kuid ma hoian seda eraldi artikli jaoks). Selgus, et pikemate viivituste pÔhjuseks on kÔned AWS Instance Metadata teenusele iga pÀringu korral.
HĂŒpotees 2: liigsed kĂ”ned AWS-i
MĂ”lemad endpointâid kuuluvad . Meie mikroteenus kasutab seda teenust töötamisel Elasticsearchiga. MĂ”lemad kĂ”ned kuuluvad baasauditi protsessi. Endpoint, millele esimeses pĂ€ringus pöördutakse, annab IAM-i rolli, mis on seotud eksemplariga.
/ # curl http://169.254.169.254/latest/meta-data/iam/security-credentials/
arn:aws:iam::<account_id>:role/some_roleTeine pĂ€ring pöördub teise endpointâi poole, et saada ajutisi volitusi selle eksemplari jaoks:
/ # curl http://169.254.169.254/latest/meta-data/iam/security-credentials/arn:aws:iam::<account_id>:role/some_role`
{
"Code" : "Success",
"LastUpdated" : "2012-04-26T16:39:16Z",
"Type" : "AWS-HMAC",
"AccessKeyId" : "ASIAIOSFODNN7EXAMPLE",
"SecretAccessKey" : "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY",
"Token" : "token",
"Expiration" : "2017-05-17T15:09:54Z"
} Kliendil on lubatud neid kasutada lĂŒhikese aja jooksul ja aeg-ajalt peab ta saama uusi sertifikaate (kuni nende Expiration). Mudel on lihtne: AWS viib lĂ€bi sagedase ajutiste vĂ”tmete rotatsiooni turvakaalutlustel, kuid kliendid saavad neid mĂ”neks minutiks vahemĂ€llu salvestada, et kompenseerida uute sertifikaatide hankimisega seotud jĂ”udluse langust.
AWS Java SDK peaks vÔtma enda kanda selle protsessi haldamise, kuid mingil pÔhjusel see ei toimu.
Otsides GitHubist, kohtasime probleemi . See aitas meil mÀÀratleda suuna, milles tuleks edasi «kaevata».
AWS SDK uuendab sertifikaate ĂŒhel jĂ€rgmistest tingimustest:
- Nende kehtivuse lÔppemise aeg (
Expiration) jÔuabEXPIRATION_THRESHOLD, mis on koodis fikseeritud 15 minutiks. - Viimati, kui prooviti sertifikaate uuendada, on möödunud rohkem aega kui
REFRESH_THRESHOLD, mis on âhardcodeâitud 60 minutiks.
Et nĂ€ha tegelikku aegumistĂ€htaega, mille saime sertifikaatidest, kĂ€ivitasime ĂŒlaltoodud cURL-kĂ€sud konteinerist ja EC2 eksemplarist. Sertifikaadi kehtivusaeg, mis saadi konteinerist, osutus palju lĂŒhemaks: tĂ€pselt 15 minutiks.
NĂŒĂŒd on kĂ”ik selge: esimese pĂ€ringu korral sai meie teenus ajutisi sertifikaate. Kuna nende kehtivusaeg ei ĂŒletanud 15 minutit, otsustas AWS SDK jĂ€rgmisel pĂ€ringul need uuendada. Ja seda juhtus iga pĂ€ringu puhul.
Miks on sertifikaatide kehtivusaeg lĂŒhenenud?
AWS Instance Metadata teenus on mĂ”eldud EC2 instantside jaoks, mitte Kubernetes'e jaoks. Teisest kĂŒljest ei soovinud me rakenduste liidest muuta. Selle jaoks kasutasime â tööriista, mis vĂ”imaldab Kubernetes'e iga sĂ”lme agentide kaudu kasutajatel (inseneridel, kes juurutavad rakendusi klastrisse) mÀÀrata IAM rolle konteineritele pod'ides, justkui need oleksid EC2 instantsid. KIAM pĂŒĂŒab kinni vĂ€ljakutsed AWS Instance Metadata teenusele ja töötleb neid oma vahemĂ€lust, saades esmalt AWS'ilt. Rakenduse seisukohalt ei muutu midagi.
KIAM annab pod'idele lĂŒhiajalisi sertifikaate. See on mĂ”istlik, arvestades, et pod'i keskmine eluiga on lĂŒhem kui EC2 instantsi oma. Vaikimisi on sertifikaatide kehtivusaeg .
SeetĂ”ttu, kui mĂ”lemad vaikeseaded ĂŒksteisega kokku lĂŒkata, tekib probleem. Iga rakendusele antud sertifikaat aegub 15 minuti pĂ€rast. Samal ajal sunnib AWS Java SDK sundsekkuma igasuguse sertifikaadi uuendamisse, mille kehtivusaeg on vĂ€hem kui 15 minutit.
Kuna tulemuseks on ajutine sertifikaat, uuendatakse seda iga pÀringu korral, mis toob kaasa paari API AWS kÔne ja pÔhjustab mÀrkimisvÀÀrset latentsuse suurenemist. AWS Java SDK-s leidsime , milles mainitakse sarnast probleemi.
Lahendus osutus lihtsaks. Muutasime lihtsalt KIAM-i, et ta otsiks pikema kehtivusajaga sertifikaate. Niipea kui see juhtus, kÀidi pÀringud lÀbi ilma AWS Metadata teenuse sekkumiseta ning latentsus langes isegi madalamale tasemele kui EC2-s.
JĂ€reldused
Meie ĂŒleviimise kogemustest lĂ€htudes vĂ”ib öelda, et ĂŒks levinumaid probleemide allikaid ei ole vigu Kuberneteses vĂ”i muudes platvormi elementides. See ei ole seotud ka mikroteenuste fundamentaalsete puudustega, mida me ĂŒle kanname. Probleemid tekivad sageli lihtsalt seetĂ”ttu, et ĂŒhendame erinevaid elemente.
Me segame keerulisi sĂŒsteeme, mis pole kunagi varem omavahel suhelnud, lootes, et koos moodustavad nad ĂŒhe suurema sĂŒsteemi. Kahjuks, mida rohkem komponente, seda rohkem ruumi eksimustele, seda kĂ”rgem on entropia.
Meie puhul ei tulenenud kĂ”rge latentsus Kubernetes, KIAM, AWS Java SDK vĂ”i meie mikroteenusest. See oli kahe eraldiseisva vaikimisi mÀÀratud parameetri ĂŒhendamise tulemus: ĂŒks KIAM-is ja teine AWS Java SDK-s. Eraldi on mĂ”lemad parameetrid mĂ”istlikud: nii aktiivne sertifikaatide uuendamise poliitika AWS Java SDK-s kui ka lĂŒhike sertifikaatide kehtivusaeg KAI-s. Kuid kui need kokku tuua, muutuvad tulemused ettearvamatuks. Kaks sĂ”ltumatut ja loogilist otsust ei pea sugugi koos toimima mĂ”istlikult.
P.S. tÔlkijalt
Rohkem informatsiooni KIAM-i arhitektuuri kohta, mis integreerib AWS IAM-i Kubernetesega, leiate kui selle loo autoritelt.
Meie blogist leiate ka:
- «»;
- «»;
- «»;
- «».
Allikas: habr.com
