Cum să construiți o dezvoltare internă cu drepturi depline folosind experiența DevOps - VTB

Practicile DevOps funcționează. Ne-am convins noi înșine de acest lucru când am redus de 10 ori timpul de instalare a lansării. În sistemul FIS Profile, pe care îl folosim la VTB, instalarea durează acum 90 minute în loc de 10. Timpul de construire a lansării a scăzut de la două săptămâni la două zile. Numărul de defecte persistente de implementare a scăzut aproape la minimum. Pentru a scăpa de „munca manuală” și a elimina dependența de vânzător, a trebuit să lucrăm cu cârje și să găsim soluții neașteptate. Mai jos este o poveste detaliată despre cum am construit o dezvoltare internă cu drepturi depline.

Cum să construiți o dezvoltare internă cu drepturi depline folosind experiența DevOps - VTB
 

Prolog: DevOps este o filozofie

În ultimul an, am depus multă muncă pentru a organiza dezvoltarea internă și implementarea practicilor DevOps la VTB:

  • Am construit procese interne de dezvoltare pentru 12 sisteme;
  • Am lansat 15 conducte, dintre care patru au fost aduse în producție;
  • 1445 scenarii de testare automatizate;
  • Am implementat cu succes o serie de versiuni pregătite de echipe interne.

Una dintre cele mai dificil de organizat dezvoltarea și implementarea practicilor DevSecOps sa dovedit a fi sistemul FIS Profile - un procesor de produse de vânzare cu amănuntul pe un DBMS non-relațional. Cu toate acestea, am reușit să construim dezvoltarea, să lansăm pipeline, să instalăm pachete individuale fără lansare pe produs și am învățat cum să asamblam versiuni. Sarcina nu a fost ușoară, dar interesantă și fără restricții evidente în implementare: iată sistemul - trebuie să construiți o dezvoltare internă. Singura condiție este să folosiți CD-ul înaintea unui mediu productiv.

La început, algoritmul de implementare părea simplu și clar:

  • Dezvoltăm expertiza inițială de dezvoltare și atingem un nivel acceptabil de calitate din partea echipei de cod fără defecte grave;
  • Ne integrăm în procesele existente pe cât posibil;
  • Pentru a transfera codul între etapele evidente, tăiem o conductă și împingem unul dintre capetele acesteia în continuare.

În acest timp, echipa de dezvoltare de dimensiunea necesară trebuie să-și dezvolte abilitățile și să-și crească ponderea contribuției la lansări la un nivel acceptabil. Și gata, putem considera sarcina finalizată.

S-ar părea că aceasta este o cale complet eficientă din punct de vedere energetic către rezultatul cerut: iată DevOps, aici sunt metricile de performanță ale echipei, iată expertiza acumulată... Dar, în practică, am primit o altă confirmare că DevOps este încă despre filozofie. , și nu „atașat la procesul gitlab, ansible, nexus și mai jos în listă”.

După ce am analizat încă o dată planul de acțiune, ne-am dat seama că construim în noi înșine un fel de furnizor de outsourcing. Prin urmare, la algoritmul descris mai sus s-a adăugat reinginierea proceselor, precum și dezvoltarea expertizei de-a lungul întregului traseu de dezvoltare pentru a obține un rol principal în acest proces. Nu este cea mai ușoară opțiune, dar aceasta este calea dezvoltării corecte din punct de vedere ideologic.
 

Unde începe dezvoltarea internă? 

Nu a fost cel mai prietenos sistem cu care să lucrați. Din punct de vedere arhitectural, era un SGBD mare non-relațional, constă din multe obiecte executabile separate (scripturi, proceduri, loturi etc.), care erau apelate după cum era necesar și funcționau pe principiul unei cutii negre: primește o solicitare și probleme. un raspuns. Alte dificultăți care merită remarcate includ:

  • Limbajul exotic (MUMPS);
  • Interfață de consolă;
  • Lipsa integrării cu instrumentele și cadrele de automatizare populare;
  • Volumul datelor în zeci de terabytes;
  • Sarcina de peste 2 milioane de operatii pe ora;
  • Semnificație - critică pentru afaceri.

