Vår implementering av Continuous Deployment på kundens plattform

Vi på True Engineering har satt upp en process för kontinuerlig leverans av uppdateringar till kundservrar och vill dela denna upplevelse.

Till att börja med utvecklade vi ett onlinesystem för kunden och implementerade det i vårt eget Kubernetes-kluster. Nu har vår högbelastningslösning flyttats till kundens plattform, för vilken vi har satt upp en helautomatisk kontinuerlig implementeringsprocess. Tack vare detta accelererade vi time-to-market - leveransen av förändringar i produktmiljön.

I den här artikeln kommer vi att prata om alla steg i processen för kontinuerlig distribution (CD) eller leverans av uppdateringar till kundens plattform:

  1. Hur börjar denna process?
  2. synkronisering med kundens Git-förråd,
  3. montering av backend och frontend,
  4. automatisk applikationsdistribution i en testmiljö,
  5. automatisk distribution till Prod.

Vi kommer att dela installationsdetaljerna längs vägen.

Vår implementering av Continuous Deployment på kundens plattform

1. Starta CD

Kontinuerlig distribution börjar med att utvecklaren driver ändringar i releasegrenen av vårt Git-förråd.

Vår applikation körs på en mikrotjänstarkitektur och alla dess komponenter lagras i ett arkiv. Tack vare detta samlas och installeras alla mikrotjänster, även om en av dem har ändrats.

Vi organiserade arbetet genom ett arkiv av flera anledningar:

  • Enkel utveckling - applikationen utvecklas aktivt, så du kan arbeta med all kod på en gång.
  • En enda CI/CD-pipeline som garanterar att applikationen som ett enda system klarar alla tester och levereras till kundens produktionsmiljö.
  • Vi eliminerar förvirring i versioner - vi behöver inte lagra en karta över mikrotjänstversioner och beskriva dess konfiguration för varje mikrotjänst i Helm-skript.

2. Synkronisering med Git-förrådet av kundens källkod

Ändringar som görs synkroniseras automatiskt med kundens Git-förråd. Där konfigureras applikationssammansättningen, som startas efter uppdatering av grenen, och distribueras till fortsättningen. Båda processerna har sitt ursprung i sin miljö från ett Git-förråd.

Vi kan inte arbeta med kundens förråd direkt eftersom vi behöver våra egna miljöer för utveckling och testning. Vi använder vårt Git-förråd för dessa ändamål - det är synkroniserat med deras Git-förråd. Så fort en utvecklare lägger upp ändringar i lämplig gren av vårt arkiv, skickar GitLab omedelbart dessa ändringar till kunden.

Vår implementering av Continuous Deployment på kundens plattform

Efter detta måste du göra monteringen. Den består av flera steg: backend och frontend montering, testning och leverans till produktion.

3. Montering av backend och frontend

Att bygga backend och frontend är två parallella uppgifter som utförs i GitLab Runner-systemet. Dess ursprungliga monteringskonfiguration finns i samma förråd.

Handledning för att skriva ett YAML-skript för att bygga i GitLab.

GitLab Runner tar koden från det nödvändiga arkivet, sätter ihop den med Java-applikationsbyggkommandot och skickar den till Docker-registret. Här monterar vi backend och frontend, skaffar Docker-bilder, som vi lägger in i ett arkiv på kundens sida. För att hantera Docker-bilder använder vi Gradle plugin.

Vi synkroniserar versionerna av våra bilder med releaseversionen som kommer att publiceras i Docker. För smidig drift har vi gjort flera justeringar:

1. Behållare byggs inte om mellan testmiljön och produktionsmiljön. Vi gjorde parametriseringar så att samma container kunde fungera med alla inställningar, miljövariabler och tjänster både i testmiljön och i produktionen utan att behöva byggas om.

2. För att uppdatera en applikation via Helm måste du ange dess version. Vi bygger backend, frontend och uppdaterar applikationen – det är tre olika uppgifter, så det är viktigt att använda samma version av applikationen överallt. För denna uppgift använder vi data från Git-historiken, eftersom vår K8S-klusterkonfiguration och applikationer finns i samma Git-förråd.

Vi får applikationsversionen från resultatet av kommandokörningen
git describe --tags --abbrev=7.

4. Automatisk distribution av alla ändringar i testmiljön (UAT)

Nästa steg i detta byggskript är att automatiskt uppdatera K8S-klustret. Detta sker förutsatt att hela applikationen har byggts och alla artefakter har publicerats till Docker Registry. Efter detta startar uppdateringen av testmiljön.

