Scriptetatik gure plataformara: nola automatizatu genuen garapena CIANen

Scriptetatik gure plataformara: nola automatizatu genuen garapena CIANen

RIT 2019-n, gure lankide Alexander Korotkov-ek egin zuen txostena CIANen garapenaren automatizazioari buruz: bizitza eta lana errazteko, Integro plataforma propioa erabiltzen dugu. Zereginen bizi-zikloaren jarraipena egiten du, garatzaileak ohiko eragiketak arintzen ditu eta ekoizpeneko akatsen kopurua nabarmen murrizten du. Argitalpen honetan, Alexanderren txostena osatuko dugu eta script soiletatik kode irekiko produktuak gure plataforma propioaren bidez konbinatzera nola pasatu ginen eta gure automatizazio-talde bereiziak zer egiten duen kontatuko dizugu.
 

Zero maila

"Ez dago zero mailarik, ez dakit horrelakorik"
"Kung Fu Panda" filmeko Shifu maisua

CIANen automatizazioa enpresa sortu zenetik 14 urtera hasi zen. Garai hartan, garapen taldeak 35 lagun zituen. Zaila sinesten, ezta? Jakina, automatizazioa nolabait existitzen zen, baina etengabeko integraziorako eta kodea emateko norabide bereizia formatzen hasi zen 2015ean. 

Garai hartan, Python, C# eta PHP monolito erraldoi bat genuen, Linux/Windows zerbitzarietan zabalduta. Munstro hau zabaltzeko, eskuz exekutatu ditugun script multzo bat genuen. Monolitoaren muntaketa ere egon zen, eta mina eta sufrimendua ekarri zuen adarrak bateratzean, akatsak zuzentzean eta berreraikitzean "eraikuntzako beste zeregin multzo batekin". Prozesu sinplifikatu batek itxura hau zuen:

Scriptetatik gure plataformara: nola automatizatu genuen garapena CIANen

Ez geunden pozik honekin, eta eraikitze- eta inplementazio-prozesu errepikakorra, automatizatua eta kudeagarria eraiki nahi genuen. Horretarako, CI/CD sistema bat behar genuen, eta Teamcity-ren doako bertsioaren eta Jenkins-en doako bertsioaren artean aukeratu genuen, haiekin lan egin eta biak egokitu zitzaizkigun funtzio multzoari dagokionez. Teamcity aukeratu dugu azken produktu gisa. Garai hartan, oraindik ez genuen mikrozerbitzuen arkitekturarik erabili eta ez genuen zeregin eta proiektu kopuru handirik espero.

Gure sistema propioaren ideiara heltzen gara

Teamcity-ren ezarpenak eskuzko lanaren zati bat bakarrik kendu zuen: Pull Requests sortzea da geratzen dena, Jiran egoeraren araberako gaiak sustatzea eta kaleratzeko gaiak hautatzea. Teamcity sistemak ezin zion horri aurre egin. Beharrezkoa zen automatizazio gehiagorako bidea aukeratu. Teamcity-n scriptekin lan egiteko edo hirugarrenen automatizazio sistemetara aldatzeko aukerak kontuan hartu ditugu. Baina azkenean erabaki genuen malgutasun handiena behar genuela, gure soluzio propioak bakarrik eman dezakeena. Horrela agertu zen Integro izeneko barne automatizazio sistemaren lehen bertsioa.

Teamcity-k automatizazioa lantzen du eraikitze- eta inplementazio-prozesuak abiarazteko mailan, eta Integro-k, berriz, garapen-prozesuen goi-mailako automatizazioan zentratu zen. Beharrezkoa zen Jira-ko arazoekin lana eta Bitbucket-en lotutako iturburu-kodea prozesatzearekin bateratzea. Etapa honetan, Integro bere lan-fluxuak izaten hasi zen mota ezberdinetako zereginekin lan egiteko. 

Negozio-prozesuetan automatizazioaren hazkundea dela eta, Teamcity-n proiektu eta exekuzio kopuruak gora egin du. Beraz, arazo berri bat etorri zen: doako Teamcity instantzia bat ez zen nahikoa (3 agente eta 100 proiektu), beste instantzia bat gehitu genuen (3 agente gehiago eta 100 proiektu), gero beste bat. Ondorioz, kudeatzeko zaila zen hainbat klusterren sistema batekin amaitu genuen:

