Vores implementering af Continuous Deployment på kundens platform

Vi hos True Engineering har opsat en proces for løbende levering af opdateringer til kundeservere og ønsker at dele denne oplevelse.

Til at begynde med udviklede vi et online system til kunden og implementerede det i vores egen Kubernetes-klynge. Nu er vores højbelastningsløsning flyttet til kundens platform, hvortil vi har opsat en fuldautomatisk kontinuerlig implementeringsproces. Takket være dette fremskyndede vi time-to-market - leveringen af ​​ændringer til produktmiljøet.

I denne artikel vil vi tale om alle stadier af processen med kontinuerlig implementering (CD) eller levering af opdateringer til kundens platform:

  1. Hvordan starter denne proces?
  2. synkronisering med kundens Git-lager,
  3. samling af backend og frontend,
  4. automatisk applikationsimplementering i et testmiljø,
  5. automatisk udrulning til Prod.

Vi deler opsætningsdetaljerne undervejs.

Vores implementering af Continuous Deployment på kundens platform

1. Start CD

Kontinuerlig Deployment begynder med, at udvikleren skubber ændringer til udgivelsesgrenen af ​​vores Git-lager.

Vores applikation kører på en mikroservicearkitektur, og alle dens komponenter er gemt i ét lager. Takket være dette samles og installeres alle mikrotjenester, selvom en af ​​dem er ændret.

Vi organiserede arbejdet gennem ét lager af flere årsager:

  • Nem udvikling - applikationen udvikler sig aktivt, så du kan arbejde med al koden på én gang.
  • En enkelt CI/CD-pipeline, der garanterer, at applikationen som et enkelt system består alle test og leveres til kundens produktionsmiljø.
  • Vi eliminerer forvirring i versioner - vi behøver ikke at gemme et kort over mikroserviceversioner og beskrive dens konfiguration for hver mikroservice i Helm-scripts.

2. Synkronisering med Git-lageret af kundens kildekode

Ændringer, der foretages, synkroniseres automatisk med kundens Git-lager. Der konfigureres applikationssamlingen, som startes efter opdatering af filialen, og udrulning til fortsættelsen. Begge processer stammer fra deres miljø fra et Git-lager.

Vi kan ikke arbejde med kundens repository direkte, fordi vi har brug for vores egne miljøer til udvikling og test. Vi bruger vores Git repository til disse formål - det er synkroniseret med deres Git repository. Så snart en udvikler sender ændringer til den relevante gren af ​​vores repository, sender GitLab straks disse ændringer til kunden.

Vores implementering af Continuous Deployment på kundens platform

Herefter skal du udføre monteringen. Det består af flere faser: backend og frontend montage, test og levering til produktion.

3. Samling af backend og frontend

Opbygning af backend og frontend er to parallelle opgaver, der udføres i GitLab Runner-systemet. Dens originale samlingskonfiguration er placeret i det samme lager.

Tutorial til at skrive et YAML-script til bygning i GitLab.

GitLab Runner tager koden fra det påkrævede lager, samler den med Java-applikations build-kommandoen og sender den til Docker-registret. Her samler vi backend og frontend, får Docker-billeder, som vi lægger i et lager på kundens side. Til at administrere Docker-billeder bruger vi Gradle plugin.

Vi synkroniserer versionerne af vores billeder med udgivelsesversionen, der vil blive offentliggjort i Docker. For problemfri drift har vi lavet flere justeringer:

1. Containere bygges ikke om mellem testmiljøet og produktionsmiljøet. Vi lavede parametriseringer, så den samme container kunne arbejde med alle indstillinger, miljøvariabler og tjenester både i testmiljøet og i produktionen uden ombygning.

2. For at opdatere en applikation via Helm skal du angive dens version. Vi bygger backend, frontend og opdaterer applikationen – det er tre forskellige opgaver, så det er vigtigt at bruge den samme version af applikationen overalt. Til denne opgave bruger vi data fra Git-historien, da vores K8S-klyngekonfiguration og applikationer er i det samme Git-lager.

Vi får applikationsversionen fra kommandoudførelsesresultaterne
git describe --tags --abbrev=7.

4. Automatisk implementering af alle ændringer i testmiljøet (UAT)

Det næste trin i dette build-script er automatisk at opdatere K8S-klyngen. Dette sker, forudsat at hele applikationen er blevet bygget og alle artefakter er blevet offentliggjort til Docker Registry. Herefter starter testmiljøopdateringen.

Klyngeopdateringen er begyndt at bruge Hjelm opdatering. Hvis noget som følge heraf ikke gik efter planen, vil Helm automatisk og uafhængigt rulle alle sine ændringer tilbage. Hans arbejde behøver ikke at blive kontrolleret.

