"Kubernetes huet d'Latenz ëm 10 Mol erhéicht": wien ass dëst Schold?

Note. iwwersat.: Dësen Artikel, geschriwwen vum Galo Navarro, deen d'Positioun vum Principal Software Engineer bei der europäescher Firma Adevinta hält, ass eng faszinéierend an léierräich "Enquête" am Beräich vun den Infrastrukturoperatiounen. Säin ursprénglechen Titel gouf an der Iwwersetzung liicht ausgebaut aus engem Grond, deen den Auteur ganz am Ufank erkläert.

"Kubernetes huet d'Latenz ëm 10 Mol erhéicht": wien ass dëst Schold?

Notiz vum Auteur: Gesäit aus wéi dëse Post ugezunn vill méi Opmierksamkeet wéi erwaart. Ech kréien nach ëmmer rosen Kommentaren datt den Titel vum Artikel täuschend ass an datt verschidde Lieser traureg sinn. Ech verstinn d'Grënn fir wat geschitt, dofir, trotz dem Risiko fir déi ganz Intrig ze ruinéieren, wëll ech Iech direkt soen iwwer wat dësen Artikel ass. Eng virwëtzeg Saach, déi ech gesinn hunn wéi d'Equipen op Kubernetes migréieren, ass datt wann e Problem entsteet (wéi eng erhéicht Latenz no enger Migratioun), déi éischt Saach, déi d'Schold kritt ass Kubernetes, awer dann stellt sech eraus datt den Orchester net wierklech ass Schold. Dësen Artikel erzielt iwwer een esou Fall. Säin Numm widderhëlt d'Ausrufe vun engem vun eisen Entwéckler (spéider gesitt Dir datt Kubernetes näischt domat ze dinn huet). Dir fannt hei keng iwwerraschend Offenbarungen iwwer Kubernetes, awer Dir kënnt e puer gutt Lektioune iwwer komplex Systemer erwaarden.

Virun e puer Wochen huet mäi Team en eenzege Mikroservice op eng Kärplattform migréiert déi CI / CD, eng Kubernetes-baséiert Runtime, Metriken an aner Goodies enthält. D'Beweegung war vun enger Prouf-Natur: Mir hu geplangt et als Basis ze huelen an an den nächste Méint ongeféier 150 Servicer weider ze transferéieren. All vun hinnen sinn responsabel fir de Fonctionnement vun e puer vun de gréisste online Plattformen a Spuenien (Infojobs, Fotocasa, etc.).

Nodeems mir d'Applikatioun op Kubernetes ofgesat hunn an e puer Traffic dohinner ëmgeleet hunn, huet eng alarméierend Iwwerraschung op eis gewaart. Verspéidung (latency) Ufroen an Kubernetes waren 10 Mol méi héich wéi an EC2. Am Allgemengen war et néideg entweder eng Léisung fir dëse Problem ze fannen, oder d'Migratioun vum Mikroservice (an eventuell de ganze Projet) opzeginn.

Firwat ass Latenz sou vill méi héich a Kubernetes wéi an EC2?

Fir de Flaschenhals ze fannen, hu mir Metriken laanscht de ganzen Ufrowee gesammelt. Eis Architektur ass einfach: en API Gateway (Zuul) Proxy Ufroe fir Mikroservice Instanzen an EC2 oder Kubernetes. A Kubernetes benotze mir NGINX Ingress Controller, an d'Backends sinn normal Objekter wéi Détachement mat enger JVM Applikatioun op der Fréijoersplattform.

                                  EC2
                            +---------------+
                            |  +---------+  |
                            |  |         |  |
                       +-------> BACKEND |  |
                       |    |  |         |  |
                       |    |  +---------+  |                   
                       |    +---------------+
             +------+  |
Public       |      |  |
      -------> ZUUL +--+
traffic      |      |  |              Kubernetes
             +------+  |    +-----------------------------+
                       |    |  +-------+      +---------+ |
                       |    |  |       |  xx  |         | |
                       +-------> NGINX +------> BACKEND | |
                            |  |       |  xx  |         | |
                            |  +-------+      +---------+ |
                            +-----------------------------+

De Problem schéngt mat der initialer Latenz am Backend verbonnen ze sinn (ech hunn de Problemberäich op der Grafik als "xx" markéiert). Op EC2 huet d'Applikatiounsreaktioun ongeféier 20ms gedauert. A Kubernetes ass d'Latenz op 100-200 ms eropgaang.

