Docker-en mikrozerbitzuen proba automatizatuak etengabe integratzeko

Mikrozerbitzuen arkitekturaren garapenarekin erlazionatutako proiektuetan, CI/CD aukera atsegin baten kategoriatik premiazko beharraren kategoriara pasatzen da. Proba automatikoak etengabeko integrazioaren zati bat da, eta horri esker, taldeari arratsalde atsegin ugari eman diezaioke familia eta lagunekin. Bestela, proiektua sekula ez amaitzeko arriskua dago.

Posible da mikrozerbitzuaren kode osoa unitate-probekin estaltzea objektu simulatuekin, baina honek arazoa partzialki konpontzen du eta galdera eta zailtasun ugari uzten ditu, batez ere datuekin lana probatzerakoan. Beti bezala, larrienak datu-base erlazional batean datu-koherentzia probatzea, hodeiko zerbitzuekin lana probatzea eta hipotesi okerrak egitea dira objektu simulatuak idaztean.

Hori guztia eta apur bat gehiago mikrozerbitzu osoa Docker edukiontzi batean probatuz konpon daiteke. Proben baliozkotasuna bermatzeko zalantzarik gabeko abantaila bat ekoizpenean sartzen diren Docker-eko irudi berberak probatzen direla da.

Ikuspegi honen automatizazioak hainbat arazo dakartza, eta horien konponbidea jarraian deskribatuko da:

  • ataza paraleloen gatazkak docker ostalari berean;
  • identifikatzaileen gatazkak datu-basean proba-iterazioetan;
  • mikrozerbitzuak prest egongo diren zain;
  • erregistroak bateratzea eta kanpoko sistemetara ateratzea;
  • irteerako HTTP eskaerak probatzea;
  • web socket proba (SignalR erabiliz);
  • OAuth autentifikazioa eta baimena probatzen.

Artikulu hau oinarritzen da nire hizkera SECR 2019-n. Beraz, irakurtzeko alferrak direnentzat, hona hemen hitzaldiaren grabaketa.

Docker-en mikrozerbitzuen proba automatizatuak etengabe integratzeko

Artikulu honetan esango dizut nola erabili script bat proban dagoen zerbitzua exekutatzeko, datu-base bat eta Amazon AWS zerbitzuak Docker-en, ondoren Postman-en probak egiten eta, amaitu ondoren, sortutako edukiontziak gelditu eta ezabatu. Kodea aldatzen den bakoitzean probak egiten dira. Horrela, bertsio bakoitzak AWS datu-basearekin eta zerbitzuekin behar bezala funtzionatzen duela ziurtatzen dugu.

Script bera garatzaileek exekutatzen dute Windows-eko mahaigainetan eta Gitlab CI zerbitzariak Linux-en.

Justifikatzeko, proba berriak sartzeak ez luke tresna gehigarririk instalatu behar ez garatzailearen ordenagailuan, ez probak konpromezu batean exekutatzen diren zerbitzarian. Docker-ek arazo hau konpontzen du.

Proba tokiko zerbitzari batean exekutatu behar da arrazoi hauengatik:

  • Sarea ez da inoiz guztiz fidagarria. Mila eskaeratik batek huts egin dezake;
    Kasu honetan, proba automatikoak ez du funtzionatuko, lana geldituko da eta arrazoia erregistroetan bilatu beharko duzu;
  • Hirugarrenen zerbitzu batzuek ez dute maizegi eskaerarik onartzen.

Horrez gain, ez da komeni standa erabiltzea, zeren eta:

  • Stand bat hautsi daiteke bertan exekutatzen den kode txarragatik ez ezik, kode zuzenak prozesatu ezin dituen datuengatik ere;
  • Probak berak egindako aldaketa guztiak atzera egiten saiatzen garen arren, zerbait gaizki joan daiteke (bestela, zergatik probatu?).

Proiektuari eta prozesuen antolaketari buruz

Gure enpresak Docker-en exekutatzen den mikrozerbitzuen web aplikazio bat garatu du Amazon AWS hodeian. Proiektuan jada erabiltzen ziren unitate-probak, baina sarritan gertatzen ziren unitate-probak hauteman ez zituzten akatsak. Beharrezkoa zen mikrozerbitzu oso bat probatu datu-basearekin eta Amazon zerbitzuekin batera.