Vi leverer K8S-klyngekonfigurationen sammen med samlingen. Derfor er det næste trin at opdatere det: configMaps, implementeringer, tjenester, hemmeligheder og alle andre K8S-konfigurationer, som vi har ændret.

Helm kører derefter en RollOut-opdatering af selve applikationen i testmiljøet. Før applikationen implementeres til produktion. Dette gøres, så brugerne manuelt kan teste de forretningsfunktioner, som vi sætter ind i testmiljøet.

5. Automatisk implementering af alle ændringer til Prod

For at implementere en opdatering til produktionsmiljøet skal du blot klikke på én knap i GitLab – og containerne bliver straks leveret til produktionsmiljøet.

Den samme applikation kan fungere i forskellige miljøer – test og produktion – uden ombygning. Vi bruger de samme artefakter uden at ændre noget i applikationen, og vi indstiller parametrene eksternt.

Fleksibel parametrering af applikationsindstillinger afhænger af det miljø, hvor applikationen skal køres. Vi har flyttet alle miljøindstillinger eksternt: alt parametreres gennem K8S-konfigurationen og Helm-parametrene. Når Helm implementerer en assembly til testmiljøet, anvendes testindstillingerne på den, og produktindstillingerne anvendes på produktionsmiljøet.

Det sværeste var at parametrere alle de brugte tjenester og variabler, der er afhængige af miljøet, og oversætte dem til miljøvariabler og beskrivelses-konfigurationer af miljøparametre for Helm.

Applikationsindstillinger bruger miljøvariabler. Deres værdier er sat i containere ved hjælp af K8S configmap, som skabes ved hjælp af Go-skabeloner. For eksempel kan indstilling af en miljøvariabel til domænenavnet gøres sådan:

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

.Values.global.env – denne variabel gemmer navnet på miljøet (prod, stage, UAT).
.Values.app.properties.app_external_domain – i denne variabel indstiller vi det ønskede domæne i filen .Values.yaml

Når en applikation opdateres, opretter Helm en configmap.yaml-fil fra skabeloner og udfylder APP_EXTERNAL_DOMAIN-værdien med den ønskede værdi afhængigt af det miljø, hvor applikationsopdateringen starter. Denne variabel er allerede indstillet i containeren. Det kan tilgås fra applikationen, så hvert applikationsmiljø vil have en forskellig værdi for denne variabel.

Relativt for nylig dukkede K8S-understøttelse op i Spring Cloud, herunder arbejde med configMaps: Spring Cloud Kubernetes. Mens projektet aktivt udvikler sig og ændrer sig radikalt, kan vi ikke bruge det i produktionen. Men vi overvåger aktivt dens tilstand og bruger den i DEV-konfigurationer. Så snart det stabiliserer sig, skifter vi fra at bruge miljøvariabler til det.

I alt

Så Continuous Deployment er konfigureret og fungerer. Alle opdateringer sker med ét tastetryk. Levering af ændringer til produktmiljøet sker automatisk. Og, hvad der er vigtigt, stopper opdateringer ikke systemet.

Vores implementering af Continuous Deployment på kundens platform

Fremtidsplaner: automatisk databasemigrering

Vi overvejede at opgradere databasen og muligheden for at rulle disse ændringer tilbage. Når alt kommer til alt, kører to forskellige versioner af applikationen på samme tid: den gamle kører, og den nye er oppe. Og vi slår først den gamle fra, når vi er sikre på, at den nye version virker. Databasemigreringen skulle give dig mulighed for at arbejde med begge versioner af applikationen.

Derfor kan vi ikke blot ændre kolonnenavnet eller andre data. Men vi kan oprette en ny kolonne, kopiere data fra den gamle kolonne ind i den og skrive triggere, der ved opdatering af dataene samtidig vil kopiere og opdatere dem i en anden kolonne. Og efter den vellykkede implementering af den nye version af applikationen, efter supportperioden efter lanceringen, vil vi være i stand til at slette den gamle kolonne og triggeren, der er blevet unødvendig.

Hvis den nye version af applikationen ikke fungerer korrekt, kan vi rulle tilbage til den tidligere version, inklusive den tidligere version af databasen. Kort sagt vil vores ændringer give dig mulighed for at arbejde samtidigt med flere versioner af applikationen.

Vi planlægger at automatisere databasemigrering via K8S-job, og integrere det i cd-processen. Og vi vil helt sikkert dele denne oplevelse på Habré.

Kilde: www.habr.com

Tilføj en kommentar