Mir hunn déi méiglech Verdächteger am Zesummenhang mat der Runtime Ännerung séier entlooss. D'JVM Versioun bleift d'selwecht. Containeriséierungsprobleemer haten och näischt domat ze dinn: d'Applikatioun leeft schonn erfollegräich a Containeren op EC2. Lueden? Awer mir hunn héich latencies observéiert souguer bei 1 Ufro pro Sekonn. Pausen fir Müllsammlung kéinten och vernoléissegt ginn.

Ee vun eise Kubernetes Administrateuren huet sech gefrot ob d'Applikatioun extern Ofhängegkeeten huet well DNS Ufroen ähnlech Problemer an der Vergaangenheet verursaacht hunn.

Hypothes 1: DNS Numm Resolutioun

Fir all Ufro kënnt eis Applikatioun eng AWS Elasticsearch Instanz een bis dräimol an engem Domain wéi elastic.spain.adevinta.com. Bannen an eise Container et gëtt eng Schuel, also kënne mir kucken ob d'Sich no engem Domain tatsächlech laang dauert.

DNS Ufroen vum Container:

[root@be-851c76f696-alf8z /]# while true; do dig "elastic.spain.adevinta.com" | grep time; sleep 2; done
;; Query time: 22 msec
;; Query time: 22 msec
;; Query time: 29 msec
;; Query time: 21 msec
;; Query time: 28 msec
;; Query time: 43 msec
;; Query time: 39 msec

Ähnlech Ufroe vun engem vun den EC2 Instanzen wou d'Applikatioun leeft:

bash-4.4# while true; do dig "elastic.spain.adevinta.com" | grep time; sleep 2; done
;; Query time: 77 msec
;; Query time: 0 msec
;; Query time: 0 msec
;; Query time: 0 msec
;; Query time: 0 msec

Bedenkt datt de Lookup ongeféier 30ms gedauert huet, gouf et kloer datt d'DNS-Resolutioun beim Zougang zu Elasticsearch wierklech zur Erhéijung vun der latency bäigedroen huet.

Wéi och ëmmer, dëst war komesch aus zwee Grënn:

  1. Mir hu schonn eng Tonn vu Kubernetes Uwendungen déi mat AWS Ressourcen interagéieren ouni ënner héijer latency ze leiden. Egal wat de Grond, et bezitt sech speziell op dëse Fall.
  2. Mir wëssen datt de JVM DNS-Caching am Gedächtnis mécht. An eise Biller ass den TTL Wäert ageschriwwen $JAVA_HOME/jre/lib/security/java.security a setzen op 10 Sekonnen: networkaddress.cache.ttl = 10. An anere Wierder, de JVM soll all DNS Ufroe fir 10 Sekonnen cache.

Fir déi éischt Hypothese ze bestätegen, hu mir beschloss fir eng Zäit laang DNS ze ruffen a kucken ob de Problem fortgaang ass. Als éischt hu mir décidéiert d'Applikatioun nei ze konfiguréieren sou datt se direkt mat Elasticsearch iwwer IP Adress kommunizéiert, anstatt duerch en Domain Numm. Dëst géif Code Ännerungen an eng nei Deployment erfuerderen, sou datt mir d'Domain einfach op seng IP Adress mapéiert hunn /etc/hosts:

34.55.5.111 elastic.spain.adevinta.com

Elo krut de Container bal direkt eng IP. Dëst huet zu enger Verbesserung gefouert, awer mir waren nëmmen e bësse méi no un den erwaarten Latenzniveauen. Och wann d'DNS-Resolutioun laang gedauert huet, ass de richtege Grond eis nach ëmmer entkomm.

Diagnostik iwwer Netzwierk

Mir hu beschloss Traffic aus dem Container ze analyséieren benotzt tcpdumpfir ze kucken wat genau am Netz geschitt:

[root@be-851c76f696-alf8z /]# tcpdump -leni any -w capture.pcap

Mir hunn dunn e puer Ufroe geschéckt an hir Erfaassung erofgelueden (kubectl cp my-service:/capture.pcap capture.pcap) fir weider Analyse an Wireshark.