Proiektuak etengabeko integrazio prozesu estandar bat erabiltzen du, mikrozerbitzua konpromezu bakoitzean probatzea barne hartzen duena. Zeregin bat esleitu ondoren, garatzaileak aldaketak egiten ditu mikrozerbitzuan, eskuz probatzen du eta eskuragarri dauden proba automatizatu guztiak exekutatzen ditu. Beharrezkoa bada, garatzaileak probak aldatzen ditu. Arazorik aurkitzen ez bada, konpromezu bat egiten da gai honen adarrean. Konpromiso bakoitzaren ondoren, probak automatikoki exekutatzen dira zerbitzarian. Adar komun batean bateratzea eta proba automatikoak abiarazten ditu berrikuspen arrakastatsu baten ondoren. Partekatutako sukurtsaleko probak gainditzen badira, zerbitzua automatikoki eguneratuko da proba-ingurunean Amazon Elastic Container Service-n (bankua). Standa beharrezkoa da garatzaile eta probatzaile guztientzat, eta ez da komeni haustea. Ingurune honetako probatzaileek konponketa bat edo eginbide berri bat egiaztatzen dute eskuzko probak eginez.

Proiektuaren arkitektura

Docker-en mikrozerbitzuen proba automatizatuak etengabe integratzeko

Aplikazioak hamar zerbitzu baino gehiago ditu. Horietako batzuk .NET Core-n idatzita daude eta beste batzuk NodeJs-en. Zerbitzu bakoitza Docker edukiontzi batean exekutatzen da Amazon Elastic Container Service-n. Bakoitzak bere Postgres datu-basea du, eta batzuek Redis ere badute. Ez dago datu-base komunik. Hainbat zerbitzuk datu bera behar badute, datu horiek, aldatzen direnean, zerbitzu horietako bakoitzari SNS (Simple Notification Service) eta SQS (Amazon Simple Queue Service) bidez igortzen dira, eta zerbitzuek beren datu-baseetan gordetzen dituzte.

SQS eta SNS

SQS-k mezuak ilaran jartzeko eta ilaran mezuak irakurtzeko aukera ematen du HTTPS protokoloa erabiliz.

Hainbat zerbitzuk ilara bat irakurtzen badute, mezu bakoitza horietako bati bakarrik iristen da. Hau erabilgarria da zerbitzu bereko hainbat instantzia exekutatzen direnean karga haien artean banatzeko.

Mezu bakoitza hainbat zerbitzutara bidaltzea nahi baduzu, hartzaile bakoitzak bere ilara propioa izan behar du, eta SNS beharrezkoa da mezuak ilara anitzetan bikoizteko.

SNSn gai bat sortzen duzu eta harpidetzen zara, adibidez, SQS ilara bat. Gaiari mezuak bidal ditzakezu. Kasu honetan, mezua gai honetara harpidetutako ilara bakoitzari bidaltzen zaio. SNS-k ez du mezuak irakurtzeko metodorik. Arazketan edo proban SNSra zer bidaltzen den jakin behar baduzu, SQS ilara bat sor dezakezu, nahi duzun gaira harpidetu eta ilara irakurri.

Docker-en mikrozerbitzuen proba automatizatuak etengabe integratzeko

API Gateway

Zerbitzu gehienak ez dira zuzenean Internetetik eskura daitezke. Sarbidea API Gateway bidez egiten da, sarbide-eskubideak egiaztatzen dituena. Hau ere gure zerbitzua da, eta probak ere badaude.

Denbora errealeko jakinarazpenak

Aplikazioak erabiltzen du SeinaleaRerabiltzaileari denbora errealeko jakinarazpenak erakusteko. Hori jakinarazpen zerbitzuan ezartzen da. Internetetik zuzenean eskura daiteke eta bera OAuth-ekin funtzionatzen du, ez zelako praktikoa izan Gateway-n Web socketetarako euskarria sortzea, OAuth eta jakinarazpen-zerbitzua integratzearekin alderatuta.