Scriptetatik gure plataformara: nola automatizatu genuen garapena CIANen

Laugarren instantzia baten galdera sortu zenean, konturatu ginen ezin genuela horrela bizitzen jarraitu, 4 instantzien laguntzaren guztizko kostuak jada ez zeudelako mugarik. Ordaindutako Teamcity erostea edo doako Jenkins aukeratzeari buruzko galdera sortu zen. Instantzia eta automatizazio planen kalkuluak egin genituen eta Jenkinsen biziko ginela erabaki genuen. Pare bat asteren buruan, Jenkinsera aldatu eta Teamcity-ren hainbat instantzia mantentzearekin lotutako buruhauste batzuk kendu genituen. Hori dela eta, Integro garatzen eta Jenkins pertsonalizatzen zentratu ahal izan ginen.

Oinarrizko automatizazioaren hazkuntzarekin (Pul Requests automatikoki sortzean, Kodearen estaldura biltzea eta argitaratzea eta beste egiaztapen batzuen moduan), eskuzko oharra ahal den neurrian bertan behera uzteko eta lan hori robotei emateko gogo handia dago. Horrez gain, konpainia mikrozerbitzuetara mugitzen hasi zen konpainiaren barruan, maiz kaleratzeak eskatzen zituztenak, eta elkarrengandik bereizita. Horrela, pixkanaka-pixkanaka gure mikrozerbitzuen bertsio automatikoetara iritsi ginen (gaur egun monolitoa eskuz askatzen ari gara prozesuaren konplexutasuna dela eta). Baina, normalean gertatzen den bezala, konplexutasun berri bat sortu zen. 

Probak automatizatzen ditugu

Scriptetatik gure plataformara: nola automatizatu genuen garapena CIANen

Argitalpenen automatizazioa dela eta, garapen-prozesuak bizkortu egin dira, neurri batean proba-etapa batzuk saltatu direlako. Eta horrek aldi baterako kalitatea galtzea ekarri zuen. Huskeria dirudi, baina kaleratzeen bizkortzearekin batera, produktua garatzeko metodologia aldatzea beharrezkoa izan zen. Beharrezkoa zen probak automatizatzeari buruz pentsatu, garatzailearen erantzukizun pertsonala (hemen buruan ideia onartzeaz ari gara, ez diru-isunak) garatzaileak kaleratutako kodea eta akatsengatik, baita erabakia hartzeaz ere. askatu/ez askatu zeregin bat inplementazio automatikoaren bidez. 

Kalitate-arazoak ezabatuz, bi erabaki garrantzitsu hartu genituen: kanariar probak egiten hasi ginen eta akatsen atzeko planoaren monitorizazio automatikoa sartu genuen gehiegizko erantzun automatikoarekin. Lehen irtenbideak posible egin zuen akats nabariak aurkitzea kodea guztiz produkziora atera baino lehen, bigarrenak ekoizpeneko arazoei erantzuteko denbora murriztu zuen. Akatsak, noski, gertatzen dira, baina denbora eta ahalegin gehiena ez zuzentzen, gutxitzen baizik. 

Automatizazio taldea

Gaur egun 130 garatzaileko langileak ditugu, eta jarraitzen dugu hazten. Etengabeko integraziorako eta kodea emateko taldea (aurrerantzean Deploy and Integration edo DI taldea) 7 pertsonak osatzen dute eta 2 norabidetan lan egiten du: Integro automatizazio plataformaren garapena eta DevOps. 

DevOps CIAN guneko Dev/Beta ingurunearen arduraduna da, Integro ingurunea, garatzaileei arazoak konpontzen eta inguruneak eskalatzeko ikuspegi berriak garatzen laguntzen die. Integro garapenaren zuzendaritzak Integro bera eta erlazionatutako zerbitzuez arduratzen da, adibidez, Jenkins, Jira, Confluence pluginak, eta garapen-taldeentzako utilitate eta aplikazio osagarriak garatzen ditu. 

DI taldeak lankidetzan lan egiten du Plataformako taldearekin, arkitektura, liburutegiak eta garapen ikuspegiak barnean garatzen dituena. Aldi berean, CIANeko edozein garatzailek automatizazioan lagundu dezake, adibidez, mikro-automatizazioa egin taldearen beharretara egokitzeko edo automatizazioa are hobeto nola egin jakiteko ideia polita partekatu.

