Post Mortem om utilgængelighed af Quay.io

Bem. overs.: I begyndelsen af august offentliggjorde Red Hat løsningen på tilgængelighedsproblemerne, som havde været til stede i de foregående måneder for brugerne af deres service. Quay.io (det er baseret på et register til containerbilleder, som virksomheden fik med købet af CoreOS). Uanset din interesse i denne service som sådan, er vejen, som virksomhedens SRE-ingeniører har taget for at diagnosticere og løse årsagerne til nedbruddet, lærerigt.

Post Mortem om utilgængelighed af Quay.io

Den 19. maj, tidligt om morgenen (ifølge sommerens nordamerikanske østlige tidszone, EDT), gik tjenesten quay.io ned. Nedbruddet påvirkede både brugerne af quay.io og open source-projekter, der bruger quay.io som platform til at bygge og distribuere software. Red Hat værdsætter tilliden fra både den ene og den anden side.

SRE-ingeniørteamet gik straks i gang med at arbejde og forsøgte at stabilisere driften af Quay så hurtigt som muligt. Men mens de gjorde dette, mistede kunderne muligheden for at push’e nye billeder, og de kunne kun periodisk pull’e eksisterende. Af en ukendt årsag blev databasen quay.io låst efter at tjenesten blev skaleret til fuld kapacitet.

«Hvad er ændret?» — det er det første spørgsmål, der plejer at blive stillet i sådanne tilfælde. Vi bemærkede, at kort før problemet begyndte, blev OpenShift Dedicated-klusteret (hvor quay.io kører) opdateret til version 4.3.19. Da quay.io kører på Red Hat OpenShift Dedicated (OSD), var regelmæssige opdateringer en almindelig operation og havde aldrig ført til problemer. Desuden havde vi i løbet af de sidste seks måneder opdateret Quay-klusteret flere gange uden nogen driftsafbrydelser.

Mens vi forsøgte at genoprette tjenestens drift, begyndte andre ingeniører at forberede et nyt OSD-kluster med den tidligere version af softwaren, så de kunne deployere alt på det, hvis det skulle blive nødvendigt.

Årsagsanalyser

Det primære symptom på nedbruddet var en lavine af titusindvis af forbindelser til databasen, hvilket gjorde MySQL-instansen praktisk talt ubrugelig. Dette gjorde det svært at diagnosticere problemet. Vi satte en grænse for det maksimale antal forbindelser fra klienter for at hjælpe SRE-teamet med at vurdere problemet. Der blev ikke observeret nogen usædvanlig trafik til databasen: faktisk var de fleste forespørgsler læseforespørgsler, mens kun få var skriveforespørgsler.

Vi forsøgte også at identificere et mønster i databasen, der kunne have forårsaget denne lavine. Men vi fandt ingen tendenser i loggene. I ventetiden på, at den nye klynge med OSD 4.3.18 blev klar, fortsatte vi med at forsøge at starte pod'erne fra quay.io. Hver gang klyngen kom op på fuld kapacitet, låste databasen. Dette betød, at det var nødvendigt at genstarte RDS-instansen ud over alle quay.io pod'er.

Ved aftenstid stabiliserede vi servicen i read-only tilstand og deaktiverede maksimalt ikke-kritiske funktioner (f.eks. affaldssamling i navnerummet) for at reducere belastningen på databasen. Låsningerne stoppede, men årsagen blev aldrig fundet. Den nye OSD-klynge var klar, og vi flyttede servicen, tilsluttede trafikken og fortsatte overvågningen.

Quay.io fungerede stabilt på den nye OSD-klynge, så vi gik tilbage til database-loggene, men kunne stadig ikke finde en korrelation, der kunne forklare låsningerne. Ingeniørerne fra OpenShift arbejdede sammen med os for at forstå, om ændringer i Red Hat OpenShift 4.3.19 kunne have forårsaget problemer med Quay. Men vi fandt ikke noget, og det lykkedes ikke at reproducere problemet i laboratoriet.

Den anden fejl

28. maj, kort før middag EDT, kollapsede quay.io igen med de samme symptomer: databasen blev låst. Og igen kastede vi alt vores kræfter ind i efterforskningen. Først og fremmest var det nødvendigt at genskabe servicefunktionen. Men denne gang førte genstart af RDS og genstart af quay.io pod'erne ikke til noget: endnu en lavine af forbindelser skyllede ind over databasen. Men hvorfor?