Proba-ikuspegi ezaguna

Unitate-probek datu-basea bezalako gauzak itxurazko objektuekin ordezkatzen dituzte. Mikrozerbitzu bat, adibidez, atzerriko gako batekin taula batean erregistro bat sortzen saiatzen bada, eta gako horrek erreferentziatutako erregistroa existitzen ez bada, ezin izango da eskaera osatu. Unitate-probak ezin dute hau detektatu.

Π’ Microsoft-en artikulua Memoria barneko datu-base bat erabiltzea eta objektu simulatuak ezartzea proposatzen da.

Memoria barneko datu-basea Entity Framework-ek onartzen duen DBMSetako bat da. Proba egiteko bereziki sortu zen. Datu-base horretako datuak erabiltzen duen prozesua amaitu arte soilik gordetzen dira. Ez du eskatzen taulak sortzea eta ez du datuen osotasuna egiaztatzen.

Objektu simulatuek ordezkatzen ari diren klasea modelatzen dute probaren garatzaileak nola funtzionatzen duen ulertzen duen neurrian.

Proba bat exekutatzen duzunean Postgres-ek automatikoki abiarazteko eta migrazioak egiteko nola lortu ez dago Microsoft-eko artikuluan zehazten. Nire irtenbideak hori egiten du eta, gainera, ez du koderik gehitzen bereziki probetarako mikrozerbitzuari berari.

Goazen konponbidera

Garapen-prozesuan, argi geratu zen unitate-probak ez zirela nahikoa arazo guztiak garaiz aurkitzeko, beraz, gai honi beste angelu batetik jorratzea erabaki zen.

Proba-ingurune bat konfiguratzea

Lehenengo zeregina proba-ingurune bat zabaltzea da. Mikrozerbitzu bat exekutatzeko beharrezkoak diren urratsak:

  • Konfiguratu proban dagoen zerbitzua tokiko ingurunerako, zehaztu datu-basera eta AWSra konektatzeko xehetasunak ingurune-aldagaietan;
  • Hasi Postgres eta egin migrazioa Liquibase exekutatuz.
    DBMS erlazionaletan, datu-basean datuak idatzi aurretik, datu-eskema bat sortu behar duzu, hau da, taulak. Aplikazio bat eguneratzean, taulak bertsio berriak erabiltzen duen formulariora eraman behar dira, eta, ahal dela, datuak galdu gabe. Honi migrazioa deitzen zaio. Hasieran hutsik dagoen datu-base batean taulak sortzea migrazioaren kasu berezi bat da. Migrazioa aplikazioan bertan integra daiteke. .NET-ek eta NodeJS-ek migrazio-esparruak dituzte. Gure kasuan, segurtasun arrazoiengatik, mikrozerbitzuei datu-eskema aldatzeko eskubidea kentzen zaie, eta migrazioa Liquibase erabiliz egiten da.
  • Abiarazi Amazon LocalStack. Hau etxean exekutatzeko AWS zerbitzuen inplementazioa da. Docker Hub-en LocalStack-erako prest dagoen irudi bat dago.
  • Exekutatu scripta LocalStack-en beharrezko entitateak sortzeko. Shell scriptek AWS CLI erabiltzen dute.

Proiektuaren probak egiteko erabiltzen da Postaria. Aurretik bazegoen, baina eskuz abiarazi zen eta standean jada zabaldutako aplikazio bat probatu zuten. Tresna honek HTTP(S) eskaera arbitrarioak egiteko eta erantzunak itxaropenekin bat datozen ala ez egiaztatzeko aukera ematen du. Kontsultak bilduma batean konbinatzen dira eta bilduma osoa exekutatu daiteke.

Docker-en mikrozerbitzuen proba automatizatuak etengabe integratzeko

Nola funtzionatzen du proba automatikoak?

Proba egiten den bitartean, denak funtzionatzen du Docker-en: proban dagoen zerbitzua, Postgres, migrazio tresna eta Postman, edo hobeto esanda, bere kontsolaren bertsioa - Newman.

