En utrullningshistoria som påverkade allt

En utrullningshistoria som påverkade allt
Verklighetens fiender av 12f-2

I slutet av april, medan White Walkers belägrade Winterfell, hände något mer intressant med oss, vi gjorde en ovanlig utbyggnad. I princip rullar vi hela tiden ut nya funktioner i produktion (som alla andra). Men den här var annorlunda. Omfattningen av den var sådan att alla potentiella misstag som vi kunde göra skulle påverka alla våra tjänster och användare. Det gjorde att vi rullade ut allt enligt plan, inom den planerade och aviserade stilleståndsperioden, utan konsekvenser för försäljningen. Artikeln handlar om hur vi uppnådde detta och hur vem som helst kan upprepa det hemma.

Jag ska nu inte beskriva de arkitektoniska och tekniska beslut vi tog eller berätta hur det hela fungerar. Det här är snarare anteckningar i marginalen om hur en av de svåraste utrullningarna gick till, som jag observerade och som jag var direkt involverad i. Jag hävdar inte fullständighet eller tekniska detaljer, kanske kommer de att dyka upp i en annan artikel.

Bakgrund + vad är detta för funktionalitet?

Vi bygger en molnplattform Mail.ru molnlösningar (MCS), där jag arbetar som teknisk direktör. Och nu är det dags att lägga till IAM (Identity and Access Management) till vår plattform, som ger enhetlig hantering av alla användarkonton, användare, lösenord, roller, tjänster och mer. Varför det behövs i molnet är en uppenbar fråga: all användarinformation lagras i det.

Vanligtvis börjar sådana saker byggas i början av alla projekt. Men historiskt sett har det varit lite annorlunda i MCS. MCS byggdes i två delar:

  • Openstack med sin egen Keystone-auktoriseringsmodul,
  • Hotbox (S3-lagring) baserad på Mail.ru Cloud-projektet,

kring vilka nya tjänster sedan dök upp.

I huvudsak var det två olika typer av auktorisation. Dessutom använde vi några separata Mail.ru-utvecklingar, till exempel en allmän Mail.ru-lösenordslagring, såväl som en självskriven openid-anslutning, tack vare vilken SSO (end-to-end-auktorisering) tillhandahölls i Horizon-panelen av virtuella maskiner (native OpenStack UI).

Att göra IAM åt oss innebar att koppla ihop allt till ett enda system, helt vårt eget. Samtidigt kommer vi inte att förlora någon funktionalitet på vägen, utan kommer att skapa en grund för framtiden som gör att vi på ett transparent sätt kan förfina den utan att omfaktorisera och skala den funktionsmässigt. Även i början hade användarna en förebild för tillgång till tjänster (central RBAC, rollbaserad åtkomstkontroll) och lite andra småsaker.

Uppgiften visade sig vara icke-trivial: python och perl, flera backends, oberoende skrivna tjänster, flera utvecklingsteam och admins. Och viktigast av allt, det finns tusentals live-användare på stridsproduktionssystemet. Allt detta måste skrivas och, viktigast av allt, rullas ut utan skadade.

Vad ska vi rulla ut?

För att uttrycka det väldigt grovt, på cirka 4 månader förberedde vi följande:

  • Vi skapade flera nya demoner som aggregerade funktioner som tidigare fungerade i olika delar av infrastrukturen. Resten av gudstjänsterna ordinerades en ny backend i form av dessa demoner.
  • Vi skrev vår egen centrala lagring av lösenord och nycklar, tillgängliga för alla våra tjänster, som fritt kan modifieras efter behov.
  • Vi skrev 4 nya backends för Keystone från grunden (användare, projekt, roller, rolltilldelningar), som i själva verket ersatte dess databas och nu fungerar som ett enda arkiv för våra användarlösenord.
  • Vi lärde alla våra Openstack-tjänster att gå till en tredjepartspolicytjänst för deras policyer istället för att läsa dessa policyer lokalt från varje server (ja, det är så Openstack fungerar som standard!)