În același timp, nu exista un depozit de cod sursă de partea noastră. Deloc. A existat documentație, dar toate cunoștințele și competențele cheie erau de partea unei organizații externe.
Am început să stăpânim dezvoltarea sistemului aproape de la zero, ținând cont de caracteristicile acestuia și de distribuția scăzută. A început în octombrie 2018:

  • Studiat documentația și elementele de bază ale generării codului;
  • Am studiat cursul scurt de dezvoltare primit de la furnizor;
  • Stăpânirea abilităților inițiale de dezvoltare;
  • Am compilat un manual de instruire pentru noii membri ai echipei;
  • Am fost de acord să includem echipa în modul „combat”;
  • S-a rezolvat problema cu controlul calității codului;
  • Am organizat un stand pentru dezvoltare.

Am petrecut trei luni dezvoltând expertiză și scufundându-ne în sistem, iar de la începutul anului 2019, dezvoltarea internă și-a început mișcarea către un viitor luminos, uneori cu dificultate, dar cu încredere și intenționat.

Migrarea depozitului și autotestare

Prima sarcină DevOps este depozitul. Am convenit rapid asupra furnizării accesului, dar a fost necesar să migrem de la SVN-ul actual cu o ramură trunk la Git-ul nostru țintă, odată cu trecerea la un model de mai multe ramuri și dezvoltarea Git Flow. Avem, de asemenea, 2 echipe cu infrastructură proprie, plus o parte din echipa vânzătorului din străinătate. A trebuit să trăiesc cu două Gits și să asigur sincronizarea. Într-o astfel de situație, era cel mai mic dintre cele două rele.

Migrarea depozitului a fost amânată în mod repetat; a fost finalizată abia în aprilie, cu ajutorul colegilor din prima linie. Cu Git Flow, am decis să păstrăm lucrurile simple pentru început și am stabilit schema clasică cu remediere rapidă, dezvoltare și lansare. Au decis să-l abandoneze pe maestru (aka prod-like). Mai jos vă vom explica de ce această opțiune s-a dovedit a fi optimă pentru noi. Un depozit extern aparținând vânzătorului, comun pentru două echipe, a fost folosit ca lucrător. S-a sincronizat cu depozitul intern conform unui program. Acum, cu Git și Gitlab a fost posibilă automatizarea proceselor.

Problema autotestelor a fost rezolvată surprinzător de ușor - ni s-a oferit un cadru gata făcut. Ținând cont de particularitățile sistemului, apelarea unei operațiuni separate a fost o parte de înțeles a procesului de afaceri și, în același timp, a servit ca un test unitar. Tot ce a rămas a fost să pregătim datele de testare și să stabilim ordinea dorită de apelare a scripturilor și evaluarea rezultatelor. Pe măsură ce lista de scenarii, formată pe baza statisticilor de funcționare, a criticității proceselor și a metodologiei de regresie existentă, au început să apară testele automate. Acum am putea începe să construim conducta.

Cum a fost: modelul înainte de automatizare

Modelul existent al procesului de implementare este o poveste separată. Fiecare modificare a fost transferată manual ca pachet separat de instalare incrementală. Urmează înregistrarea manuală în Jira și instalarea manuală pe medii. Pentru pachetele individuale, totul părea clar, dar odată cu pregătirea lansării, lucrurile s-au complicat.

Asamblarea s-a efectuat la nivelul livrărilor individuale, care erau obiecte independente. Orice modificare este o livrare nouă. Printre altele, 60-70 versiuni tehnice au fost adăugate la cele 10-15 de pachete ale compoziției principale ale versiunii - versiuni obținute atunci când se adaugă sau se exclude ceva din ediție și care reflectă modificările vânzărilor din afara versiunilor.

Obiectele din livrări se suprapuneau unele cu altele, în special în codul executabil, care era mai puțin de jumătate unic. Au existat multe dependențe atât de codul deja instalat, cât și de cel a cărui instalare tocmai a fost planificată. 

Pentru a obține versiunea necesară a codului, a fost necesar să se respecte cu strictețe ordinea de instalare, timp în care obiectele au fost rescrise fizic de multe ori, de aproximativ 10-12 ori.

După instalarea unui lot de pachete, a trebuit să urmez manual instrucțiunile pentru a inițializa setările. Versiunea a fost asamblată și instalată de către vânzător. Compoziția versiunii a fost clarificată aproape înainte de momentul implementării, ceea ce a presupus crearea de pachete de „decuplare”. Drept urmare, o parte semnificativă a proviziilor s-a mutat de la eliberare la eliberare cu propria sa coadă de „decuplări”.