Docker-ek hainbat arazo konpontzen ditu:

  • Ostalariaren konfigurazioarekiko independentzia;
  • Mendekotasunak instalatzea: Docker-ek irudiak deskargatzen ditu Docker Hub-etik;
  • Sistema jatorrizko egoerara itzultzea: edukiontziak kendu besterik ez.

Docker-konposatu edukiontziak sare birtual batean batzen ditu, Internetetik isolatuta, eta bertan edukiontziak domeinu-izenen bidez elkar aurkitzen dira.

Proba shell script batek kontrolatzen du. Proba Windows-en exekutatzeko git-bash erabiltzen dugu. Horrela, script bat nahikoa da Windows zein Linuxentzat. Git eta Docker proiektuko garatzaile guztiek instalatzen dituzte. Git Windows-en instalatzean, git-bash instalatzen da, beraz, denek ere badute.

Scriptak urrats hauek egiten ditu:

  • Docker irudiak eraikitzea
    docker-compose build
  • Datu-basea eta LocalStack abiarazi
    docker-compose up -d <ΠΊΠΎΠ½Ρ‚Π΅ΠΉΠ½Π΅Ρ€>
  • Datu-basearen migrazioa eta LocalStack-en prestaketa
    docker-compose run <ΠΊΠΎΠ½Ρ‚Π΅ΠΉΠ½Π΅Ρ€>
  • Proba egiten ari den zerbitzua martxan jartzea
    docker-compose up -d <сСрвис>
  • Proba exekutatzen (Newman)
  • Edukiontzi guztiak gelditzea
    docker-compose down
  • Emaitzak Slack-en argitaratzen
    Txat bat dugu, non marka berdea edo gurutze gorria duten mezuak eta erregistrorako esteka bat doazen.

Docker-eko irudi hauek urrats hauetan parte hartzen dute:

  • Probatzen ari den zerbitzua ekoizpenaren irudi bera da. Proba egiteko konfigurazioa ingurune-aldagaien bidez egiten da.
  • Postgres, Redis eta LocalStack-erako, Docker Hub-eko prest egindako irudiak erabiltzen dira. Liquibase eta Newmanentzako prest egindako irudiak ere badaude. Euren hezurduran gurea eraikitzen dugu, bertan gure fitxategiak gehituz.
  • LocalStack prestatzeko, prest egindako AWS CLI irudi bat erabiltzen duzu eta bertan oinarritutako script bat duen irudi bat sortzen duzu.

Erabiltzea bolumen, ez duzu Docker irudi bat eraiki beharrik edukiontzira fitxategiak gehitzeko. Hala ere, bolumenak ez dira egokiak gure ingurunerako, Gitlab CI atazak beraiek edukiontzietan exekutatzen direlako. Docker edukiontzi batetik kontrola dezakezu, baina bolumenek ostalari-sistemako karpetak soilik muntatzen dituzte, eta ez beste edukiontzi batetik.

Aurkitu ditzakezun arazoak

Presttasunaren zain

Zerbitzu bat duen edukiontzi bat martxan dagoenean, horrek ez du esan nahi konexioak onartzeko prest dagoenik. Konexioak jarraitu arte itxaron behar duzu.

Arazo hau batzuetan script baten bidez konpontzen da itxaron.sh, TCP konexioa ezartzeko aukera baten zain dagoena. Hala ere, LocalStack-ek 502 Bad Gateway errore bat bota dezake. Horrez gain, zerbitzu ugariz osatuta dago, eta horietako bat prest badago, honek ez du ezer esaten besteei buruz.

Erabaki: SQS eta SNSren 200 erantzunaren zain dauden LocalStack hornitzeko scriptak.

Zeregin paraleloen gatazkak

Hainbat proba aldi berean exekutatu daitezke Docker ostalari berean, beraz, edukiontzien eta sarearen izenak bakarrak izan behar dute. Gainera, zerbitzu bereko adar ezberdinetako probak ere aldi berean exekutatu daitezke, beraz, ez da nahikoa haien izenak idazketa fitxategi bakoitzean idaztea.

Erabaki: script-ak COMPOSE_PROJECT_NAME aldagaia balio esklusibo batean ezartzen du.

