Post Mortem om nedetid på Quay.io

Obs. overs.: i begynnelsen av august offentliggjorde Red Hat løsningen på tilgjengelighetsproblemene som hadde oppstått de foregående månedene for brukerne av deres tjeneste. Quay.io (med en containerbilderegister som kom til selskapet med oppkjøpet av CoreOS). Uansett hvor interessert man er i denne tjenesten som sådan, er veien som SRE-ingeniørene i selskapet har tatt for å diagnostisere og løse årsakene til krasjet, lærerik.

Post Mortem om nedetid på Quay.io

19. mai, tidlig om morgenen (ifølge sommertiden i Nord-Amerika, EDT), falt tjenesten quay.io. Ulykken påvirket både brukerne av quay.io og Open Source-prosjektene som bruker quay.io som plattform for bygging og distribusjon av programvare. Red Hat verdsetter tilliten fra begge parter.

SRE-ingeniørteamet grep straks inn for å stabilisere tjenesten Quay så raskt som mulig. Imidlertid mens de gjorde dette, mistet kundene muligheten til å pushe nye bilder, og de klarte bare sporadisk å pull’e eksisterende. Av en ukjent grunn ble databasen quay.io blokkert etter at tjenesten ble skalert opp til full kapasitet.

«Hva har endret seg?» — dette er det første spørsmålet som vanligvis stilles i slike tilfeller. Vi la merke til at kort tid før problemet begynte, begynte OpenShift Dedicated-klyngen (som quay.io opererer på) å oppdatere til versjon 4.3.19. Siden quay.io kjører på Red Hat OpenShift Dedicated (OSD), var regelmessige oppdateringer en vanlig operasjon og hadde aldri ført til problemer. Dessuten hadde vi flere ganger oppdatert Quay-klyngene de siste seks månedene uten noen nedetid.

Mens vi forsøkte å gjenopprette tjenesten, begynte andre ingeniører å forberede en ny OSD-klynge med en tidligere versjon av programvaren, slik at de kunne rulle ut alt på den om nødvendig.

Analyse av rotårsaken

Det primære symptomet på feilen var en flom av tiotusener av tilkoblinger til databasen, som gjorde at MySQL-instansen faktisk ble unyttbar. Dette gjorde det vanskelig å diagnostisere problemet. Vi satte en grense for det maksimale antallet tilkoblinger fra klientene for å hjelpe SRE-teamet med å vurdere problemet. Ingen uvanlig trafikk til databasen ble lagt merke til: faktisk var de fleste forespørslene leseforespørsel, og bare noen få var skriveforespørsel.

Vi forsøkte også å avdekke et mønster i DB-trafikken som kunne ha forårsaket denne nedgangen. Imidlertid fant vi ingen regelmessigheter i loggene. Mens vi ventet på at den nye klyngen med OSD 4.3.18 skulle bli klar, fortsatte vi forsøkene på å starte pod'ene quay.io. Hver gang klyngen nådde full kapasitet, frøs databasen. Dette betydde at vi måtte starte RDS-instansen på nytt i tillegg til alle pod'ene quay.io.

Om kvelden stabiliserte vi tjenesten i read-only-modus og slo av så mange unødvendige funksjoner som mulig (for eksempel søppeloppsamling i navnerommet) for å redusere belastningen på databasen. Frysingene opphørte, men årsaken ble aldri funnet.. Den nye OSD-klyngen var klar, og vi flyttet tjenesten, koblet trafikken, og fortsatte overvåkningen.

Quay.io fungerte stabilt på den nye OSD-klyngen, så vi gikk tilbake til databaseloggene, men klarte ikke å finne noen korrelasjon som forklarte blokkeringen. Ingeniører fra OpenShift jobbet sammen med oss for å forsøke å forstå om endringene i Red Hat OpenShift 4.3.19 kunne ha forårsaket problemene med Quay. Imidlertid ble det ikke oppdaget noe, og det var ikke mulig å gjenskape problemet i laboratorium..

Det andre feiltrinnet

28. mai, rett før middagstid EDT, falt quay.io igjen med samme symptom: databasen frøs. N igjen satte vi inn all vår innsats på etterforskning. Først og fremst var det nødvendig å gjenopprette drift av tjenesten. Imidlertid førte ikke omstart av RDS og oppstart av pod'ene quay.io denne gangen til noe resultat: et nytt bølgeslag av tilkoblinger oversvømte databasen. Men hvorfor?Quay er skrevet i Python, og hver pod fungerer som en enhetlig monolittisk beholder. I containerens kjøremiljø kjøres mange samtidige oppgaver samtidig. Vi bruker biblioteket

gevent gunicorn under til å håndtere webforespørslene. Når Quay mottar en forespørsel (via vårt eget API eller gjennom Docker API), tildeles det en gevent-arbeider. Vanligvis må denne arbeideren kontakte databasen. Etter det første feilet oppdaget vi at gevent-arbeiderne koblet seg til databasen ved å bruke standardinnstillingene. for å håndtere webforespørslene. Når Quay mottar en forespørsel (via vårt eget API, eller via Docker API), tildeles en gevent worker. Vanligvis skal denne workeren kontakte databasen. Etter den første krasjingen oppdaget vi at gevent workerne koblet seg til databasen ved å bruke standardinnstillingene.