Automatizazioaren geruza pastela CIANen

Scriptetatik gure plataformara: nola automatizatu genuen garapena CIANen

Automatizazioan parte hartzen duten sistema guztiak hainbat geruzatan bana daitezke:

  1. Kanpoko sistemak (Jira, Bitbucket, etab.). Garapen taldeek haiekin lan egiten dute.
  2. Integra plataforma. Gehienetan, garatzaileek ez dute zuzenean lan egiten, baina automatizazio guztiak martxan mantentzen dituena da.
  3. Entrega, orkestrazio eta aurkikuntza zerbitzuak (adibidez, Jeknins, Consul, Nomad). Haien laguntzarekin, zerbitzarietan kodea zabaltzen dugu eta zerbitzuak elkarren artean funtzionatzen dutela ziurtatzen dugu.
  4. Geruza fisikoa (zerbitzariak, OS, erlazionatutako softwarea). Gure kodeak maila honetan funtzionatzen du. Hau zerbitzari fisikoa edo birtuala izan daiteke (LXC, KVM, Docker).

Kontzeptu horretatik abiatuta, DI taldearen barruan ardura-eremuak banatzen ditugu. Lehenengo bi mailak Integro garapenaren zuzendaritzaren ardura-eremuan daude, eta azken bi mailak DevOps-en erantzukizun-eremuan daude jada. Bereizketa honek zereginetan zentratzeko aukera ematen digu eta ez du interakzioa oztopatzen, elkarrengandik gertu gaudelako eta ezagutza eta esperientzia etengabe trukatzen baikara.

Osorik

Zentratu gaitezen Integro-n eta has gaitezen teknologia pilarekin:

  • CentOS 7
  • Docker + Nomad + Kontsul + Ganga
  • Java 11 (Integro monolito zaharra Java 8n jarraituko du)
  • Spring Boot 2.X + Spring Cloud Config
  • PostgreSql 11
  • RabbitMQ 
  • Apache Ignite
  • Camunda (txertatua)
  • Grafana + Grafitoa + Prometheus + Jaeger + ELK
  • Web UI: React (CSR) + MobX
  • SSO: Keycloak

Mikrozerbitzuen garapenaren printzipioari eusten diogu, nahiz eta Integro-ren lehen bertsio baten monolito moduan ondarea dugun. Mikrozerbitzu bakoitza bere Docker edukiontzian exekutatzen da, eta zerbitzuak elkarren artean komunikatzen dira HTTP eskaeren eta RabbitMQ mezuen bidez. Mikrozerbitzuek Consul bidez aurkitzen dute elkar eta hari eskaera bat egiten diote, SSO bidez baimena emanez (Keycloak, OAuth 2/OpenID Connect).

Scriptetatik gure plataformara: nola automatizatu genuen garapena CIANen

Bizitza errealeko adibide gisa, kontuan hartu Jenkins-ekin elkarrekintzan aritzea, hau da, pauso hauek dituena:

  1. Lan-fluxua kudeatzeko mikrozerbitzuak (aurrerantzean Flow mikrozerbitzua deitzen zaio) Jenkins-en eraikitze bat exekutatu nahi du. Horretarako, Consul erabiltzen du Jenkins-ekin integratzeko mikrozerbitzuaren IP:PORTA aurkitzeko (aurrerantzean Jenkins mikrozerbitzua deitzen zaio) eta eskaera asinkrono bat bidaltzen dio Jenkins-en eraikitzen hasteko.
  2. Eskaera bat jaso ondoren, Jenkins mikrozerbitzuak Lanaren ID batekin sortzen eta erantzuten du, eta ondoren lanaren emaitza identifikatzeko erabil daiteke. Aldi berean, Jenkinsen eraikuntza abiarazten du REST API dei baten bidez.
  3. Jenkinsek eraikitzea egiten du eta, amaitu ondoren, webhook bat bidaltzen du exekuzio emaitzekin Jenkins mikrozerbitzura.
  4. Jenkins mikrozerbitzuak, webhook-a jaso ondoren, eskaeraren prozesaketa amaitzeari buruzko mezu bat sortzen du eta exekuzioaren emaitzak eransten dizkio. Sortutako mezua RabbitMQ ilarara bidaltzen da.
  5. RabbitMQ-ren bidez, argitaratutako mezua Flow mikrozerbitzura iristen da, eta honek bere zeregina prozesatzeko emaitza ezagutzen du eskaeraren Lanaren IDarekin eta jasotako mezuarekin bat eginez.

