Hur man bygger en fullfjädrad intern utveckling med hjälp av DevOps - VTB-upplevelse

DevOps praxis fungerar. Vi var själva övertygade om detta när vi minskade installationstiden för release med 10 gånger. I FIS Profile-systemet, som vi använder på VTB, tar installationen nu 90 minuter istället för 10. Release-byggtiden har minskat från två veckor till två dagar. Antalet ihållande implementeringsfel har sjunkit till nästan ett minimum. För att komma bort från "manuellt arbete" och eliminera beroendet av leverantören var vi tvungna att arbeta med kryckor och hitta oväntade lösningar. Nedanför snittet finns en detaljerad berättelse om hur vi byggde upp en fullfjädrad intern utveckling.

Hur man bygger en fullfjädrad intern utveckling med hjälp av DevOps - VTB-upplevelse
 

Prolog: DevOps är en filosofi

Under det senaste året har vi gjort mycket arbete för att organisera den interna utvecklingen och implementeringen av DevOps-praxis på VTB:

  • Vi byggde interna utvecklingsprocesser för 12 system;
  • Vi lanserade 15 pipelines, varav fyra togs i produktion;
  • Automatiserade 1445 testscenarier;
  • Vi har framgångsrikt implementerat ett antal versioner förberedda av interna team.

En av de svåraste att organisera intern utveckling och implementering av DevSecOps-praxis visade sig vara FIS Profile-systemet - en detaljhandelsproduktprocessor på ett icke-relationellt DBMS. Ändå kunde vi bygga utvecklingen, lansera pipeline, installera individuella icke-release-paket på produkten och lära oss hur man sätter ihop releaser. Uppgiften var inte lätt, men intressant och utan uppenbara begränsningar i implementeringen: här är systemet - du måste bygga en egen utveckling. Det enda villkoret är att använda CD:n innan en produktiv miljö.

Till en början verkade implementeringsalgoritmen enkel och tydlig:

  • Vi utvecklar inledande utvecklingsexpertis och uppnår en acceptabel kvalitetsnivå från kodteamet utan grova defekter;
  • Vi integrerar i befintliga processer så mycket som möjligt;
  • För att överföra kod mellan uppenbara stadier skär vi en pipeline och trycker in en av dess ändar i fortsättningen.

Under denna tid måste utvecklingsteamet av den storlek som krävs utveckla kompetens och öka andelen av sitt bidrag till releaser till en acceptabel nivå. Och det är det, vi kan betrakta uppgiften som slutförd.

Det verkar som att detta är en helt energieffektiv väg till det resultat som krävs: här är DevOps, här är teamets prestationsmått, här är den samlade expertis... Men i praktiken fick vi ytterligare en bekräftelse på att DevOps fortfarande handlar om filosofi , och inte "kopplad till gitlab-processen, ansible, nexus och längre ner i listan."

Efter att återigen ha analyserat handlingsplanen insåg vi att vi byggde en sorts outsourcingleverantör inom oss själva. Därför lades processomarbetning till algoritmen som beskrivs ovan, liksom utvecklingen av expertis längs hela utvecklingsvägen för att uppnå en ledande roll i denna process. Inte det lättaste alternativet, men detta är vägen till en ideologiskt korrekt utveckling.
 

Var börjar den interna utvecklingen? 

Det var inte det mest vänliga systemet att arbeta med. Arkitektoniskt var det en stor icke-relationell DBMS, som bestod av många separata körbara objekt (skript, procedurer, batcher, etc.), som anropades efter behov, och fungerade enligt principen om en svart låda: den tar emot en förfrågan och utfärdar ett svar. Andra svårigheter värda att notera inkluderar:

  • Exotiskt språk (MUMPS);
  • Konsolgränssnitt;
  • Brist på integration med populära automationsverktyg och ramverk;
  • Datavolym i tiotals terabyte;
  • Belastning på över 2 miljoner operationer per timme;
  • Betydelse - Affärskritisk.