En sådan stor omarbetning kräver stora, komplexa och, viktigast av allt, synkrona förändringar i flera system skrivna av olika utvecklingsteam. När det väl är monterat ska hela systemet fungera.

Hur rullar man ut sådana förändringar och inte skruvar ihop det? Först bestämde vi oss för att se lite in i framtiden.

Utbyggnadsstrategi

  • Det skulle vara möjligt att rulla ut produkten i flera steg, men det skulle öka utvecklingstiden med tre gånger. Dessutom skulle vi under en tid ha fullständig avsynkronisering av data i databaserna. Du skulle behöva skriva dina egna synkroniseringsverktyg och leva med flera datalager under lång tid. Och detta skapar en mängd olika risker.
  • Allt som kunde förberedas transparent för användaren gjordes i förväg. Det tog 2 månader.
  • Vi tillät oss driftstopp i flera timmar – bara för användaroperationer för att skapa och ändra resurser.
  • För driften av alla redan skapade resurser var driftstopp oacceptabelt. Vi planerade att under utrullningen skulle resurserna fungera utan driftstopp och påverka för kunderna.
  • För att minska påverkan på våra kunder om något går fel beslutade vi att rulla ut på söndagskvällen. Färre kunder hanterar virtuella maskiner på natten.
  • Vi varnade alla våra kunder att servicehantering kommer att vara otillgänglig under den period som valts för utrullning.

Utvikning: vad är en utrullning?

<försiktighet, filosofi>

Varje IT-specialist kan enkelt svara på vad en utrullning är. Du installerar CI/CD, och allt levereras automatiskt till butiken. 🙂

Naturligtvis är detta sant. Men svårigheten är att med moderna verktyg för kodleveransautomation går förståelsen för själva utrullningen förlorad. Hur du glömmer det episka med uppfinningen av hjulet när du tittar på modern transport. Allt är så automatiserat att utrullningen ofta genomförs utan att man förstår helheten.

Och hela bilden är så här. Utbyggnaden består av fyra huvudaspekter:

  1. Leverans av kod, inklusive datamodifiering. Till exempel deras migrationer.
  2. Kodåterställning är möjligheten att gå tillbaka om något går fel. Till exempel genom att skapa säkerhetskopior.
  3. Tid för varje utrullning/återställning. Du måste förstå tidpunkten för varje operation av de första två punkterna.
  4. Berörd funktionalitet. Det är nödvändigt att utvärdera både de förväntade positiva och möjliga negativa effekterna.

Alla dessa aspekter måste beaktas för en framgångsrik utbyggnad. Vanligtvis bedöms bara den första, eller i bästa fall den andra, poängen, och sedan anses utbyggnaden vara framgångsrik. Men trean och fjärden är ännu viktigare. Vilken användare skulle vilja ha det om lanseringen tog 3 timmar istället för en minut? Eller om något onödigt påverkas under utrullningen? Eller kommer driftstopp för en tjänst att leda till oförutsägbara konsekvenser?

Akt 1..n, förberedelse för frigivning

Först tänkte jag kortfattat beskriva våra möten: hela teamet, dess delar, mängder av diskussioner vid fika, argument, tester, brainstorms. Då tänkte jag att det skulle vara onödigt. Fyra månaders utveckling består alltid av detta, speciellt när du inte skriver något som kan levereras konstant, utan en stor funktion för ett livesystem. Vilket påverkar alla tjänster, men ingenting bör förändras för användarna förutom "en knapp i webbgränssnittet."

Vår förståelse för hur man rullar ut förändrades från varje nytt möte, och det var ganska markant. Vi skulle till exempel uppdatera hela vår faktureringsdatabas. Men vi räknade ut tiden och insåg att det var omöjligt att göra detta på en rimlig utrullningstid. Det tog oss nästan en extra vecka att skära och arkivera faktureringsdatabasen. Och när den förväntade utrullningshastigheten fortfarande inte var tillfredsställande beställde vi ytterligare, kraftfullare hårdvara, där hela basen släpades. Det är inte så att vi inte ville göra det här tidigare, men det nuvarande behovet av att rulla ut gjorde att vi inte hade några alternativ.