Klusteruppdateringen börjar använda Hjälmuppdatering. Om, som ett resultat, något inte gick enligt plan, kommer Helm automatiskt och oberoende att återställa alla sina ändringar. Hans arbete behöver inte kontrolleras.

Vi levererar K8S-klusterkonfigurationen tillsammans med monteringen. Därför är nästa steg att uppdatera den: configMaps, distributioner, tjänster, hemligheter och alla andra K8S-konfigurationer som vi har ändrat.

Helm kör sedan en RollOut-uppdatering av själva applikationen i testmiljön. Innan applikationen distribueras till produktion. Detta görs så att användare manuellt kan testa de affärsfunktioner som vi lägger in i testmiljön.

5. Automatisk distribution av alla ändringar i Prod

För att distribuera en uppdatering till produktionsmiljön behöver du bara klicka på en knapp i GitLab - och behållarna levereras omedelbart till produktionsmiljön.

Samma applikation kan fungera i olika miljöer – test och produktion – utan att behöva byggas om. Vi använder samma artefakter utan att ändra något i applikationen, och vi ställer in parametrarna externt.

Flexibel parametrering av applikationsinställningar beror på i vilken miljö applikationen kommer att köras. Vi har flyttat alla miljöinställningar externt: allt parametreras genom K8S-konfigurationen och Helm-parametrarna. När Helm distribuerar en sammansättning till testmiljön tillämpas testinställningarna på den och produktinställningarna tillämpas på produktionsmiljön.

Det svåraste var att parametrisera alla använda tjänster och variabler som är beroende av miljön, och översätta dem till miljövariabler och beskrivnings-konfigurationer av miljöparametrar för Helm.

Programinställningar använder miljövariabler. Deras värden ställs in i behållare med hjälp av K8S configmap, som är mall med hjälp av Go-mallar. Till exempel kan du ställa in en miljövariabel för domännamnet så här:

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

.Values.global.env – denna variabel lagrar namnet på miljön (prod, stage, UAT).
.Values.app.properties.app_external_domain – i denna variabel ställer vi in ​​önskad domän i filen .Values.yaml

När du uppdaterar en applikation skapar Helm en configmap.yaml-fil från mallar och fyller värdet APP_EXTERNAL_DOMAIN med önskat värde beroende på i vilken miljö applikationsuppdateringen startar. Denna variabel är redan inställd i behållaren. Den kan nås från applikationen, så varje applikationsmiljö kommer att ha olika värde för denna variabel.

Relativt nyligen dök K8S-stöd upp i Spring Cloud, inklusive att arbeta med configMaps: Vårmoln Kubernetes. Samtidigt som projektet aktivt utvecklas och förändras radikalt kan vi inte använda det i produktionen. Men vi övervakar aktivt dess tillstånd och använder den i DEV-konfigurationer. Så snart det stabiliseras kommer vi att byta från att använda miljövariabler till det.

Totalt

Så, kontinuerlig distribution är konfigurerad och fungerar. Alla uppdateringar sker med en knapptryckning. Leverans av ändringar i produktmiljön sker automatiskt. Och, viktigare, uppdateringar stoppar inte systemet.

Vår implementering av Continuous Deployment på kundens plattform

Framtidsplaner: automatisk databasmigrering

Vi funderade på att uppgradera databasen och möjligheten att återställa dessa ändringar. När allt kommer omkring körs två olika versioner av applikationen samtidigt: den gamla körs och den nya är uppe. Och vi kommer att stänga av den gamla först när vi är säkra på att den nya versionen fungerar. Databasmigreringen bör tillåta dig att arbeta med båda versionerna av programmet.

Därför kan vi inte bara ändra kolumnnamnet eller andra data. Men vi kan skapa en ny kolumn, kopiera data från den gamla kolumnen in i den och skriva triggers som, vid uppdatering av data, samtidigt kommer att kopiera och uppdatera den i en annan kolumn. Och efter den framgångsrika implementeringen av den nya versionen av applikationen, efter supportperioden efter lanseringen, kommer vi att kunna ta bort den gamla kolumnen och triggern som har blivit onödig.

Om den nya versionen av applikationen inte fungerar korrekt kan vi återgå till den tidigare versionen, inklusive den tidigare versionen av databasen. Kort sagt, våra ändringar gör att du kan arbeta samtidigt med flera versioner av applikationen.

Vi planerar att automatisera databasmigrering via K8S-jobb och integrera det i CD-processen. Och vi kommer definitivt att dela denna upplevelse på Habré.

Källa: will.com

Lägg en kommentar