Onze implementatie van Continuous Deployment op het platform van de klant

Wij van True Engineering hebben een proces opgezet voor het continu leveren van updates aan de servers van klanten en willen deze ervaring delen.

Om te beginnen hebben we voor de klant een online systeem ontwikkeld en in ons eigen Kubernetes cluster uitgerold. Nu is onze high-load oplossing verhuisd naar het platform van de klant, waarvoor we een volledig automatisch Continuous Deployment-proces hebben opgezet. Hierdoor hebben we de time-to-market versneld: het doorvoeren van wijzigingen in de productomgeving.

In dit artikel zullen we het hebben over alle fasen van het Continuous Deployment (CD)-proces of de levering van updates op het platform van de klant:

  1. Hoe begint dit proces?
  2. synchronisatie met de Git-repository van de klant,
  3. assemblage van backend en frontend,
  4. automatische applicatie-implementatie in een testomgeving,
  5. automatische implementatie naar Prod.

We zullen onderweg de installatiedetails delen.

Onze implementatie van Continuous Deployment op het platform van de klant

1. Start CD

Continue implementatie begint wanneer de ontwikkelaar wijzigingen doorvoert naar de releasetak van onze Git-repository.

Onze applicatie draait op een microservice-architectuur en alle componenten zijn opgeslagen in één repository. Hierdoor worden alle microservices verzameld en geïnstalleerd, zelfs als een ervan is gewijzigd.

Om verschillende redenen hebben we het werk via één repository georganiseerd:

  • Gemak van ontwikkeling - de applicatie wordt actief ontwikkeld, zodat u met alle code in één keer kunt werken.
  • Eén enkele CI/CD-pijplijn die garandeert dat de applicatie als één systeem alle tests doorstaat en wordt opgeleverd aan de productieomgeving van de klant.
  • We elimineren verwarring in versies: we hoeven geen kaart met microserviceversies op te slaan en de configuratie ervan voor elke microservice in Helm-scripts te beschrijven.

2. Synchronisatie met de Git-repository van de broncode van de klant

Aangebrachte wijzigingen worden automatisch gesynchroniseerd met de Git-repository van de klant. Daar wordt de applicatie-assembly geconfigureerd, die wordt gestart na het updaten van de branch, en de implementatie naar de voortzetting. Beide processen vinden hun oorsprong in hun omgeving vanuit een Git-repository.

We kunnen niet rechtstreeks met de repository van de klant werken omdat we onze eigen omgevingen nodig hebben voor ontwikkeling en testen. We gebruiken onze Git-repository voor deze doeleinden - deze is gesynchroniseerd met hun Git-repository. Zodra een ontwikkelaar wijzigingen in de juiste tak van onze repository plaatst, pusht GitLab deze wijzigingen onmiddellijk naar de klant.

Onze implementatie van Continuous Deployment op het platform van de klant

Hierna moet je de montage doen. Het bestaat uit verschillende fasen: backend- en frontend-assemblage, testen en oplevering aan productie.

3. Het samenstellen van de backend en frontend

Het bouwen van de backend en frontend zijn twee parallelle taken die worden uitgevoerd in het GitLab Runner-systeem. De oorspronkelijke assemblageconfiguratie bevindt zich in dezelfde repository.

Tutorial voor het schrijven van een YAML-script voor het bouwen in GitLab.

GitLab Runner haalt de code uit de vereiste repository, stelt deze samen met de Java-applicatie build-opdracht en stuurt deze naar het Docker-register. Hier assembleren we de backend en frontend, verkrijgen we Docker-images, die we in een repository aan de kant van de klant plaatsen. Om Docker-images te beheren gebruiken we Gradle-plug-in.

We synchroniseren de versies van onze afbeeldingen met de releaseversie die in Docker wordt gepubliceerd. Voor een soepele werking hebben wij diverse aanpassingen gedaan:

1. Containers worden niet opnieuw opgebouwd tussen de testomgeving en de productieomgeving. We hebben parametrisaties gemaakt zodat dezelfde container met alle instellingen, omgevingsvariabelen en services zowel in de testomgeving als in productie kon werken zonder opnieuw te hoeven opbouwen.

2. Om een ​​applicatie via Helm te updaten, moet u de versie ervan opgeven. Wij bouwen de backend, frontend en updaten de applicatie – dit zijn drie verschillende taken, dus het is belangrijk om overal dezelfde versie van de applicatie te gebruiken. Voor deze taak gebruiken we gegevens uit de Git-geschiedenis, omdat onze K8S-clusterconfiguratie en applicaties zich in dezelfde Git-repository bevinden.

We halen de applicatieversie uit de resultaten van de opdrachtuitvoering
git describe --tags --abbrev=7.

4. Automatische implementatie van alle wijzigingen in de testomgeving (UAT)

De volgende stap in dit buildscript is het automatisch bijwerken van het K8S-cluster. Dit gebeurt op voorwaarde dat de volledige applicatie is gebouwd en alle artefacten zijn gepubliceerd naar de Docker Registry. Hierna start de update van de testomgeving.

