Hoe je een volwaardige inhouse ontwikkeling kunt bouwen met behulp van DevOps - VTB-ervaring

DevOps-praktijken werken. Daar waren we zelf van overtuigd toen we de installatietijd van de release met 10 keer verkortten. In het FIS Profile-systeem, dat we bij VTB gebruiken, duurt de installatie nu 90 minuten in plaats van 10 minuten. De release-buildtijd is teruggebracht van twee weken naar twee dagen. Het aantal hardnekkige implementatiefouten is tot bijna een minimum gedaald. Om af te komen van “handenarbeid” en de afhankelijkheid van de leverancier weg te nemen, moesten we met krukken werken en onverwachte oplossingen vinden. Onder de snit staat een gedetailleerd verhaal over hoe we een volwaardige interne ontwikkeling hebben opgebouwd.

Hoe je een volwaardige inhouse ontwikkeling kunt bouwen met behulp van DevOps - VTB-ervaring
 

Proloog: DevOps is een filosofie

Het afgelopen jaar hebben we veel werk verzet om de interne ontwikkeling en implementatie van DevOps-praktijken bij VTB te organiseren:

  • We hebben interne ontwikkelingsprocessen gebouwd voor 12 systemen;
  • We hebben vijftien pijpleidingen gelanceerd, waarvan er vier in productie zijn genomen;
  • Geautomatiseerde 1445 testscenario's;
  • We hebben met succes een aantal releases geïmplementeerd die zijn voorbereid door interne teams.

Een van de moeilijkst te organiseren interne ontwikkeling en implementatie van DevSecOps-praktijken bleek het FIS Profile-systeem te zijn: een retailproductprocessor op een niet-relationeel DBMS. Niettemin konden we de ontwikkeling opbouwen, de pijplijn lanceren, individuele niet-releasepakketten op het product installeren en leerden we releases samen te stellen. De taak was niet eenvoudig, maar interessant en zonder duidelijke beperkingen bij de implementatie: hier is het systeem - je moet een interne ontwikkeling bouwen. De enige voorwaarde is dat u de cd in een productieve omgeving gebruikt.

In eerste instantie leek het implementatiealgoritme eenvoudig en duidelijk:

  • We ontwikkelen initiële ontwikkelingsexpertise en bereiken een acceptabel kwaliteitsniveau van het codeteam zonder grove gebreken;
  • We integreren zoveel mogelijk in bestaande processen;
  • Om code tussen voor de hand liggende fasen over te dragen, snijden we een pijplijn door en duwen een van de uiteinden in het vervolg.

Gedurende deze tijd moet het ontwikkelteam van de vereiste omvang vaardigheden ontwikkelen en het aandeel van zijn bijdrage aan releases vergroten tot een acceptabel niveau. En dat is alles, we kunnen de taak als voltooid beschouwen.

Het lijkt erop dat dit een volledig energie-efficiënte weg naar het gewenste resultaat is: hier is DevOps, hier zijn de prestatiestatistieken van het team, hier is de opgebouwde expertise... Maar in de praktijk kregen we opnieuw een bevestiging dat DevOps nog steeds over filosofie gaat , en niet “verbonden aan het gitlab-proces, ansible, nexus en verderop in de lijst.”

Nadat we het actieplan opnieuw hadden geanalyseerd, realiseerden we ons dat we een soort outsource-leverancier in onszelf aan het bouwen waren. Daarom werd aan het hierboven beschreven algoritme process reengineering toegevoegd, evenals de ontwikkeling van expertise langs het gehele ontwikkelingstraject om een ​​leidende rol in dit proces te bereiken. Niet de gemakkelijkste optie, maar dit is het pad van ideologisch correcte ontwikkeling.
 

Waar begint de interne ontwikkeling? 

Het was niet het meest gebruiksvriendelijke systeem om mee te werken. Architectonisch gezien was het één groot niet-relationeel DBMS, bestaande uit veel afzonderlijke uitvoerbare objecten (scripts, procedures, batches, enz.), die naar behoefte werden opgeroepen, en werkte volgens het principe van een zwarte doos: het ontvangt een verzoek en geeft een antwoord. Andere problemen die het vermelden waard zijn, zijn onder meer:

  • Exotische taal (Bof);
  • Console-interface;
  • Gebrek aan integratie met populaire automatiseringstools en -frameworks;
  • Datavolume in tientallen terabytes;
  • Belasting van ruim 2 miljoen handelingen per uur;
  • Betekenis - Bedrijfskritisch.