Acum este clar că cu această abordare - asamblarea puzzle-ului de lansare la nivel de pachet - o singură ramură principală nu avea nicio semnificație practică. Instalarea în producție a durat de la o oră și jumătate până la două ore de muncă manuală. Este bine că cel puțin la nivel de instalator a fost specificată ordinea procesării obiectelor: câmpurile și structurile au fost introduse înainte de datele pentru acestea și proceduri. Cu toate acestea, acest lucru a funcționat doar într-un pachet separat.

Rezultatul logic al acestei abordări au fost defecte de instalare obligatorii sub formă de versiuni strâmbe ale obiectelor, cod inutil, instrucțiuni lipsă și influențe reciproce nesocotite ale obiectelor, care au fost eliminate febril după eliberare. 

Primele actualizări: comite asamblare și livrare

Automatizarea a început prin transmiterea codului printr-o conductă de-a lungul acestui traseu:

  • Ridicați livrarea finită din depozit;
  • Instalați-l într-un mediu dedicat;
  • Rulați autotestări;
  • Evaluați rezultatul instalării;
  • Apelați următoarea conductă de pe partea comenzii de testare.

Următoarea conductă ar trebui să înregistreze sarcina în Jira și să aștepte ca comenzile să fie distribuite buclelor de testare selectate, care depind de momentul implementării sarcinii. Trigger - o scrisoare despre disponibilitatea pentru livrare la o anumită adresă. Aceasta, desigur, era o cârjă evidentă, dar trebuia să încep de undeva. În mai 2019, transferul de cod a început cu verificări ale mediilor noastre. Procesul a început, tot ce rămâne este să-l aducem într-o formă decentă:

  • Fiecare modificare este efectuată într-o ramură separată, care corespunde pachetului de instalare și se îmbină în ramura principală țintă;
  • Declanșatorul de lansare a conductei este apariția unui nou commit în ramura principală printr-o cerere de îmbinare, care este închisă de menținătorii din echipa internă;
  • Arhivele sunt sincronizate o dată la cinci minute;
  • Se începe asamblarea pachetului de instalare - folosind asamblatorul primit de la furnizor.

După aceasta, au existat deja pași pentru a verifica și transfera codul, pentru a lansa conducta și a asambla de partea noastră.

Această opțiune a fost lansată în iulie. Dificultățile tranziției au dus la o oarecare nemulțumire în rândul vânzătorului și al primei linie, dar pe parcursul lunii următoare am reușit să înlăturăm toate punctele aspre și să stabilim un proces în rândul echipelor. Acum avem asamblare prin comitere și livrare.
În august, am reușit să finalizăm prima instalare a unui pachet separat în producție folosind pipeline-ul nostru, iar din septembrie, fără excepție, toate instalările pachetelor individuale care nu sunt lansate au fost efectuate prin instrumentul nostru CD. În plus, am reușit să realizăm o cotă de sarcini interne în 40% din compoziția lansării cu o echipă mai mică decât furnizorul - acesta este un succes sigur. Cea mai serioasă sarcină a rămas - asamblarea și instalarea versiunii.

Soluția finală: pachete de instalare cumulate 

Am înțeles perfect că scriptarea instrucțiunilor vânzătorului a fost o automatizare așa-așa; a trebuit să regândim procesul în sine. Soluția a fost evidentă - să colecteze o aprovizionare cumulată din ramura de lansare cu toate obiectele versiunilor necesare.

Am început cu dovada conceptului: am asamblat manual pachetul de lansare în conformitate cu conținutul implementării anterioare și l-am instalat în mediile noastre. Totul a funcționat, conceptul s-a dovedit a fi viabil. Apoi, am rezolvat problema scriptării setărilor de inițializare și includerea lor în commit. Am pregătit un nou pachet și l-am testat în medii de testare, ca parte a actualizării conturului. Instalarea a avut succes, deși cu o gamă largă de comentarii din partea echipei de implementare. Dar principalul lucru este că ni s-a dat permisiunea de a intra în producție în lansarea din noiembrie cu ansamblul nostru.