När en av oss tvivlade på att utbyggnaden skulle kunna påverka tillgängligheten för våra virtuella maskiner, tillbringade vi en vecka med att genomföra tester, experiment, kodanalys och fick en klar förståelse för att detta inte skulle hända i vår produktion, och även de mest tveksamma personerna höll med om med detta.

Under tiden genomförde killarna från teknisk support sina egna oberoende experiment för att skriva instruktioner till klienter om anslutningsmetoder, som skulle ändras efter utrullningen. De arbetade med användar-UX, utarbetade instruktioner och gav personliga konsultationer.

Vi automatiserade alla utrullningsoperationer som var möjliga. Varje operation var skriptad, även de enklaste, och tester kördes ständigt. De bråkade om det bästa sättet att stänga av tjänsten - utelämna demonen eller blockera åtkomst till tjänsten med en brandvägg. Vi skapade en checklista med team för varje steg i utbyggnaden och uppdaterade den kontinuerligt. Vi ritade och uppdaterade ständigt ett Gantt-diagram för allt utrullningsarbete, med tidpunkter.

Och så…

Sista akten, innan den rullas ut

...det är dags att rulla ut.

Som de säger, ett konstverk kan inte slutföras, bara färdigt arbeta på det. Du måste anstränga dig av vilja, förstå att du inte kommer att hitta allt, men att tro att du har gjort alla rimliga antaganden, försett alla möjliga fall, stängt alla kritiska buggar och alla deltagare gjorde allt de kunde. Ju mer kod du rullar ut, desto svårare är det att övertyga dig själv om detta (dessutom förstår alla att det är omöjligt att förutse allt).

Vi bestämde oss för att vi var redo att rulla ut när vi var övertygade om att vi hade gjort allt för att täcka alla risker för våra användare i samband med oväntade effekter och stillestånd. Det vill säga allt kan gå fel förutom:

  1. Påverka (heligt för oss, mest värdefulla) användarinfrastruktur,
  2. Funktionalitet: användningen av vår tjänst efter lanseringen bör vara densamma som före den.

Rulla ut

En utrullningshistoria som påverkade allt
Två kast, 8 stör inte

Vi tar driftstopp för alla förfrågningar från användare i 7 timmar. För närvarande har vi både en utrullningsplan och en återställningsplan.

  • Själva utrullningen tar cirka 3 timmar.
  • 2 timmar för testning.
  • 2 timmar - reservera för en eventuell återställning av ändringar.

Ett Gantt-diagram har tagits fram för varje åtgärd, hur lång tid det tar, vad som händer sekventiellt, vad som görs parallellt.

En utrullningshistoria som påverkade allt
En del av ett utrullning av Gantt-diagram, en av de tidiga versionerna (utan parallell exekvering). Det mest värdefulla synkroniseringsverktyget

Alla deltagare har sin roll i utbyggnaden bestämd, vilka uppgifter de gör och vad de är ansvariga för. Vi försöker få varje steg till automatik, rulla ut, rulla tillbaka, samla feedback och rulla ut igen.

Krönika av händelser

Så, 15 personer kom till jobbet söndagen den 29 april klockan 10. Förutom nyckeldeltagarna kom några helt enkelt för att stötta laget, vilket särskilt tack till dem.

Det är också värt att nämna att vår nyckeltestare är på semester. Det är omöjligt att rulla ut utan att testa, vi undersöker alternativ. En kollega går med på att testa oss från semestern, vilket hon får enorm tacksamhet från hela teamet.

00:00. Sluta
Vi stoppar användarförfrågningar, hänger upp en skylt som säger tekniskt arbete. Övervakningen skriker, men allt är normalt. Vi kontrollerar att inget ramlat mer än det som skulle falla. Och vi börjar arbetet med migration.