Tegelijkertijd was er aan onze kant geen broncoderepository. Helemaal niet. Er was documentatie, maar alle belangrijke kennis en competenties stonden aan de kant van een externe organisatie.
We zijn begonnen met het beheersen van de ontwikkeling van het systeem bijna vanaf nul, rekening houdend met de kenmerken en lage distributie ervan. Gestart in oktober 2018:

  • Bestudeerde de documentatie en basisbeginselen van het genereren van code;
  • We bestudeerden de korte cursus over ontwikkeling die we van de leverancier kregen;
  • Beheersen van initiële ontwikkelingsvaardigheden;
  • Voor nieuwe teamleden hebben wij een trainingshandleiding samengesteld;
  • We hebben afgesproken om het team in de ‘gevechtsmodus’ te zetten;
  • Het probleem met codekwaliteitscontrole opgelost;
  • We organiseerden een stand voor ontwikkeling.

We hebben drie maanden lang expertise ontwikkeld en ons ondergedompeld in het systeem, en vanaf begin 2019 begon de interne ontwikkeling zijn beweging richting een mooie toekomst, soms met moeite, maar vol vertrouwen en doelbewust.

Repositorymigratie en autotests

De eerste DevOps-taak is de repository. We waren het snel eens over het verlenen van toegang, maar het was noodzakelijk om te migreren van de huidige SVN met één trunkvertakking naar onze doel-Git met de overgang naar een model van meerdere vertakkingen en de ontwikkeling van Git Flow. We hebben ook 2 teams met hun eigen infrastructuur, plus een deel van het team van de leverancier in het buitenland. Ik moest met twee Gits leven en voor synchronisatie zorgen. In een dergelijke situatie was dit het minste van twee kwaden.

De migratie van de repository werd herhaaldelijk uitgesteld; deze werd pas in april voltooid, met de hulp van collega's uit de frontlinie. Met Git Flow besloten we om de zaken om te beginnen eenvoudig te houden en kozen we voor het klassieke schema met hotfix, ontwikkeling en release. Ze besloten de meester (ook wel prod-achtig) in de steek te laten. Hieronder leggen we uit waarom deze optie voor ons optimaal bleek te zijn. Een externe repository van de leverancier, gemeenschappelijk voor twee teams, werd als werker gebruikt. Het synchroniseerde volgens een schema met de interne repository. Met Git en Gitlab was het nu mogelijk om processen te automatiseren.

Het probleem van de autotests werd verrassend eenvoudig opgelost: we kregen een kant-en-klaar raamwerk. Rekening houdend met de eigenaardigheden van het systeem was het oproepen van een afzonderlijke operatie een begrijpelijk onderdeel van het bedrijfsproces en diende het tegelijkertijd als een unit-test. Het enige dat nog restte, was het voorbereiden van de testgegevens en het instellen van de gewenste volgorde voor het aanroepen van de scripts en het evalueren van de resultaten. Naarmate de lijst met scenario's, gevormd op basis van bedrijfsstatistieken, de kriticiteit van processen en de bestaande regressiemethodologie, werd ingevuld, begonnen automatische tests te verschijnen. Nu konden we beginnen met de aanleg van de pijpleiding.

Hoe het was: het model vóór automatisering

Het bestaande model van het implementatieproces is een verhaal apart. Elke wijziging werd handmatig overgebracht als een afzonderlijk incrementeel installatiepakket. Vervolgens kwam de handmatige registratie in Jira en de handmatige installatie in omgevingen. Voor individuele pakketten leek alles duidelijk, maar bij de voorbereiding van de release waren de zaken ingewikkelder.

De montage vond plaats op het niveau van individuele leveringen, die onafhankelijke objecten waren. Elke wijziging is een nieuwe levering. Er zijn onder andere 60-70 technische versies toegevoegd aan de 10-15 pakketten van de hoofdrelease-samenstelling - versies die zijn verkregen bij het toevoegen of uitsluiten van iets uit de release en die veranderingen in de verkoop buiten releases weerspiegelen.

Objecten binnen de leveringen overlapten elkaar, vooral in de uitvoerbare code, die minder dan de helft uniek was. Er waren veel afhankelijkheden, zowel van de reeds geïnstalleerde code als van degene waarvan de installatie zojuist was gepland. 

Om de vereiste versie van de code te verkrijgen, was het noodzakelijk om de installatievolgorde strikt te volgen, waarbij objecten vele malen fysiek werden herschreven, zo'n 10 tot 12 keer.