Samtidigt fanns det inget källkodsförråd på vår sida. Alls. Det fanns dokumentation, men all nyckelkunskap och kompetens fanns på en extern organisations sida.
Vi började bemästra utvecklingen av systemet nästan från början, med hänsyn till dess funktioner och låga distribution. Startade i oktober 2018:

  • Studerade dokumentationen och grunderna för kodgenerering;
  • Vi studerade den korta kursen om utveckling som erhållits från leverantören;
  • Bemästrade initiala utvecklingsfärdigheter;
  • Vi sammanställde en utbildningsmanual för nya teammedlemmar;
  • Vi kom överens om att inkludera laget i "stridsläge";
  • Löste problemet med kodkvalitetskontroll;
  • Vi anordnade en monter för utveckling.

Vi ägnade tre månader åt att utveckla expertis och fördjupa oss i systemet, och från början av 2019 började intern utveckling sin rörelse mot en ljus framtid, ibland med svårighet, men självsäkert och målmedvetet.

Förvarsmigrering och autotester

Den första DevOps-uppgiften är förvaret. Vi kom snabbt överens om att tillhandahålla åtkomst, men det var nödvändigt att migrera från nuvarande SVN med en trunkgren till vårt mål-Git med övergången till en modell av flera grenar och utveckling av Git Flow. Vi har också 2 team med egen infrastruktur, plus en del av leverantörens team utomlands. Jag var tvungen att leva med två Gits och säkerställa synkronisering. I en sådan situation var det det minsta av två onda.

Migreringen av förvaret sköts upp upprepade gånger, den slutfördes först i april med hjälp av kollegor från frontlinjen. Med Git Flow bestämde vi oss för att hålla det enkelt till att börja med och bestämde oss för det klassiska schemat med snabbkorrigering, utveckla och släpp. De bestämde sig för att överge master (aka prod-like). Nedan kommer vi att förklara varför detta alternativ visade sig vara optimalt för oss. Ett externt förråd som tillhörde leverantören, gemensamt för två team, användes som arbetare. Det synkroniserades med det interna förvaret enligt ett schema. Nu med Git och Gitlab var det möjligt att automatisera processer.

Frågan om autotester löstes förvånansvärt enkelt - vi fick ett färdigt ramverk. Med hänsyn till systemets särdrag var det en förståelig del av affärsprocessen att anropa en separat operation och fungerade samtidigt som ett enhetstest. Allt som återstod var att förbereda testdata och ställa in önskad ordning för att anropa skripten och utvärdera resultaten. När listan över scenarier, bildad på grundval av operationsstatistik, processkritik och befintlig regressionsmetodik, fylldes i, började automatiska tester dyka upp. Nu kunde vi börja bygga rörledningen.

Hur det var: modellen före automatisering

Den befintliga modellen för implementeringsprocessen är en separat historia. Varje modifiering överfördes manuellt som ett separat inkrementellt installationspaket. Därefter kom manuell registrering i Jira och manuell installation på miljöer. För enskilda paket såg allt klart ut, men med förberedelserna av releasen var saker och ting mer komplicerade.

Montering utfördes på nivån för individuella leveranser, som var självständiga objekt. Varje förändring är en ny leverans. Bland annat lades 60–70 tekniska versioner till de 10–15 paketen av huvudreleasesammansättningen – versioner som erhålls när man lägger till eller exkluderar något från releasen och speglar förändringar i försäljning utanför releaser.

Objekt inom leveranserna överlappade varandra, särskilt i den körbara koden, som var mindre än hälften unik. Det fanns många beroenden både på den redan installerade koden och på den vars installation precis var planerad. 

För att få den erforderliga versionen av koden var det nödvändigt att strikt följa installationsordningen, under vilken objekt fysiskt skrevs om många gånger, cirka 10–12 gånger.

Efter att ha installerat ett parti paket var jag tvungen att manuellt följa instruktionerna för att initiera inställningarna. Releasen monterades och installerades av leverantören. Sammansättningen av releasen klargjordes nästan före implementeringsögonblicket, vilket innebar skapandet av "frikopplings"-paket. Som ett resultat av detta flyttade en betydande del av leveranserna från utsläpp till utsläpp med sin egen svans av "avkopplingar".