Med tanke på det betydelige antallet Quay-poder og tusenvis av innkommende forespørselen per sekund, kunne det store antallet databaseforbindelser teoretisk overbelaste MySQL-instansen. Gjennom overvåking var det kjent at Quay i snitt håndterer 5000 forespørselen per sekund. Det omtrentlige tallet for databaseforbindelser var det samme. 5000 forbindelser passet innenfor kapasiteten til vår RDS-instans (noe som ikke kan sies om titusenvis). Av en eller annen grunn skjedde det uventede utbrudd av antall forbindelser, men vi la ikke merke til noen korrelasjon med innkommende forespørselen.

Denne gangen bestemte vi oss for å finne og løse årsaken til problemet, i stedet for bare å begrense oss til omstart. Det ble gjort endringer i Quay-koden som begrenset antallet databaseforbindelser for hver worker gevent. Dette tallet ble en parameter i konfigurasjonen: det ble mulig å endre det "on-the-fly", uten å måtte bygge et nytt containerbilde. For å finne ut hvor mange forbindelse som faktisk kunne håndteres, ble det gjennomført flere tester med staging-miljøet, hvor ulike verdier ble satt for å se hvordan dette ville påvirke belastningstestscenariene. Til slutt ble det oppdaget at Quay begynte å gi feilmeldinger 502 når antallet forbindelser oversteg 10 000.

Vi rullet straks ut denne nye versjonen i produksjon og begynte å overvåke grafen for databaseforbindelser. Tidligere ble databasen låst omtrent etter 20 minutter. Etter 30 problemfrie minutter hadde vi håp, og etter en time – selvtillit. Vi gjenopprettet skrive trafikken på nettstedet og begynte på post-mortem analysen.

Ved å omgå problemet som førte til låsingen, fikk vi ikke klarlagt de reelle årsakene. Det ble bekreftet at det ikke var relatert til noen endringer i OpenShift 4.3.19, da det samme skjedde i versjon 4.3.18, som tidligere hadde fungert med Quay uten problemer.

Det var åpenbart noe annet som var skjult i klyngen.

En grundig undersøkelse

Quay.io har brukt standardinnstillinger for tilkobling til databasen uten problemer i seks år. Hva har endret seg? Det er tydelig at trafikken til quay.io har økt jevnt i hele denne tiden. I vårt tilfelle så det ut som om vi nådde et terskelverdi som utløste en lavine av tilkoblinger. Vi fortsatte å undersøke database-loggene etter det andre krasjet, men vi fant ingen mønstre eller åpenbare sammenhenger.

I mellomtiden arbeidet SRE-teamet med forbedringer innen observasjon av forespørslene i Quay og den generelle helsen til tjenesten. Nye metrikker og overvåkningsdashbord, som viser hvilke deler av Quay som er mest etterspurt av kundene.

Quay.io fungerte normalt frem til 9. juni. Om morgenen (i EDT) så vi igjen en betydelig økning i antall tilkoblinger til databasen. Denne gangen oppstod det ikke noen nedetid, ettersom den nye parameteren begrenset antallet og hindret det i å overstige MySQLs kapasitet. Imidlertid rapporterte mange brukere om treghet på quay.io i omtrent en halvtime. Vi samlet raskt så mye data som mulig, ved hjelp av de nye overvåkingsverktøyene. Plutselig viste det seg å være et mønster.

Før hoppen i antall tilkoblinger, kom et stort antall forespørslene til App Registry API. App Registry er en lite kjent funksjon på quay.io. Den gjør det mulig å lagre ting som Helm-diagrammer og containere med rike metadata. De fleste brukere av quay.io arbeider ikke med denne funksjonen, men den benyttes aktivt av Red Hat OpenShift. OperatorHub som er en del av OpenShift lagrer alle operatorene i App Registry. Disse operatorene danner grunnlaget for OpenShift arbeidsbelastningsøkosystem og operasjonsmodellen (i forhold til "andre driftsdag" operasjoner, Day 2), fokusert på partnere.

Hver OpenShift 4-klynge bruker operatorer fra den innebygde OperatorHub for å publisere katalogen over tilgjengelige operatorer for installasjon og gi oppdateringer for allerede installerte. Etter hvert som populariteten til OpenShift 4 har økt, har også antallet klynger på det økt over hele verden. Hver av disse klyngene laster inn innholdet fra operatorene for å starte den innebygde OperatorHub ved å bruke App Registry inne i quay.io som backend. I jakta etter årsaken til problemet, mistet vi faktumet at med den gradvise økningen i popularitet for OpenShift, økte også belastningen på en av de sjeldent brukte funksjonene quay.io..