Nadat ik een reeks pakketten had geïnstalleerd, moest ik handmatig de instructies volgen om de instellingen te initialiseren. De release is door de leverancier gemonteerd en geïnstalleerd. De samenstelling van de release werd bijna vóór het moment van implementatie verduidelijkt, wat de creatie van "ontkoppelende" pakketten met zich meebracht. Als gevolg hiervan verschoof een aanzienlijk deel van de voorraden van vrijgave naar vrijgave, met een eigen staart van “ontkoppelingen”.

Nu is het duidelijk dat met deze aanpak – het samenstellen van de releasepuzzel op pakketniveau – een enkele masterbranch geen praktische betekenis had. De installatie op de productie kostte anderhalf tot twee uur handarbeid. Het is goed dat in ieder geval op installatieniveau de volgorde van objectverwerking werd gespecificeerd: velden en structuren werden ingevoerd vóór de gegevens daarvoor en procedures. Dit werkte echter alleen binnen een apart pakket.

Het logische resultaat van deze aanpak waren de verplichte installatiefouten in de vorm van scheve versies van objecten, onnodige code, ontbrekende instructies en onverklaarde wederzijdse invloeden van objecten, die na de release koortsachtig werden geëlimineerd. 

Eerste updates: montage en levering vastleggen

Automatisering begon met het verzenden van code via een pijp langs deze route:

  • Haal de voltooide levering op uit de opslag;
  • Installeer het op een speciale omgeving;
  • Voer autotests uit;
  • Evalueer het installatieresultaat;
  • Roep de volgende pijplijn aan aan de kant van de testopdracht.

De volgende pijplijn moet de taak in Jira registreren en wachten tot opdrachten worden gedistribueerd naar geselecteerde testlussen, die afhankelijk zijn van de timing van de taakimplementatie. Trigger - een brief over de gereedheid voor bezorging op een bepaald adres. Dit was natuurlijk een voor de hand liggende steunpilaar, maar ik moest ergens beginnen. In mei 2019 begon de codeoverdracht met controles op onze omgevingen. Het proces is begonnen, het enige dat overblijft is om het in goede vorm te brengen:

  • Elke wijziging wordt uitgevoerd in een afzonderlijke vertakking, die overeenkomt met het installatiepakket en opgaat in de doelmastervertakking;
  • De trigger voor het starten van de pijplijn is het verschijnen van een nieuwe commit in de master branch via een samenvoegverzoek, dat wordt gesloten door beheerders van het interne team;
  • Repository's worden elke vijf minuten gesynchroniseerd;
  • De montage van het installatiepakket wordt gestart - met behulp van de assembler die is ontvangen van de leverancier.

Hierna waren er al bestaande stappen om de code te controleren en over te dragen, om de pijp te lanceren en aan onze kant te monteren.

Deze optie is in juli gelanceerd. De moeilijkheden bij de transitie resulteerden in enige ontevredenheid bij de leverancier en de frontlinie, maar de maand daarna slaagden we erin alle ruwe kantjes weg te nemen en een proces onder de teams op gang te brengen. We hebben nu montage door commit en levering.
In augustus zijn we erin geslaagd de eerste installatie van een afzonderlijk pakket in productie te voltooien met behulp van onze pijplijn, en sinds september zijn zonder uitzondering alle installaties van individuele niet-releasepakketten uitgevoerd via onze CD-tool. Bovendien zijn we erin geslaagd om een ​​aandeel van de interne taken in 40% van de releasesamenstelling te realiseren met een kleiner team dan de leverancier - dit is een absoluut succes. De meest serieuze taak bleef over: het samenstellen en installeren van de release.

De uiteindelijke oplossing: cumulatieve installatiepakketten 

We begrepen heel goed dat het scripten van de instructies van de leverancier een matige automatisering was; we moesten het proces zelf heroverwegen. De oplossing lag voor de hand: het verzamelen van een cumulatief aanbod van de releasetak met alle objecten van de vereiste versies.

We zijn begonnen met proof of concept: we hebben het releasepakket met de hand samengesteld volgens de inhoud van de eerdere implementatie en op onze omgevingen geïnstalleerd. Alles lukte, het concept bleek levensvatbaar. Vervolgens hebben we het probleem opgelost van het scripten van de initialisatie-instellingen en het opnemen ervan in de commit. We hebben een nieuw pakket voorbereid en getest in testomgevingen als onderdeel van de contourupdate. De installatie was succesvol, zij het met veel reacties van het implementatieteam. Maar het belangrijkste is dat we toestemming hebben gekregen om in de release van november met onze assemblage in productie te gaan.

