Vår implementering av Continuous Deployment på kundens plattform

Vi i True Engineering har satt opp en prosess for kontinuerlig levering av oppdateringer til kundeservere og ønsker å dele denne opplevelsen.

Til å begynne med utviklet vi et online system for kunden og implementerte det i vår egen Kubernetes-klynge. Nå har høylastløsningen vår flyttet til kundens plattform, som vi har satt opp en helautomatisk kontinuerlig distribusjonsprosess for. Takket være dette akselererte vi time-to-market - levering av endringer i produktmiljøet.

I denne artikkelen vil vi snakke om alle stadiene i prosessen med kontinuerlig distribusjon (CD) eller levering av oppdateringer til kundens plattform:

  1. Hvordan starter denne prosessen?
  2. synkronisering med kundens Git-lager,
  3. montering av backend og frontend,
  4. automatisk applikasjonsdistribusjon i et testmiljø,
  5. automatisk distribusjon til Prod.

Vi deler oppsettdetaljene underveis.

Vår implementering av Continuous Deployment på kundens plattform

1. Start CD

Kontinuerlig distribusjon begynner med at utvikleren presser endringer i utgivelsesgrenen til Git-depotet vårt.

Applikasjonen vår kjører på en mikrotjenestearkitektur og alle komponentene er lagret i ett depot. Takket være dette samles og installeres alle mikrotjenester, selv om en av dem er endret.

Vi organiserte arbeidet gjennom ett depot av flere grunner:

  • Enkel utvikling - applikasjonen utvikler seg aktivt, slik at du kan jobbe med all koden samtidig.
  • En enkelt CI/CD-pipeline som garanterer at applikasjonen som et enkelt system består alle tester og leveres til kundens produksjonsmiljø.
  • Vi eliminerer forvirring i versjoner - vi trenger ikke å lagre et kart over mikrotjenesteversjoner og beskrive konfigurasjonen for hver mikrotjeneste i Helm-skript.

2. Synkronisering med Git-lageret av kundens kildekode

Endringer som gjøres synkroniseres automatisk med kundens Git-lager. Der konfigureres applikasjonssammenstillingen, som startes etter oppdatering av grenen, og distribusjon til fortsettelsen. Begge prosessene stammer fra deres miljø fra et Git-depot.

Vi kan ikke jobbe med kundens depot direkte fordi vi trenger våre egne miljøer for utvikling og testing. Vi bruker Git-depotet vårt til disse formålene - det er synkronisert med Git-depotet deres. Så snart en utvikler legger inn endringer i den aktuelle grenen av vårt depot, sender GitLab umiddelbart disse endringene til kunden.

Vår implementering av Continuous Deployment på kundens plattform

Etter dette må du gjøre monteringen. Den består av flere stadier: backend og frontend montering, testing og levering til produksjon.

3. Montering av backend og frontend

Å bygge backend og frontend er to parallelle oppgaver som utføres i GitLab Runner-systemet. Den opprinnelige monteringskonfigurasjonen er plassert i samme depot.

Veiledning for å skrive et YAML-skript for bygging i GitLab.

GitLab Runner tar koden fra det nødvendige depotet, setter den sammen med Java-applikasjonsbyggkommandoen og sender den til Docker-registeret. Her setter vi sammen backend og frontend, skaffer Docker-bilder, som vi legger inn i et depot på kundens side. For å administrere Docker-bilder bruker vi Gradle-plugin.

Vi synkroniserer versjonene av bildene våre med utgivelsesversjonen som vil bli publisert i Docker. For jevn drift har vi gjort flere justeringer:

1. Containere bygges ikke om mellom testmiljøet og produksjonsmiljøet. Vi gjorde parametriseringer slik at samme container kunne fungere med alle innstillinger, miljøvariabler og tjenester både i testmiljøet og i produksjonen uten ombygging.

2. For å oppdatere en applikasjon via Helm, må du spesifisere versjonen. Vi bygger backend, frontend og oppdaterer applikasjonen – dette er tre forskjellige oppgaver, så det er viktig å bruke samme versjon av applikasjonen overalt. For denne oppgaven bruker vi data fra Git-historien, siden vår K8S-klyngekonfigurasjon og applikasjoner er i samme Git-depot.

Vi får applikasjonsversjonen fra kommandoutførelsesresultatene
git describe --tags --abbrev=7.

4. Automatisk distribusjon av alle endringer i testmiljøet (UAT)

Det neste trinnet i dette byggeskriptet er å automatisk oppdatere K8S-klyngen. Dette skjer forutsatt at hele applikasjonen er bygget og alle artefakter har blitt publisert til Docker Registry. Etter dette starter testmiljøoppdateringen.

Klyngeoppdateringen begynner å bruke Roroppdatering. Hvis noe som et resultat ikke gikk etter planen, vil Helm automatisk og uavhengig rulle tilbake alle endringene. Arbeidet hans trenger ikke å bli kontrollert.