Orain 30 mikrozerbitzu inguru ditugu, hainbat taldetan bana daitezkeenak:

  1. Konfigurazioaren kudeaketa.
  2. Erabiltzaileekiko informazioa eta interakzioa (mezulariak, posta).
  3. Iturburu kodearekin lan egitea.
  4. Inplementazio tresnekin integratzea (jenkins, nomada, kontsul, etab.).
  5. Jarraipena (argitalpenak, akatsak, etab.).
  6. Web utilitateak (proba-inguruneak kudeatzeko, estatistikak biltzeko, etab. UI).
  7. Zereginen jarraitzaile eta antzeko sistemekin integratzea.
  8. Lan-fluxuen kudeaketa zeregin desberdinetarako.

Lan-fluxuaren zereginak

Integro-k zereginen bizi-zikloarekin lotutako jarduerak automatizatzen ditu. Termino sinplifikatuetan, zeregin baten bizi-zikloa Jira-n zeregin baten lan-fluxu gisa ulertuko da. Gure garapen-prozesuek hainbat lan-fluxu-aldaera dituzte proiektuaren, zeregin motaren eta ataza jakin batean aukeratutako aukeren arabera. 

Ikus dezagun gehien erabiltzen dugun lan-fluxua:

Scriptetatik gure plataformara: nola automatizatu genuen garapena CIANen

Diagraman, engranajeak adierazten du Integro-k trantsizioa automatikoki deitzen duela, eta giza irudiak, berriz, pertsona batek eskuz trantsizioa deitzen duela adierazten du. Ikus ditzagun zeregin batek lan-fluxu honetan har ditzakeen hainbat bide.

Guztiz eskuzko probak DEV+BETAn proba kanariorik gabe (normalean honela askatzen dugu monolito bat):

Scriptetatik gure plataformara: nola automatizatu genuen garapena CIANen

Beste trantsizio-konbinazio batzuk egon daitezke. Batzuetan, arazo batek hartuko duen bidea Jira-ko aukeren bidez hauta daiteke.

Zereginen mugimendua

Ikus ditzagun zeregin bat "DEV Testing + Canary Tests" lan-fluxuan zehar egiten diren urrats nagusiak:

1. Garatzaileak edo PM-k sortzen du zeregina.

2. Garatzaileak zeregina lanera eramaten du. Amaitu ondoren, BERRIKUSTEN egoerara aldatzen da.

3. Jirak Webhook bat bidaltzen du Jira mikrozerbitzura (Jira-rekin integratzeko arduraduna).

4. Jira mikrozerbitzuak eskaera bat bidaltzen dio Flow zerbitzura (lana egiten den barne-fluxuen arduraduna) lan-fluxua abiarazteko.

5. Flow zerbitzuaren barruan:

  • Ebaluatzaileak zereginari esleitzen zaizkio (erabiltzaileei buruz dena dakien mikrozerbitzua + Jira mikrozerbitzua).
  • Iturria mikrozerbitzuaren bidez (biltegiei eta adarrei buruz badaki, baina ez du kodearekin berarekin funtzionatzen), gure alearen adar bat duten biltegien bilaketa egiten da (bilaketa errazteko, adarraren izena bat dator gaiarekin zenbakia Jiran). Gehienetan, zeregin batek adar bakarra du biltegi batean; horrek inplementazio-ilararen kudeaketa errazten du eta biltegien arteko konektibitatea murrizten du.
  • Aurkitutako adar bakoitzeko, ekintza sekuentzia hau egiten da:

    i) Adar nagusia eguneratzea (kodearekin lan egiteko Git mikrozerbitzua).
    ii) Garatzaileak aldaketetarako adarra blokeatzen du (Bitbucket mikrozerbitzua).
    iii) Adar honetarako Pull Request bat sortzen da (Bitbucket mikrozerbitzua).
    iv) Pull Request berri bati buruzko mezu bat bidaltzen da garatzaileen txatetara (Jakinarazi mikrozerbitzuari jakinarazpenekin lan egiteko).
    v) Eraiki, probatu eta inplementatu zereginak DEV-n hasten dira (Jenkins-ekin lan egiteko Jenkins mikrozerbitzua).
    vi) Aurreko urrats guztiak ondo betetzen badira, Integro-k bere Onarpena jartzen du Pull Request-en (Bitbucket mikrozerbitzua).

  • Integro izendatutako ebaluatzaileen Pull Request onarpena zain dago.
  • Beharrezko onespen guztiak jaso bezain laster (proba automatikoak positiboki gainditu dira barne), Integro-k zeregina Test on Dev (Jira mikrozerbitzua) egoerara transferitzen du.