Alla har en utskriven utrullningsplan punkt för punkt, alla vet vem som gör vad och i vilket ögonblick. Efter varje åtgärd kontrollerar vi tiderna för att säkerställa att vi inte överskrider dem, och allt går enligt plan. De som inte deltar i utrullningen direkt i det aktuella skedet förbereder sig genom att lansera en onlineleksak (Xonotic, typ 3 kvacksalvare) för att inte störa sina kollegor. 🙂

02:00. Utrullad
En trevlig överraskning - vi avslutar utrullningen en timme tidigare, på grund av optimeringen av våra databaser och migreringsskript. Det allmänna ropet, "rullade ut!" Alla nya funktioner är under produktion, men än så länge kan bara vi se dem i gränssnittet. Alla går in i testläge, sorterar dem i grupper och börjar se vad som hände till slut.

Det blev inte särskilt bra, vi inser detta efter 10 minuter, när ingenting är uppkopplat eller fungerar i teammedlemmarnas projekt. Snabb synkronisering, vi uttrycker våra problem, sätter prioriteringar, bryter in i team och går in i felsökning.

02:30. Två stora problem kontra fyra ögon
Vi hittar två stora problem. Vi insåg att kunderna inte skulle se vissa anslutna tjänster och problem skulle uppstå med partnerkonton. Båda beror på ofullkomliga migreringsskript för vissa edge-fall. Vi måste fixa det nu.

Vi skriver frågor som registrerar detta, med minst 4 ögon. Vi testar dem under förproduktionen för att se till att de fungerar och inte går sönder något. Du kan rulla på. Samtidigt kör vi vårt regelbundna integrationstest, som avslöjar några fler problem. De är alla små, men de måste också repareras.

03:00. -2 problem +2 problem
De två tidigare stora problemen har åtgärdats, och nästan alla mindre också. Alla de som är lediga i fixar arbetar aktivt i sina konton och rapporterar vad de hittar. Vi prioriterar, fördelar mellan teamen och lämnar icke-kritiska saker till morgonen.

Vi kör testerna igen, de upptäcker två nya stora problem. Alla tjänstepolicyer kom inte fram korrekt, så vissa användarförfrågningar godkänns inte. Plus ett nytt problem med partnerkonton. Låt oss skynda oss att titta.

03:20. Nödsynkronisering
Ett nytt problem fixat. För det andra organiserar vi en nödsynkronisering. Vi förstår vad som händer: den tidigare fixen fixade ett problem, men skapade ett annat. Vi tar en paus för att ta reda på hur vi gör det korrekt och utan konsekvenser.

03:30. Sex ögon
Vi förstår vad det slutliga tillståndet för basen ska vara så att allt går bra för alla partners. Vi skriver en förfrågan med 6 ögon, rullar ut i förproduktion, testar, rullar ut för produktion.

04:00. Allt fungerar
Alla tester godkända, inga kritiska problem är synliga. Då och då är det något i teamet som inte fungerar för någon, vi reagerar snabbt. Oftast är larmet falskt. Men ibland kommer något inte fram, eller så fungerar inte en separat sida. Vi sitter, fixar, fixar, fixar. Ett separat team lanserar den sista stora funktionen – fakturering.

04:30. Ingen återvändo
Point of no return närmar sig, det vill säga tiden då vi, om vi börjar rulla tillbaka, inte kommer att möta den stilleståndstid som vi fått. Det finns problem med fakturering, som vet och registrerar allt, men envist vägrar att skriva av pengar från kunder. Det finns flera buggar på enskilda sidor, åtgärder och statusar. Huvudfunktionen fungerar, alla tester passerar framgångsrikt. Vi beslutar att utrullningen har skett, vi kommer inte att rulla tillbaka.

06:00. Öppet för alla i användargränssnittet
Buggar fixade. Vissa som inte tilltalar användarna lämnas till senare. Vi öppnar gränssnittet för alla. Vi fortsätter att arbeta med fakturering, väntar på feedback från användare och bevakar resultat.