Nu är det tydligt att med detta tillvägagångssätt - att sätta ihop releasepusslet på paketnivå - hade en enda mastergren ingen praktisk betydelse. Installation på produktion tog från en och en halv till två timmars manuellt arbete. Det är bra att åtminstone på installationsnivån specificerades ordningen för objektbearbetning: fält och strukturer angavs före data för dem och procedurer. Detta fungerade dock bara inom ett separat paket.

Det logiska resultatet av detta tillvägagångssätt var de obligatoriska installationsdefekterna i form av sneda versioner av objekt, onödig kod, saknade instruktioner och oförklarad ömsesidig påverkan av objekt, som febrilt eliminerades efter frigivningen. 

Första uppdateringarna: åta montering och leverans

Automatisering började med att sända kod genom ett rör längs denna väg:

  • Hämta den färdiga leveransen från lager;
  • Installera den i en dedikerad miljö;
  • Kör autotester;
  • Utvärdera installationsresultatet;
  • Anropa följande pipeline vid sidan av testkommandot.

Nästa pipeline bör registrera uppgiften i Jira och vänta på att kommandon distribueras till utvalda testslingor, som beror på tidpunkten för implementeringen av uppgiften. Trigger - ett brev om beredskap för leverans till en given adress. Detta var naturligtvis en självklar krycka, men jag var tvungen att börja någonstans. I maj 2019 började överföringen av kod med kontroller av våra miljöer. Processen har börjat, allt som återstår är att få den i anständig form:

  • Varje modifiering utförs i en separat gren, som motsvarar installationspaketet och övergår i målhuvudgrenen;
  • Pipeline-startutlösaren är uppkomsten av en ny commit i huvudgrenen genom en sammanslagningsförfrågan, som stängs av underhållare från det interna teamet;
  • Förvar synkroniseras en gång var femte minut;
  • Monteringen av installationspaketet påbörjas - med hjälp av assemblern som erhållits från leverantören.

Efter detta fanns det redan befintliga steg för att kontrollera och överföra koden, för att starta röret och montera på vår sida.

Det här alternativet lanserades i juli. Svårigheterna med övergången resulterade i visst missnöje bland leverantören och frontlinjen, men under den kommande månaden lyckades vi ta bort alla ojämna kanter och etablera en process bland teamen. Vi har nu montering genom commit och leverans.
I augusti lyckades vi slutföra den första installationen av ett separat paket i produktionen med vår pipeline, och sedan september, utan undantag, har alla installationer av enskilda icke-release-paket utförts genom vårt CD-verktyg. Dessutom lyckades vi uppnå en andel inhouse-uppgifter i 40 % av releasesammansättningen med ett mindre team än leverantören - detta är en klar framgång. Den allvarligaste uppgiften återstod - att montera och installera releasen.

Den slutliga lösningen: kumulativa installationspaket 

Vi förstod mycket väl att skriptning av leverantörens instruktioner var en sådär automatisering; vi var tvungna att tänka om själva processen. Lösningen var uppenbar - att samla ett kumulativt utbud från release-grenen med alla objekt i de erforderliga versionerna.

Vi började med proof of concept: vi satte ihop releasepaketet för hand enligt innehållet i den tidigare implementeringen och installerade det på våra miljöer. Allt löste sig, konceptet visade sig vara genomförbart. Därefter löste vi problemet med att skripta initialiseringsinställningarna och inkludera dem i commit. Vi förberedde ett nytt paket och testade det i testmiljöer som en del av konturuppdateringen. Installationen var framgångsrik, om än med en lång rad kommentarer från implementeringsteamet. Men huvudsaken är att vi fick klartecken att gå i produktion i novembersläppet med vår montering.