6. Probatzaileek zeregina probatzen dute. Arazorik ez badago, zeregina Eraikitzeko Prest egoerara pasatzen da.

7. Integro-k zeregina askatzeko prest dagoela "ikusten du" eta inplementazioa hasten du kanariar moduan (Jenkins mikrozerbitzua). Askatzeko prest egotea arau multzo batek zehazten du. Adibidez, zeregina behar den egoeran dago, ez dago blokeorik beste zereginetan, ez dago mikrozerbitzu honen karga aktiborik, etab.

8. Zeregin Canary egoerara transferitzen da (Jira mikrozerbitzua).

9. Jenkinsek inplementazio-zeregin bat abiarazten du Nomad-en bidez canary moduan (normalean 1-3 instantzia) eta kaleratze-jarraipen-zerbitzuari (DeployWatch microservice) jakinarazten dio inplementazioari buruz.

10. DeployWatch mikrozerbitzuak errorearen atzeko planoa biltzen du eta erreakzionatzen du, beharrezkoa bada. Errorearen atzeko planoa gainditzen bada (atzealdeko araua automatikoki kalkulatzen da), garatzaileei Jakinarazi mikrozerbitzuaren bidez jakinarazten zaie. 5 minuturen buruan garatzaileak ez badu erantzun (Bereratu edo Egon egin klik), orduan kanariar instantzia automatikoki atzera botako da. Atzeko planoa gainditzen ez bada, garatzaileak eskuz abiarazi beharko du zereginen inplementazioa Produkziora (interfazeko botoi batean klik eginez). 60 minuturen buruan garatzaileak ez badu abiarazi Produkziorako inplementazioa, kanariar-instantziak ere atzera egingo dira segurtasun arrazoiengatik.

11. Ekoizpenerako hedapena abiarazi ondoren:

  • Ataza Produkzioaren egoerara (Jira mikrozerbitzua) transferitzen da.
  • Jenkins mikrozerbitzuak inplementazio-prozesua hasten du eta DeployWatch mikrozerbitzuari inplementazioari buruz jakinarazten dio.
  • DeployWatch mikrozerbitzuak Ekoizpeneko edukiontzi guztiak eguneratu direla egiaztatzen du (denak eguneratu ez ziren kasuak egon ziren).
  • Notify mikrozerbitzuaren bidez, inplementazioaren emaitzei buruzko jakinarazpena bidaltzen zaio Produkziora.

12. Garatzaileek 30 minutu izango dituzte Produkziotik zeregin bat atzera egiten hasteko, mikrozerbitzuen portaera okerra hautematen bada. Denbora hori igarota, zeregina automatikoki batuko da maisuan (Git mikrozerbitzua).

13. Maisuarekin bat egin ondoren, zereginaren egoera Itxita (Jira mikrozerbitzua) izango da.

Diagramak ez du guztiz zehatza denik (errealitatean are urrats gehiago daude), baina prozesuetan integrazio-maila ebaluatzeko aukera ematen du. Ez dugu eskema hau idealtzat jotzen eta askapen automatikoaren eta hedapenaren euskarriaren prozesuak hobetzen ari gara.

Zer da hurrengoa

Automatizazioa garatzeko plan handiak ditugu, adibidez, monolitoen bertsioetan eskuzko eragiketak ezabatzea, inplementazio automatikoan monitorizazioa hobetzea eta garatzaileekiko interakzioa hobetzea.

Baina geldi gaitezen hemen oraingoz. Automatizazioaren berrikuspenean gai asko landu genituen azaletik, batzuk ez ziren batere ukitu, beraz pozik erantzungo ditugu galderak. Xehetasunez estali beharreko iradokizunen zain gaude, idatzi iruzkinetan.

Iturria: www.habr.com

Gehitu iruzkin berria