07:00. Problem med API-belastning
Det blir tydligt att vi missplanerade belastningen på vårt API något och testade denna belastning, vilket inte kunde identifiera problemet. Som ett resultat misslyckas ≈5 % av förfrågningarna. Låt oss mobilisera och leta efter anledningen.

Fakturering är envis och vill inte heller fungera. Vi beslutar att skjuta upp det till senare för att genomföra förändringarna på ett lugnt sätt. Det vill säga alla resurser samlas i den, men avskrivningar från klienter går inte igenom. Naturligtvis är detta ett problem, men jämfört med den allmänna utrullningen verkar det oviktigt.

08:00. Fixa API
Vi rullade ut en fix för lasten, misslyckandena försvann. Vi börjar gå hem.

10:00. Allt
Allt är fixat. Det är tyst i övervakningen och hos kunderna går teamet gradvis och lägger sig. Faktureringen kvarstår, vi återställer den imorgon.

Sedan under dagen skedde utrullningar som fixade loggar, aviseringar, returkoder och anpassningar för några av våra kunder.

Så lanseringen lyckades! Det kunde naturligtvis vara bättre, men vi drog slutsatser om vad som inte räckte för att vi skulle uppnå perfektion.

Totalt

Under 2 månaders aktiva förberedelser inför utrullningen genomfördes 43 uppgifter, som varade från ett par timmar till flera dagar.

Under lanseringen:

  • nya och ändrade demoner - 5 stycken, ersätter 2 monoliter;
  • ändringar i databaserna - alla våra 6 databaser med användardata har påverkats, nedladdningar har gjorts från tre gamla databaser till en ny;
  • helt omgjord frontend;
  • mängd nedladdad kod - 33 tusen rader ny kod, ≈ 3 tusen rader kod i tester, ≈ 5 tusen rader migrationskod;
  • all data är intakt, inte en enda kunds virtuella maskin skadades. 🙂

Goda rutiner för bra utbyggnad

De vägledde oss i denna svåra situation. Men generellt sett är det användbart att följa dem under alla utrullningar. Men ju mer komplex utbyggnaden är, desto större roll spelar de.

  1. Det första du behöver göra är att förstå hur utbyggnaden kan eller kommer att påverka användarna. Blir det stillestånd? Om så är fallet, vad är stilleståndstiden? Hur kommer detta att påverka användarna? Vilka är de möjliga bästa och värsta scenarierna? Och täcka riskerna.
  2. Planera allt. I varje steg måste du förstå alla aspekter av lanseringen:
    • kod leverans;
    • kod återställning;
    • tidpunkt för varje operation;
    • påverkad funktionalitet.
  3. Spela igenom scenarierna tills alla stadier av utrullningen, såväl som riskerna vid var och en av dem, blir uppenbara. Om du har några tvivel kan du ta en paus och undersöka det tveksamma stadiet separat.
  4. Varje steg kan och bör förbättras om det hjälper våra användare. Det kommer till exempel att minska stilleståndstiden eller ta bort vissa risker.
  5. Återställningstestning är mycket viktigare än kodleveranstestning. Det är nödvändigt att kontrollera att systemet som ett resultat av återställningen kommer att återgå till sitt ursprungliga tillstånd och bekräfta detta med tester.
  6. Allt som kan automatiseras bör automatiseras. Allt som inte kan automatiseras bör skrivas i förväg på ett fuskark.
  7. Anteckna framgångskriteriet. Vilken funktionalitet ska finnas tillgänglig och vid vilken tidpunkt? Om detta inte händer, kör en återställningsplan.
  8. Och viktigast av allt - människor. Alla bör vara medvetna om vad de gör, varför och vad som beror på deras handlingar i utbyggnadsprocessen.

Och i en mening, med god planering och genomarbetning kan du rulla ut vad du vill utan konsekvenser för försäljningen. Även något som kommer att påverka alla dina tjänster i produktionen.

Källa: will.com

Lägg en kommentar