De clusterupdate wordt gestart met behulp van Helm-update. Als daardoor iets niet volgens plan is verlopen, zal Helm automatisch en onafhankelijk alle wijzigingen terugdraaien. Zijn werk hoeft niet gecontroleerd te worden.

Wij leveren de K8S clusterconfiguratie mee met de montage. Daarom is de volgende stap het updaten: configMaps, implementaties, services, geheimen en alle andere K8S-configuraties die we hebben gewijzigd.

Helm voert vervolgens een RollOut-update uit van de applicatie zelf in de testomgeving. Voordat de applicatie in productie wordt genomen. Dit wordt gedaan zodat gebruikers handmatig de bedrijfsfuncties kunnen testen die we in de testomgeving hebben geplaatst.

5. Automatische implementatie van alle wijzigingen in Prod

Om een ​​update voor de productieomgeving te implementeren, hoef je slechts op één knop in GitLab te klikken - en de containers worden onmiddellijk in de productieomgeving afgeleverd.

Dezelfde applicatie kan in verschillende omgevingen (test- en productieomgeving) werken zonder deze opnieuw te moeten opbouwen. We gebruiken dezelfde artefacten zonder iets in de applicatie te veranderen, en we stellen de parameters extern in.

Flexibele parametrering van applicatie-instellingen is afhankelijk van de omgeving waarin de applicatie zal worden uitgevoerd. We hebben alle omgevingsinstellingen extern verplaatst: alles is geparametriseerd via de K8S-configuratie en Helm-parameters. Wanneer Helm een ​​assemblage in de testomgeving implementeert, worden de testinstellingen hierop toegepast en worden de productinstellingen toegepast op de productieomgeving.

Het moeilijkste was om alle gebruikte services en variabelen die afhankelijk zijn van de omgeving te parametriseren en deze te vertalen naar omgevingsvariabelen en beschrijvingsconfiguraties van omgevingsparameters voor Helm.

Applicatie-instellingen gebruiken omgevingsvariabelen. Hun waarden worden ingesteld in containers met behulp van K8S-configmap, die is getemperd met behulp van Go-sjablonen. Het instellen van een omgevingsvariabele op de domeinnaam kan bijvoorbeeld als volgt worden gedaan:

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

.Waarden.global.env – deze variabele slaat de naam van de omgeving op (prod, stage, UAT).
.Waarden.app.properties.app_extern_domein – in deze variabele stellen we het gewenste domein in het .Values.yaml bestand in

Bij het updaten van een applicatie maakt Helm een ​​configmap.yaml-bestand op basis van sjablonen en vult de waarde APP_EXTERNAL_DOMAIN met de gewenste waarde, afhankelijk van de omgeving waarin de applicatie-update start. Deze variabele is al ingesteld in de container. Het is toegankelijk vanuit de applicatie, dus elke applicatieomgeving zal een andere waarde voor deze variabele hebben.

Relatief recent verscheen K8S-ondersteuning in Spring Cloud, inclusief het werken met configMaps: Lente Cloud Kubernetes. Hoewel het project zich actief ontwikkelt en radicaal verandert, kunnen we het niet in de productie gebruiken. Maar we monitoren actief de toestand ervan en gebruiken deze in DEV-configuraties. Zodra het zich stabiliseert, zullen we overstappen van het gebruik van omgevingsvariabelen naar het gebruik ervan.

In totaal

Continuous Deployment is dus geconfigureerd en werkt. Alle updates vinden plaats met één druk op de knop. Het doorgeven van wijzigingen aan de productomgeving gebeurt automatisch. En belangrijker nog: updates stoppen het systeem niet.

Onze implementatie van Continuous Deployment op het platform van de klant

Toekomstplannen: automatische databasemigratie

We hebben nagedacht over het upgraden van de database en de mogelijkheid om deze wijzigingen ongedaan te maken. Er draaien immers twee verschillende versies van de applicatie tegelijkertijd: de oude draait en de nieuwe is actief. En we zullen de oude alleen uitschakelen als we zeker weten dat de nieuwe versie werkt. De databasemigratie moet u in staat stellen met beide versies van de applicatie te werken.

Daarom kunnen we niet zomaar de kolomnaam of andere gegevens wijzigen. Maar we kunnen een nieuwe kolom maken, gegevens uit de oude kolom ernaar kopiëren en triggers schrijven die, wanneer de gegevens worden bijgewerkt, deze tegelijkertijd in een andere kolom kopiëren en bijwerken. En na de succesvolle implementatie van de nieuwe versie van de applicatie, na de ondersteuningsperiode na de lancering, kunnen we de oude kolom en de trigger die overbodig is geworden verwijderen.

Als de nieuwe versie van de applicatie niet correct werkt, kunnen we teruggaan naar de vorige versie, inclusief de vorige versie van de database. Kortom, dankzij onze wijzigingen kunt u gelijktijdig met meerdere versies van de applicatie werken.

We zijn van plan de databasemigratie via K8S-job te automatiseren en deze in het CD-proces te integreren. En deze ervaring gaan we zeker delen op Habré.

Bron: www.habr.com

Voeg een reactie