Vi utførte en viss analyse av trafikken til App Registry og tok en titt på koden til registret. Umiddelbart ble svakheter avdekket som førte til at databaseforespørslene ble dannet suboptimalt. Under lav belastning forårsaket de ingen problemer, men når belastningen økte, ble de en kilde til problemer. App Registry hadde to problematiske endepunkter som reagerte dårlig på økt belastning: den første ga en liste over alle pakker i depotet, den andre returnerte alle blob-er for pakken.

Årsaksbekjempelse

Hele den påfølgende uken jobbet vi med å optimalisere koden til App Registry og omgivelsene. Åpenbart ineffektive SQL-forespørslene ble omarbeidet, unødvendige kall til kommandoen ble fjernet curl (. den ble kjørt ved hver henting av blob-er), caching ble lagt til overalt der det var mulig. Deretter ble det utført omfattende ytelsestesting og hastigheten på App Registry ble sammenlignet før og etter endringene.

API-forespørslene som tidligere tok opptil et halvt minutt, ble nå utført på millisekunder.. I løpet av den påfølgende uken distribuerte vi endringene i produksjon, og siden har quay.io fungert stabilt. I løpet av denne tiden har vi observert flere kraftige trafikktopper på endepunktet til App Registry, men de forbedringene vi gjorde, forhindret nedetid i databasen.

Hva har vi lært?

Det er klart at enhver tjeneste prøver å unngå nedetid. I vårt tilfelle tror vi at de nylige avbruddene har gjort quay.io bedre. Vi har lært flere viktige lekser som vi ønsker å dele:

  1. Data om hvem og hvordan folk bruker tjenesten din er aldri overflødige.Siden Quay "bare fungerte", hadde vi aldri behov for å bruke tid på å optimalisere trafikken og administrere belastningen. Alt dette skapte en falsk følelse av sikkerhet, at tjenesten kunne skaleres uendelig.
  2. Når en tjeneste går ned, å gjenopprette dens funksjon er vår hovedprioritet.. Sidan Quay fortsatte att lida av en blockerad databas under det första felet hade våra standardprocedurer inte den förväntade effekten och vi kunde inte återställa tjänsten med dem. Det ledde till en situation där vi tvingades spendera tid på att analysera och samla in data i hopp om att hitta den grundläggande orsaken – istället för att rikta all vår ansträngning mot att återställa funktionaliteten.
  3. Utvärdera påverkan av varje funktion i tjänsten. Kunder använde sällan App Registry, så det var inte en prioritet för vårt team. När vissa produktfunktioner nästan inte används, dyker buggar sällan upp, och utvecklarna slutar att övervaka koden. Det är lätt att bli offer för missuppfattningen att det är som det borde vara – tills plötsligt den funktionen hamnar i centrum för en stor incident.

Hva skjer videre?

Arbetet för att säkerställa tjänstens stabilitet pågår ständigt och vi förbättrar den hela tiden. Trafikmängderna på quay.io fortsätter att växa, och vi är medvetna om att vi måste göra allt vi kan för att förtjäna kundernas förtroende. Därför arbetar vi för närvarande med följande uppgifter:

  1. Distribution av skrivskyddade databas-repliker för att hjälpa tjänsten att hantera relevant trafik vid problem med huvudinstansen RDS.
  2. Uppdatering av RDS-instansen. Den nuvarande versionen är inte i sig ett problem. Snarare vill vi bara ta bort en falsk ledtråd (som vi följde under felet); att hålla mjukvaran uppdaterad hjälper till att eliminera ännu en faktor för framtida avbrott.
  3. Ytterligare caching över hela klustret. Vi fortsätter att leta efter områden där caching kan minska belastningen på databasen.
  4. Tillägg av en webbapplikationsbrandvägg (WAF) för att se vem och varför som ansluter till quay.io.
  5. Från och med nästa release kommer Red Hat OpenShift-kluster att överge App Registry till förmån för operatorkataloger baserade på containerbilder som är tillgängliga på quay.io.
  6. En långsiktig ersättning för App Registry kan vara stöd för specifikationerna för artefakter från Open Container Initiative (OCI). För närvarande implementeras det som en inbyggd funktionalitet i Quay och kommer att vara tillgänglig för användare när specifikationen slutgiltigt godkänns.

Alt dette er en del av de pågående investeringene fra Red Hat i quay.io, ettersom vi går fra et lite «spirende» team til en moden plattform drevet av SRE. Vi vet at mange av våre kunder, inkludert Red Hat selv, er avhengige av quay.io i sitt daglige arbeid, og vi jobber hardt for å være så åpne som mulig om nylige avbrudd og pågående innsats for å bli bedre.

P.S. from the translator

Also read in our blog:

Kilde: habr.com

Kjøp pålitelig hosting for nettsteder med DDoS-beskyttelse, VPS VDS-servere 🔥 Kjøp pålitelig hosting for nettsteder med DDoS-beskyttelse, VPS VDS-servere | ProHoster