Vi leverer K8S-klyngekonfigurasjonen sammen med monteringen. Derfor er neste trinn å oppdatere den: configMaps, distribusjoner, tjenester, hemmeligheter og andre K8S-konfigurasjoner som vi har endret.

Helm kjører deretter en RollOut-oppdatering av selve applikasjonen i testmiljøet. Før applikasjonen distribueres til produksjon. Dette gjøres slik at brukerne manuelt kan teste forretningsfunksjonene som vi legger inn i testmiljøet.

5. Automatisk distribusjon av alle endringer i Prod

For å distribuere en oppdatering til produksjonsmiljøet, trenger du bare å klikke på én knapp i GitLab – og containerne blir umiddelbart levert til produksjonsmiljøet.

Den samme applikasjonen kan fungere i forskjellige miljøer – test og produksjon – uten ombygging. Vi bruker de samme artefaktene uten å endre noe i applikasjonen, og vi setter parameterne eksternt.

Fleksibel parameterisering av applikasjonsinnstillinger avhenger av miljøet applikasjonen skal kjøres i. Vi har flyttet alle miljøinnstillingene eksternt: alt er parametrisert gjennom K8S-konfigurasjonen og Helm-parametrene. Når Helm distribuerer en sammenstilling til testmiljøet, brukes testinnstillingene på den, og produktinnstillingene brukes på produksjonsmiljøet.

Det vanskeligste var å parameterisere alle brukte tjenester og variabler som avhenger av miljøet, og oversette dem til miljøvariabler og beskrivelse-konfigurasjoner av miljøparametere for Helm.

Applikasjonsinnstillinger bruker miljøvariabler. Verdiene deres er satt i containere ved hjelp av K8S configmap, som er malt ved hjelp av Go-maler. For eksempel kan du sette en miljøvariabel til domenenavnet slik:

APP_EXTERNAL_DOMAIN: {{ (pluck .Values.global.env .Values.app.properties.app_external_domain | first) }}

.Values.global.env – denne variabelen lagrer navnet på miljøet (prod, stage, UAT).
.Values.app.properties.app_external_domain – i denne variabelen setter vi ønsket domene i .Values.yaml-filen

Når du oppdaterer en applikasjon, oppretter Helm en configmap.yaml-fil fra maler og fyller APP_EXTERNAL_DOMAIN-verdien med ønsket verdi avhengig av miljøet der applikasjonsoppdateringen starter. Denne variabelen er allerede satt i beholderen. Den kan nås fra applikasjonen, så hvert applikasjonsmiljø vil ha en annen verdi for denne variabelen.

Relativt nylig dukket K8S-støtte opp i Spring Cloud, inkludert arbeid med configMaps: Vårsky Kubernetes. Mens prosjektet aktivt utvikler seg og endrer seg radikalt, kan vi ikke bruke det i produksjon. Men vi overvåker aktivt tilstanden og bruker den i DEV-konfigurasjoner. Så snart det stabiliserer seg, vil vi bytte fra å bruke miljøvariabler til det.

Totalt

Så kontinuerlig distribusjon er konfigurert og fungerer. Alle oppdateringer skjer med ett tastetrykk. Levering av endringer i produktmiljøet skjer automatisk. Og, viktigere, oppdateringer stopper ikke systemet.

Vår implementering av Continuous Deployment på kundens plattform

Fremtidsplaner: automatisk databasemigrering

Vi tenkte på å oppgradere databasen og muligheten for å rulle tilbake disse endringene. Tross alt kjører to forskjellige versjoner av applikasjonen samtidig: den gamle kjører, og den nye er oppe. Og vi slår av den gamle først når vi er sikre på at den nye versjonen fungerer. Databasemigreringen skal tillate deg å jobbe med begge versjonene av applikasjonen.

Derfor kan vi ikke bare endre kolonnenavnet eller andre data. Men vi kan opprette en ny kolonne, kopiere data fra den gamle kolonnen inn i den og skrive triggere som, når du oppdaterer dataene, samtidig vil kopiere og oppdatere dem i en annen kolonne. Og etter vellykket distribusjon av den nye versjonen av applikasjonen, etter støtteperioden etter lansering, vil vi kunne slette den gamle kolonnen og utløseren som har blitt unødvendig.

Hvis den nye versjonen av applikasjonen ikke fungerer som den skal, kan vi rulle tilbake til forrige versjon, inkludert forrige versjon av databasen. Kort sagt, endringene våre vil tillate deg å jobbe samtidig med flere versjoner av applikasjonen.

Vi planlegger å automatisere databasemigrering via K8S-jobb, og integrere den i CD-prosessen. Og vi vil definitivt dele denne opplevelsen på Habré.

Kilde: www.habr.com

Legg til en kommentar