Et war näischt verdächteg iwwer d'DNS Ufroen (ausser eng kleng Saach iwwer déi ech méi spéit schwätzen). Awer et waren gewësse Komeschheeten an der Aart a Weis wéi eise Service all Ufro gehandelt huet. Drënner ass e Screenshot vun der Erfaassung déi weist datt d'Ufro ugeholl gëtt ier d'Äntwert ufänkt:

"Kubernetes huet d'Latenz ëm 10 Mol erhéicht": wien ass dëst Schold?

Package Zuelen sinn an der éischter Kolonn gewisen. Fir Kloerheet hunn ech déi verschidden TCP Streams Faarfkodéiert.

Déi gréng Baach ugefaange mat Pak 328 weist wéi de Client (172.17.22.150) eng TCP Verbindung op de Container etabléiert (172.17.36.147). No der éischter Handshake (328-330), Package 331 bruecht HTTP GET /v1/.. - eng Entréeën Ufro un eise Service. De ganze Prozess huet 1 ms gedauert.

De groe Stroum (vum Paket 339) weist datt eise Service eng HTTP-Ufro un d'Elasticsearch Instanz geschéckt huet (et gëtt keen TCP Handshake well et eng existent Verbindung benotzt). Dëst huet 18 ms gedauert.

Bis elo ass alles gutt, an d'Zäite entspriechen ongeféier den erwaarten Verspéidungen (20-30 ms wann Dir vum Client gemooss gëtt).

Wéi och ëmmer, déi blo Sektioun dauert 86ms. Wat leeft dran? Mam Paket 333 huet eise Service eng HTTP GET Ufro un geschéckt /latest/meta-data/iam/security-credentials, an direkt duerno, iwwer déiselwecht TCP Verbindung, eng aner GET Ufro un /latest/meta-data/iam/security-credentials/arn:...

Mir hu fonnt datt dëst mat all Ufro duerch d'Spuer widderholl gouf. DNS Resolutioun ass wierklech e bësse méi lues an eise Container (d'Erklärung fir dëst Phänomen ass ganz interessant, awer ech späicheren et fir en separaten Artikel). Et huet sech erausgestallt datt d'Ursaach vun de laange Verspéidungen Uriff un den AWS Instance Metadata Service op all Ufro waren.

Hypothes 2: onnéideg Uruff un AWS

Béid Endpunkte gehéieren zu AWS Instanz Metadaten API. Eise Mikroservice benotzt dëse Service wärend Elasticsearch leeft. Béid Uriff sinn Deel vum Basis Autorisatiounsprozess. Den Endpunkt, deen op der éischter Ufro zougänglech ass, stellt d'IAM Roll, déi mat der Instanz assoziéiert ass.

/ # curl http://169.254.169.254/latest/meta-data/iam/security-credentials/
arn:aws:iam::<account_id>:role/some_role

Déi zweet Ufro freet den zweeten Endpunkt fir temporär Permissiounen fir dës Instanz:

/ # 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"
}

De Client kann se fir eng kuerz Zäit benotzen a muss periodesch nei Certificaten kréien (ier se sinn Expiration). De Modell ass einfach: AWS rotéiert temporär Schlësselen dacks aus Sécherheetsgrënn, awer Cliente kënnen se fir e puer Minutten cache fir d'Leeschtungsstrof ze kompenséieren, déi mat der Erhalen vun neien Zertifikater verbonne sinn.

D'AWS Java SDK soll d'Verantwortung iwwerhuelen fir dëse Prozess z'organiséieren, awer aus irgendege Grënn geschitt dat net.

Nodeems mir Probleemer op GitHub gesicht hunn, hu mir e Problem fonnt #1921. Si huet eis gehollef d'Richtung ze bestëmmen, an där mir weider "graven".

D'AWS SDK aktualiséiert Certificaten wann ee vun de folgende Konditioune geschitt:

  • Auslafdatum (Expiration) Falen an EXPIRATION_THRESHOLD, hardcoded zu 15 Minutten.
  • Méi Zäit ass vergaang zënter dem leschte Versuch, Zertifikater ze erneieren wéi REFRESH_THRESHOLD, hardcoded fir 60 Minutten.

Fir den aktuellen Verfallsdatum vun den Zertifikater ze gesinn, déi mir kréien, hu mir déi uewe genannte cURL Kommandoe vu béide Container an der EC2 Instanz ausgefouert. D'Validitéitszäit vum Zertifika, deen aus dem Container kritt gouf, huet sech vill méi kuerz gewisen: genau 15 Minutten.