Quay er skrevet i Python, og hver pod fungerer som en monolitisk container. I containerens køretidsmiljø kører mange parallelle opgaver samtidigt. Vi bruger biblioteket gevent under gunicorn til at håndtere webanmodninger. Når Quay modtager en anmodning (gennem vores eget API eller gennem Docker's API), tildeles den en gevent worker. Normalt skal denne worker kontakte databasen. Efter den første fejl opdagede vi, at gevent workerne tilsluttede databasen ved hjælp af standardindstillingerne.

Baseret på det betydelige antal pod’er i Quay og de tusinder af indkommende forespørgsler per sekund, kunne det store antal forbindelser til databasen teoretisk overbelaste MySQL-forekomsten. Gennem overvågning var det kendt, at Quay i gennemsnit behandler 5.000 forespørgsler per sekund. Omtrent det samme var tilfældet for antallet af forbindelser til databasen. 5.000 forbindelser kunne med lidt overskud håndteres af vores RDS-forekomst (hvilket ikke gælder for titusinder). Af en eller anden grund opstod der uventede stigninger i antallet af forbindelser, men vi bemærkede ikke nogen korrelation med de indkommende forespørgsler.

Denne gang besluttede vi os for at finde og løse kilden til problemet i stedet for blot at genstarte. Der blev foretaget ændringer i Quays kodebase for at begrænse antallet af forbindelser til databasen for hver worker gevent. Dette nummer blev en parameter i konfigurationen: det blev muligt at ændre det "on-the-fly" uden at skulle kompilere et nyt containerbillede. For at finde ud af, hvor mange forbindelser der reelt kunne håndteres, blev der udført adskillige tests med et staging-miljø, hvor forskellige værdier blev sat for at se, hvordan det ville påvirke belastningstestscenarierne. Resultatet viste, at Quay begynder at returnere 502-fejl, når antallet af forbindelser overstiger 10.000.

Vi deployerede straks denne nye version i produktionen og begyndte at overvåge grafen for forbindelser til databasen. Tidligere blev databasen blokeret efter cirka 20 minutter. Efter 30 problemfrie minutter havde vi håb, og efter en time - sikkerhed. Vi genoptog skrive-trafikken på hjemmesiden og begyndte på postmortem-analysen.

Ved at omgå problemet, der førte til blokeringen, fik vi ikke afklaret de sande årsager. Det blev bekræftet, at det ikke var relateret til nogen ændringer i OpenShift 4.3.19, da det samme skete med version 4.3.18, som tidligere havde fungeret med Quay uden problemer.

Der gemte sig tydeligvis noget andet i klyngen.

En detaljeret undersøgelse

Quay.io har i seks år brugt standardindstillingerne til at tilslutte til databasen uden problemer. Hvad er ændret? Det er tydeligt, at trafikken til quay.io hele tiden er steget. I vores tilfælde så det ud til, at der var nået en tærskel, som fungerede som en udløser for et væld af forbindelser. Vi fortsatte med at undersøge database-logfilerne efter det andet nedbrud, men fandt ingen mønstre eller åbenlyse sammenhænge.

I mellemtiden arbejdede SRE-teamet på forbedringer inden for overvågelser af anmodninger i Quay og den generelle sundhed af tjenesten. Nye målinger og overvågningspaneler blev implementeret, der viser, hvilke dele af Quay der er mest efterspurgte af kunderne.

Quay.io fungerede normalt indtil 9. juni. Om morgenen (EDT) blev vi igen vidner til et betydeligt stigning i antallet af forbindelse til databasen. Der var ingen nedetid denne gang, da en ny parameter begrænsede deres antal og forhindrede dem i at overstige MySQL's kapacitet. I cirka en halv time rapporterede mange brugere dog langsom drift af quay.io. Vi indsamlede hurtigt alle tilgængelige data ved at bruge de nye overvågningsværktøjer. Pludselig dukkede der et mønster op.

Før selve stigningen i forbindelserne kom der et stort antal anmodninger til App Registry API. App Registry er en mindre kendt funktion i quay.io. Den gør det muligt at gemme ting som Helm-diagrammer og containere med rige metadata. De fleste brugere af quay.io arbejder ikke med denne funktion, men den bruges aktivt af Red Hat OpenShift. OperatorHub i OpenShift gemmer alle operatører i App Registry. Disse operatører danner grundlaget for OpenShift's arbejdsbelastningsøkosystem og driftsmodel (i forbindelse med 'anden dags' operationer, Day 2), der er rettet mod partnere.

Hver OpenShift 4-klynge bruger operatørerne fra den indbyggede OperatorHub til at offentliggøre kataloget over operatører, der er tilgængelige til installation og til at levere opdateringer til allerede installerede. Med den stigende popularitet af OpenShift 4 er antallet af klynger på denne platform også steget over hele verden. Hver af disse klynger indlæser indholdet af operatørerne for at starte den indbyggede OperatorHub, idet de bruger App Registry inden i quay.io som backend. I jagter efter problemet glemte vi, at den stigende popularitet af OpenShift også øgede belastningen på en af de sjældent anvendte funktioner quay.io..

Vi gennemførte en analyse af trafikken til App Registry og kiggede ind i registreringskoden. Mangelene, som straks blev afsløret, medførte, at databaseforespørgslerne blev dannet suboptimalt. Under lav belastning skabte de ikke problemer, men ved højere belastning blev de en kilde til problemer. App Registry havde to problematiske endepunkter, der reagerede dårligt på stigende belastning: det første gav en liste over alle pakker i depotet, det andet returnerede alle blobber til pakken.

Årsagsafhjælpning

Hele den følgende uge arbejdede vi på at optimere koden i App Registry og dets miljø. Åbenlyst ineffektive SQL-forespørgsler blev omarbejdet, unødvendige kald til kommandoen blev elimineret (den blev udført ved hver hentning af blobber), og caching blev tilføjet, hvor det var muligt. Derefter blev der udført omfattende ydelsestest og hastigheden af App Registry blev sammenlignet før og efter ændringerne. tar API-forespørgsler, som tidligere tog op til halvmidt, blev nu udført på millisekunder

. I næste uge udrullede vi ændringerne i produktion, og siden da har quay.io fungeret stabilt. I denne periode blev der observeret flere skarpe trafikstigninger på endepunktet for App Registry, men de forbedringer, vi havde lavet, forhindrede nedbrud i databasen.Det er tydeligt, at enhver tjeneste stræber efter at undgå nedetid. I vores tilfælde mener vi, at de nylige nedbrud har hjulpet med at gøre quay.io bedre. Vi har lært nogle vigtige lektioner, som vi gerne vil dele:

Hvad har vi lært?

Data om hvem og hvordan man bruger din tjeneste er aldrig overflødige.

  1. Da Quay "bare fungerede", havde vi aldrig behov for at bruge tid på at optimere trafikken og styre belastningen. Alt dette skabte en falsk følelse af sikkerhed, at tjenesten kunne skaleres ubegribeligt.Når en tjeneste går ned,
  2. er det at få den op at køre igen den højeste prioritet. at genoprette dets funktion er den højeste prioritet. Da Quay fortsatte med at lide af en blokeret database under det første nedbrud, havde vores standardprocedurer ikke den forventede effekt, og vi kunne ikke genoprette tjenesten ved hjælp af dem. Dette førte til en situation, hvor vi måtte bruge tid på at analysere og indsamle data i håbet om at finde årsagen — i stedet for at fokusere alle vores kræfter på at genoprette funktionaliteten.
  3. Vurder indflydelsen af hver funktion i tjenesten. Kunderne brugte sjældent App Registry, så det var ikke en prioritet for vores team. Når visse produktfunktioner næsten ikke bliver brugt, opstår deres fejl sjældent, og udviklerne stopper med at overvåge koden. Det er nemt at falde for misforståelsen om, at det er som det skal være — indtil denne funktion pludselig står i centrum af en stor hændelse.

Hvad nu?

Arbejdet med at sikre tjenestens stabilitet stopper aldrig, og vi forbedrer konstant den. Trafikmængden på quay.io fortsætter med at stige, og vi er klar over, at vi skal gøre alt, hvad vi kan, for at leve op til kundernes tillid. Derfor arbejder vi i øjeblikket på følgende opgaver:

  1. Udrulning af kun-læse database-replikaer for at hjælpe tjenesten med at håndtere den relevante trafik i tilfælde af problemer med den primære RDS-instans.
  2. Opdatering af RDS-instansen. Den nuværende version er ikke i sig selv et problem. Snarere ønsker vi blot at fjerne et falsk spor (som vi fulgte under nedbruddet); at holde softwaren opdateret vil fjerne endnu en faktor for fremtidige nedbrud.
  3. Yderligere caching på tværs af klyngen. Vi fortsætter med at søge efter områder, hvor caching kan reducere belastningen på databasen.
  4. Tilføjelse af en webapplikationsfirewall (WAF) for at se, hvem der tilslutter sig quay.io, og hvorfor.
  5. Fra næste release vil Red Hat OpenShift-klyngerne opgive App Registry til fordel for operator kataloger baseret på containerbilleder tilgængelige på quay.io.
  6. En langsigtet erstatning for App Registry kan være understøttelse af Open Container Initiative (OCI) artefakt specifikationer. Dette implementeres i øjeblikket som en indbygget funktion i Quay og vil være tilgængeligt for brugerne, når specifikationen er endeligt aftalt.

Alt det ovenstående er en del af Red Hats fortsatte investeringer i quay.io, efterhånden som vi går fra et lille "startup-agtigt" team til en moden platform drevet af SRE. Vi er klar over, at mange af vores kunder, inklusive Red Hat, er afhængige af quay.io i deres daglige arbejde, og vi stræber efter at være så åbne som muligt om de seneste driftsforstyrrelser og vores fortsatte bestræbelser på at forbedre os.

P.S. fra oversætteren

Læs også på vores blog:

Kilde: habr.com

Køb pålidelig webhosting med DDoS-beskyttelse, VPS VDS-servere 🔥 Køb pålidelig webhosting med DDoS-beskyttelse, VPS VDS-servere | ProHoster