Cu puțin peste o lună rămasă, rechizitele alese manual sugerau clar că timpul se scurge. Au decis să facă construcția din ramura de lansare, dar de ce ar trebui să fie separată? Nu avem un produs similar, iar filialele existente nu sunt bune - există o mulțime de coduri inutile. Trebuie urgent să reducem numărul de produse, iar aceasta înseamnă peste trei mii de comite. Asamblarea manuală nu este deloc o opțiune. Am schițat un script care rulează prin jurnalul de instalare a produsului și colectează commit-uri pentru ramură. A treia oară a funcționat corect, iar după „terminarea cu un fișier” ramura era gata. 

Am scris propriul nostru constructor pentru pachetul de instalare și l-am terminat într-o săptămână. Apoi a trebuit să modificăm programul de instalare din funcționalitatea de bază a sistemului, deoarece este open-source. După o serie de verificări și modificări, rezultatul a fost considerat reușit. Între timp s-a conturat compoziția lansării, pentru instalarea corectă a căreia a fost necesară alinierea circuitului de testare cu cel de producție, iar pentru aceasta a fost scris un scenariu separat.

Desigur, au existat o mulțime de comentarii despre prima instalare, dar în general codul a funcționat. Și după aproximativ a treia instalare totul a început să arate bine. Controlul compoziției și controlul versiunii obiectelor au fost monitorizate separat în modul manual, ceea ce în această etapă era destul de justificat.

O provocare suplimentară a fost numărul mare de non-lansări care trebuiau luate în considerare. Dar cu ramura similară Prod și Rebase, sarcina a devenit transparentă.

Prima data, rapid si fara erori

Am abordat lansarea cu o atitudine optimistă și cu peste o duzină de instalări reușite pe diferite circuite. Dar, literalmente, cu o zi înainte de termenul limită, s-a dovedit că vânzătorul nu a finalizat lucrările de pregătire a versiunii pentru instalare în modul acceptat. Dacă, dintr-un motiv oarecare, versiunea noastră nu funcționează, lansarea va fi întreruptă. Mai mult, prin eforturile noastre, ceea ce este deosebit de neplăcut. Nu aveam cum să ne retragem. Prin urmare, ne-am gândit la opțiuni alternative, am pregătit planuri de acțiune și am început instalarea.

În mod surprinzător, întreaga lansare, formată din peste 800 de obiecte, a început corect, prima dată și în doar 10 minute. Am petrecut o oră verificând jurnalele căutând erori, dar nu am găsit niciuna.

Toată ziua următoare a fost tăcere în chatul de lansare: fără probleme de implementare, versiuni strâmbe sau cod „nepotrivit”. A fost chiar oarecum incomod. Mai târziu, au apărut unele comentarii, dar în comparație cu alte sisteme și cu experiența anterioară, numărul și prioritatea acestora au fost considerabil mai mici.

Un efect suplimentar din efectul cumulativ a fost o creștere a calității asamblarii și testării. Datorită instalărilor multiple ale versiunii complete, defectele de construcție și erorile de implementare au fost identificate în timp util. Testarea în configurațiile de lansare completă a făcut posibilă identificarea suplimentară a defectelor în influența reciprocă a obiectelor care nu au apărut în timpul instalărilor incrementale. A fost cu siguranță un succes, mai ales având în vedere contribuția noastră de 57% la lansare.

Rezultate și concluzii

În mai puțin de un an am reușit să:

  • Construiți o dezvoltare internă cu drepturi depline folosind un sistem exotic;
  • Eliminați dependența critică de furnizor;
  • Lansați CI/CD pentru o moștenire foarte neprietenoasă;
  • Ridicarea proceselor de implementare la un nou nivel tehnic;
  • Reduceți semnificativ timpul de implementare;
  • Reduceți semnificativ numărul de erori de implementare;
  • Declarați-vă cu încredere ca un expert de top în dezvoltare.

Desigur, multe din ceea ce este descris arată ca o porcărie de-a dreptul, dar acestea sunt caracteristicile sistemului și limitările procesului care există în el. În momentul de față, modificările au afectat produsele și serviciile IS Profile (conturi master, carduri de plastic, conturi de economii, escrow, împrumuturi în numerar), dar, potențial, abordarea poate fi aplicată oricărui IS pentru care este stabilită sarcina implementării practicilor DevOps. Modelul cumulativ poate fi replicat în siguranță pentru implementările ulterioare (inclusiv cele care nu sunt lansate) din mai multe livrări.

Sursa: www.habr.com

Adauga un comentariu