Elo ass alles kloer ginn: fir déi éischt Ufro krut eise Service temporäre Certificaten. Well se net méi wéi 15 Minutten valabel waren, géif d'AWS SDK décidéieren se op eng spéider Ufro ze aktualiséieren. An dat ass mat all Ufro geschitt.

Firwat ass d'Validitéit Period vun Certificaten méi kuerz ginn?

AWS Instance Metadata ass entwéckelt fir mat EC2 Instanzen ze schaffen, net Kubernetes. Op der anerer Säit wollte mir d'Applikatiounsinterface net änneren. Fir dëst hu mir benotzt KIAM - e Tool dat, mat Hëllef vun Agenten op all Kubernetes Node, Benotzer erlaabt (Ingenieuren déi Uwendungen op e Cluster ofsetzen) IAM Rollen un Container a Pods zouzeweisen wéi wa se EC2 Instanzen wieren. KIAM interceptéiert Uruff un den AWS Instance Metadata Service a veraarbecht se aus sengem Cache, nodeems se se virdru vun AWS kritt hunn. Vun der Applikatioun Siicht ännert sech näischt.

KIAM liwwert kuerzfristeg Zertifikater fir Pods. Dëst mécht Sënn wann Dir bedenkt datt déi duerchschnëttlech Liewensdauer vun engem Pod méi kuerz ass wéi eng EC2 Instanz. Standard Validitéit Period fir Certificaten gläich op déi selwecht 15 Minutten.

Als Resultat, wann Dir béid Standardwäerter openeen iwwerlagert, entsteet e Problem. All Zertifika, deen un eng Applikatioun geliwwert gëtt, leeft no 15 Minutten of. Wéi och ëmmer, d'AWS Java SDK forcéiert eng Erneierung vun all Zertifika deen manner wéi 15 Minutte virum Verfallsdatum lénks huet.

Als Resultat ass den temporäre Zertifika gezwongen mat all Ufro erneiert ze ginn, wat e puer Uruff un d'AWS API enthält an eng bedeitend Erhéijung vun der latency verursaacht. An AWS Java SDK hu mir fonnt Funktioun Ufro, déi en ähnleche Problem ernimmt.

D'Léisung huet sech als einfach erausgestallt. Mir hunn KIAM einfach nei konfiguréiert fir Certificaten mat enger méi laanger Validitéitsperiod ze froen. Wann dëst geschitt ass, hunn d'Ufroe ugefaang ouni d'Participatioun vum AWS Metadata Service ze fléien, an d'Latenz ass op nach méi niddereg Niveaue gefall wéi am EC2.

Conclusiounen

Baséierend op eis Erfahrung mat Migratiounen, ass eng vun den heefegste Quelle vu Probleemer net Bugs a Kubernetes oder aner Elementer vun der Plattform. Et adresséiert och keng fundamental Mängel an de Mikroservicer déi mir portéieren. Probleemer entstinn dacks einfach well mir verschidden Elementer zesummesetzen.

Mir vermëschen komplex Systemer déi nach ni matenee interagéiert hunn, an erwaarden datt se zesummen en eenzegen, méi grousse System bilden. Leider, wat méi Elementer, wat méi Plaz fir Feeler, wat méi héich d'Entropie ass.

An eisem Fall war déi héich Latenz net d'Resultat vu Bugs oder schlechten Entscheedungen an Kubernetes, KIAM, AWS Java SDK oder eisem Mikroservice. Et war d'Resultat vun der Kombinatioun vun zwee onofhängege Standardastellungen: een am KIAM, deen aneren an der AWS Java SDK. Getrennt geholl, si béid Parameteren Sënn: déi aktiv Zertifikat Erneierung Politik an der AWS Java SDK, an déi kuerz Validitéit Period vun Certificaten am KAIM. Awer wann Dir se zesummesetzt, ginn d'Resultater onberechenbar. Zwee onofhängeg a logesch Léisunge mussen net Sënn maachen wann se kombinéiert sinn.

PS vum Iwwersetzer

Dir kënnt méi iwwer d'Architektur vum KIAM Utility léieren fir AWS IAM mat Kubernetes z'integréieren dësen Artikel vu senge Schëpfer.

Liest och op eisem Blog:

Source: will.com

Setzt e Commentaire