Med drygt en månad kvar antydde de handplockade förnödenheterna tydligt att tiden rann ut. De bestämde sig för att bygga från releasegrenen, men varför skulle den separeras? Vi har inte en Prod-liknande, och befintliga filialer är inte bra - det finns mycket onödig kod. Vi måste snarast minska antalet prod-likes, och det är över tre tusen åtaganden. Att montera för hand är inte alls ett alternativ. Vi skissade ut ett skript som går igenom produktinstallationsloggen och samlar in åtaganden till filialen. Tredje gången fungerade det korrekt, och efter att ha "avslutat med en fil" var grenen klar. 

Vi skrev vår egen byggare för installationspaketet och gjorde klart det på en vecka. Sedan var vi tvungna att ändra installationsprogrammet från systemets kärnfunktionalitet, eftersom det är öppen källkod. Efter en rad kontroller och modifieringar ansågs resultatet vara framgångsrikt. Under tiden tog kompositionen av utgåvan form, för den korrekta installationen av vilken det var nödvändigt att anpassa testkretsen med produktionen, och ett separat manus skrevs för detta.

Naturligtvis fanns det många kommentarer om den första installationen, men överlag fungerade koden. Och efter ungefär den tredje installationen började allt se bra ut. Kompositionskontroll och versionskontroll av objekt övervakades separat i manuellt läge, vilket i detta skede var ganska berättigat.

En ytterligare utmaning var det stora antalet icke-releaser som man måste ta hänsyn till. Men med den Prod-liknande grenen och Rebase blev uppgiften transparent.

Första gången, snabbt och utan fel

Vi närmade oss releasen med en optimistisk attityd och mer än ett dussin framgångsrika installationer på olika kretsar. Men bokstavligen en dag före deadline visade det sig att säljaren inte hade slutfört arbetet med att förbereda releasen för installation på det accepterade sättet. Om vår build av någon anledning inte fungerar kommer releasen att avbrytas. Dessutom genom våra ansträngningar, vilket är särskilt obehagligt. Vi hade inget sätt att dra oss tillbaka. Därför tänkte vi igenom alternativa alternativ, utarbetade handlingsplaner och påbörjade installationen.

Överraskande nog började hela releasen, bestående av mer än 800 objekt, korrekt, första gången och på bara 10 minuter. Vi tillbringade en timme med att kontrollera loggarna och letade efter fel, men hittade inga.

Hela nästa dag var det tyst i releasechatten: inga implementeringsproblem, sneda versioner eller "olämplig" kod. Det var till och med på något sätt besvärligt. Senare kom några kommentarer, men jämfört med andra system och tidigare erfarenheter var deras antal och prioritet märkbart lägre.

En ytterligare effekt från den kumulativa effekten var en höjning av kvaliteten på montering och testning. På grund av flera installationer av den fullständiga versionen identifierades byggdefekter och distributionsfel i tid. Testning i full release-konfigurationer gjorde det möjligt att dessutom identifiera defekter i den ömsesidiga påverkan av objekt som inte uppträdde under inkrementella installationer. Det var definitivt en succé, särskilt med tanke på vårt bidrag på 57 % till releasen.

Resultat och slutsatser

På mindre än ett år lyckades vi:

  • Bygg en fullfjädrad intern utveckling med hjälp av ett exotiskt system;
  • Eliminera kritiskt leverantörsberoende;
  • Starta CI/CD för ett mycket ovänligt arv;
  • Lyft implementeringsprocesser till en ny teknisk nivå;
  • Reducera drifttiden avsevärt;
  • Avsevärt minska antalet implementeringsfel;
  • Deklarera dig själv som en ledande utvecklingsexpert.

Naturligtvis ser mycket av det som beskrivs ut som rent skit, men det här är funktionerna i systemet och de processbegränsningar som finns i det. För tillfället påverkade ändringarna IS Profiles produkter och tjänster (huvudkonton, plastkort, sparkonton, deposition, kontantlån), men potentiellt kan tillvägagångssättet tillämpas på alla IS för vilka uppgiften att implementera DevOps-praxis är inställd. Den kumulativa modellen kan säkert replikeras för efterföljande implementeringar (inklusive icke-release) från många leveranser.

Källa: will.com

Lägg en kommentar