Met nog iets meer dan een maand te gaan, gaven de zorgvuldig uitgekozen voorraden duidelijk aan dat de tijd begon te dringen. Ze besloten om de build vanuit de release branch te maken, maar waarom zou deze gescheiden moeten worden? We hebben geen Prod-achtige, en bestaande branches zijn niet goed - er is veel onnodige code. We moeten dringend het aantal prod-likes terugdringen, en dit zijn ruim drieduizend commits. Met de hand in elkaar zetten is helemaal geen optie. We hebben een script geschetst dat door het productinstallatielogboek loopt en commits voor de branch verzamelt. De derde keer werkte het correct, en na “afwerking met een bestand” was de branch klaar. 

Voor het installatiepakket hebben wij onze eigen bouwer geschreven en deze in een week voltooid. Vervolgens moesten we het installatieprogramma aanpassen aan de kernfunctionaliteit van het systeem, aangezien het open source is. Na een reeks controles en aanpassingen werd het resultaat als succesvol beschouwd. Ondertussen kreeg de samenstelling van de release vorm, voor de juiste installatie waarvan het nodig was om het testcircuit af te stemmen op het productiecircuit, en hiervoor werd een apart script geschreven.

Uiteraard waren er veel opmerkingen over de eerste installatie, maar over het algemeen werkte de code. En na ongeveer de derde installatie begon alles er goed uit te zien. Compositiecontrole en versiecontrole van objecten werden afzonderlijk in de handmatige modus gemonitord, wat in dit stadium volkomen gerechtvaardigd was.

Een extra uitdaging was het grote aantal non-releases waarmee rekening moest worden gehouden. Maar met de Prod-achtige branch en Rebase werd de taak transparant.

Eerste keer, snel en zonder fouten

We benaderden de release met een optimistische instelling en meer dan een dozijn succesvolle installaties op verschillende circuits. Maar letterlijk een dag voor de deadline bleek dat de leverancier het werk om de release voor installatie op de geaccepteerde manier voor te bereiden niet had voltooid. Als onze build om wat voor reden dan ook niet werkt, wordt de release verstoord. Bovendien, door onze inspanningen, wat vooral onaangenaam is. We hadden geen mogelijkheid om ons terug te trekken. Daarom hebben we alternatieve opties overwogen, actieplannen opgesteld en begonnen met de installatie.

Verrassend genoeg startte de hele release, bestaande uit meer dan 800 objecten, correct, de eerste keer en in slechts 10 minuten. We hebben een uur besteed aan het controleren van de logboeken op zoek naar fouten, maar hebben er geen gevonden.

De hele volgende dag was het stil in de releasechat: geen implementatieproblemen, kromme versies of “ongepaste” code. Het was op de een of andere manier zelfs ongemakkelijk. Later kwamen er enkele opmerkingen naar voren, maar vergeleken met andere systemen en eerdere ervaringen was het aantal en de prioriteit ervan merkbaar lager.

Een bijkomend effect van het cumulatieve effect was een toename van de kwaliteit van assemblage en testen. Dankzij meerdere installaties van de volledige release werden bouwfouten en implementatiefouten tijdig geïdentificeerd. Testen in configuraties met volledige release maakte het mogelijk om bovendien defecten in de wederzijdse invloed van objecten te identificeren die niet verschenen tijdens incrementele installaties. Het was absoluut een succes, vooral gezien onze bijdrage van 57% aan de release.

Resultaten en conclusies

In minder dan een jaar zijn we erin geslaagd om:

  • Bouw een volwaardige interne ontwikkeling met behulp van een exotisch systeem;
  • Elimineer kritische leveranciersafhankelijkheid;
  • Lanceer CI/CD voor een zeer onvriendelijke erfenis;
  • Implementatieprocessen naar een nieuw technisch niveau tillen;
  • De implementatietijd aanzienlijk verkorten;
  • Het aantal implementatiefouten aanzienlijk verminderen;
  • Verklaar uzelf vol vertrouwen als een toonaangevend ontwikkelingsexpert.

Natuurlijk lijkt veel van wat wordt beschreven regelrechte onzin, maar dit zijn de kenmerken van het systeem en de procesbeperkingen die erin bestaan. Op dit moment hebben de veranderingen gevolgen voor de producten en diensten van IS Profile (hoofdrekeningen, plastic kaarten, spaarrekeningen, borgstellingen, contante leningen), maar potentieel kan de aanpak worden toegepast op elke IS waarvoor de taak is gesteld om DevOps-praktijken te implementeren. Het cumulatieve model kan veilig worden gerepliceerd voor volgende implementaties (inclusief niet-release-implementaties) uit vele leveringen.

Bron: www.habr.com

Voeg een reactie