Windows Ezaugarriak

Docker Windows-en erabiltzean hainbat gauza adierazi nahi ditudanean, esperientzia hauek garrantzitsuak baitira erroreak zergatik gertatzen diren ulertzeko.

  1. Edukiontzi bateko shell scriptek Linux lerro amaierak izan behar dituzte.
    Shell CR ikurra sintaxi errore bat da. Zaila da errore-mezutik hori horrela dela esatea. Windows-en halako script-ak editatzerakoan, testu-editore egoki bat behar duzu. Gainera, bertsioak kontrolatzeko sistema behar bezala konfiguratu behar da.

Honela konfiguratzen da git:

git config core.autocrlf input

  1. Git-bash-ek Linux karpeta estandarrak emulatzen ditu eta, exe fitxategi bati deitzean (docker.exe barne), Linux bide absolutuak Windows bideekin ordezkatzen ditu. Hala ere, honek ez du zentzurik tokiko makinan (edo edukiontzi bateko bideetan) ez dauden bideentzat. Jokabide hau ezin da desgaitu.

Erabaki: gehitu barra gehigarri bat bidearen hasieran: //bin /bin ordez. Linuxek horrelako bideak ulertzen ditu; horretarako, hainbat barra berdinak dira. Baina git-bash-ek ez ditu horrelako bideak ezagutzen eta ez du horiek bihurtzen saiatzen.

Erregistroko irteera

Probak exekutatzen direnean, Newman-en eta probatzen ari den zerbitzuaren erregistroak ikusi nahiko nituzke. Erregistro horien gertaerak elkarri lotuta daudenez, kontsola batean konbinatzea askoz erosoagoa da bi fitxategi bereizi baino. Newman-ek bidez abiarazten du docker-compose exekuzioa, eta beraz, bere irteera kontsolan amaitzen da. Zerbitzuaren irteera ere hara joaten dela ziurtatzea besterik ez da geratzen.

Jatorrizko irtenbidea egitea zen docker-compose banderarik ez -d, baina shell gaitasunak erabiliz, bidali prozesu hau atzeko planora:

docker-compose up <service> &

Honek funtzionatu zuen Docker-etik hirugarrenen zerbitzu batera erregistroak bidaltzea beharrezkoa izan zen arte. docker-compose erregistroak kontsolara ateratzeari utzi zion. Hala ere, taldeak lan egin zuen docker erantsi.

Erabaki:

docker attach --no-stdin ${COMPOSE_PROJECT_NAME}_<сСрвис>_1 &

Identifikatzaile-gatazka proba-iterazioetan

Probak hainbat iteraziotan egiten dira. Datu-basea ez da garbitu. Datu-baseko erregistroek ID bakarrak dituzte. Eskaeretan ID espezifikoak idazten baditugu, gatazka bat izango dugu bigarren errepikapenean.

Hori ekiditeko, IDak bakarrak izan behar dira, edo probak sortutako objektu guztiak ezabatu behar dira. Objektu batzuk ezin dira ezabatu baldintzak direla eta.

Erabaki: sortu GUIDak Postman script-ak erabiliz.

var uuid = require('uuid');
var myid = uuid.v4();
pm.environment.set('myUUID', myid);

Ondoren, erabili ikurra kontsultan {{myUUID}}, aldagaiaren balioarekin ordezkatuko dena.

Elkarlana LocalStack bidez

Probatzen ari den zerbitzuak SQS ilara batean irakurtzen edo idazten badu, hori egiaztatzeko, probak berak ere lan egin behar du ilara honekin.

Erabaki: Postman-en eskaerak LocalStack-era.

AWS zerbitzuen APIa dokumentatuta dago, eta SDKrik gabe kontsultak egiteko aukera ematen du.

Zerbitzu batek ilara batean idazten badu, irakurri eta mezuaren edukia egiaztatzen dugu.

Zerbitzuak mezuak bidaltzen baditu SNSra, prestaketa fasean LocalStack-ek ere ilara bat sortzen du eta SNS gai honetara harpidetzen da. Ondoren, dena goian deskribatutakoari dagokio.

Zerbitzuak ilaratik mezu bat irakurri behar badu, aurreko probako urratsean mezu hau ilaran idatziko dugu.

Proba egiten ari den mikrozerbitzutik sortutako HTTP eskaerak probatzen

Zerbitzu batzuek HTTP bidez funtzionatzen dute AWS ez den beste zerbaitekin, eta AWSren eginbide batzuk ez daude LocalStack-en inplementatzen.

Erabaki: kasu hauetan lagun dezake MockServer, prest egindako irudia daukana Docker zentroa. Espero diren eskaerak eta haiei erantzunak HTTP eskaera baten bidez konfiguratzen dira. APIa dokumentatuta dago, beraz Postman-en eskaerak egiten ditugu.

OAuth autentifikazioa eta baimena probatzen

OAuth erabiltzen dugu eta JSON Web Tokenak (JWT). Probak lokalean exekutatu dezakegun OAuth hornitzaile bat behar du.

Zerbitzuaren eta OAuth hornitzailearen arteko elkarrekintza guztia bi eskaerarekin dator: lehenik, konfigurazioa eskatzen da. /.ezaguna/openid-konfigurazioa, eta ondoren gako publikoa (JWKS) konfigurazioko helbidean eskatzen da. Hau guztia eduki estatikoa da.

Erabaki: Gure probako OAuth hornitzailea edukien zerbitzari estatiko bat da eta bertan dauden bi fitxategi. Tokena behin sortzen da eta Git-ekin konprometitzen da.

SignalR proben ezaugarriak

Postman-ek ez du funtzionatzen websocketekin. SignalR probatzeko tresna berezi bat sortu zen.

SignalR bezero bat arakatzaile bat baino gehiago izan daiteke. .NET Core-ren azpian bezero liburutegi bat dago. Bezeroak, .NET Core-n idatzita, konexio bat ezartzen du, autentifikatu egiten da eta mezu-sekuentzia zehatz baten zain dago. Ustekabeko mezu bat jasotzen bada edo konexioa galtzen bada, bezeroa 1eko kodearekin irtengo da. Espero den azken mezua jasotzen bada, bezeroa 0 kodearekin irtengo da.

Newmanek bezeroarekin aldi berean lan egiten du. Hainbat bezero abiarazten dira mezuak behar dituzten guztiei bidaltzen zaizkiela egiaztatzeko.

Docker-en mikrozerbitzuen proba automatizatuak etengabe integratzeko

Hainbat bezero exekutatzeko, erabili aukera --eskala docker-compose komando lerroan.

Exekutatu aurretik, Postman script-a bezero guztiek konexioak ezartzeko zain dago.
Konexio baten zain egotearen arazoa topatu dugu jada. Baina zerbitzariak zeuden, eta hemen dago bezeroa. Beste ikuspegi bat behar da.

Erabaki: ontzian dagoen bezeroak mekanismoa erabiltzen du Osasun Kontrolaostalariaren gidoiari bere egoeraren berri emateko. Bezeroak fitxategi bat sortzen du bide zehatz batean, esan /healthcheck, konexioa ezarri bezain laster. Docker fitxategiko HealthCheck script-ak itxura hau du:

HEALTHCHECK --interval=3s CMD if [ ! -e /healthcheck ]; then false; fi

Team docker ikuskatu Ontziaren egoera normala, osasun egoera eta irteera kodea erakusten ditu.

Newman amaitu ondoren, script-ak bezeroa duten edukiontzi guztiak amaitu direla egiaztatzen du, 0 kodearekin.

Happinnes existitzen da

Goian azaldutako zailtasunak gainditu ondoren, korrika proba egonkorrak izan genituen. Probetan, zerbitzu bakoitzak unitate bakar gisa funtzionatzen du, datu-basearekin eta Amazon LocalStack-ekin elkarreraginean.

Proba hauek 30 garatzaile baino gehiagoko talde bat babesten dute aplikazio bateko akatsetatik 10 mikrozerbitzu baino gehiagoren interakzio konplexua maiz inplementatzen dituztenekin.

Iturria: www.habr.com

Gehitu iruzkin berria