Het verwijderen van een verouderde feature branch in een Kubernetes-cluster

Het verwijderen van een verouderde feature branch in een Kubernetes-cluster

Hey there! Functietak (ook bekend als deployment preview, review app) - dit is wanneer niet alleen de master branch wordt geïmplementeerd, maar ook elk pull-verzoek naar een unieke URL. In een productieomgeving kun je controleren of de code werkt; de feature kan aan andere programmeurs of productspecialisten worden getoond. Terwijl u in een pull-request werkt, wordt elke nieuwe commit die momenteel wordt geïmplementeerd voor de oude code verwijderd, en wordt de nieuwe implementatie voor de nieuwe code uitgerold. Er kunnen vragen rijzen wanneer u een pull-verzoek in de master branch heeft samengevoegd. U hebt de feature branch niet meer nodig, maar de Kubernetes-bronnen bevinden zich nog steeds in het cluster.

Meer over functietakken

Eén benadering voor het maken van functievertakkingen in Kubernetes is het gebruik van naamruimten. In het kort ziet de productieconfiguratie er als volgt uit:

kind: Namespace
apiVersion: v1
metadata:
  name: habr-back-end
...

kind: Deployment
apiVersion: apps/v1
metadata:
  namespace: habr-back-end
spec:
  replicas: 3
...

Voor een feature branch wordt een naamruimte gemaakt met zijn ID (bijvoorbeeld het pull-aanvraagnummer) en een soort prefix/postfix (bijvoorbeeld -pr-):

kind: Namespace
apiVersion: v1
metadata:
  name: habr-back-end-pr-17
...

kind: Deployment
apiVersion: apps/v1
metadata:
  namespace: habr-back-end-pr-17
spec:
  replicas: 1
...

Over het algemeen schreef ik Kubernetes-operator (een applicatie die toegang heeft tot clusterbronnen), link naar het project op Github. Het verwijdert naamruimten die tot oude feature branches behoren. Als u in Kubernetes een naamruimte verwijdert, worden andere bronnen in die naamruimte ook automatisch verwijderd.

$ kubectl get pods --all-namespaces | grep -e "-pr-"
NAMESPACE            ... AGE
habr-back-end-pr-264 ... 4d8h
habr-back-end-pr-265 ... 5d7h

U kunt lezen hoe u functievertakkingen in een cluster implementeert hier и hier.

Motivatie

Laten we eens kijken naar een typische levenscyclus van pull-aanvragen met continue integratie (continuous integration):

  1. We pushen een nieuwe commit naar de branch.
  2. Op de build worden linters en/of tests uitgevoerd.
  3. Kubernetes pull-aanvraagconfiguraties worden direct gegenereerd (het nummer wordt bijvoorbeeld ingevoegd in de voltooide sjabloon).
  4. Met behulp van kubectl apply worden configuraties aan het cluster toegevoegd (implementeren).
  5. Pull-aanvraag wordt samengevoegd in de masterbranch.

Terwijl u in een pull-request werkt, wordt elke nieuwe commit-implementatie voor de oude code verwijderd, en wordt de nieuwe implementatie voor de nieuwe code uitgerold. Maar wanneer een pull-verzoek wordt samengevoegd in de master branch, zal alleen de master branch worden gebouwd. Als gevolg hiervan blijkt dat we de pull-aanvraag al zijn vergeten en dat de Kubernetes-bronnen zich nog steeds in het cluster bevinden.

Hoe te gebruiken

Installeer het project met de onderstaande opdracht:

$ kubectl apply -f https://raw.githubusercontent.com/dmytrostriletskyi/stale-feature-branch-operator/master/configs/production.yml

Maak een bestand met de volgende inhoud en installeer via kubectl apply -f:

apiVersion: feature-branch.dmytrostriletskyi.com/v1
kind: StaleFeatureBranch
metadata:
  name: stale-feature-branch
spec:
  namespaceSubstring: -pr-
  afterDaysWithoutDeploy: 3

Parameter naamruimteSubstring nodig om naamruimten te filteren op pull-aanvragen van andere naamruimten. Als het cluster bijvoorbeeld de volgende naamruimten heeft: habr-back-end, habr-front-end, habr-back-end-pr-17, habr-back-end-pr-33, dan zijn er kandidaten voor verwijdering habr-back-end-pr-17, habr-back-end-pr-33.

Parameter afterDaysWithoutDeploy nodig om oude naamruimten te verwijderen. Als er bijvoorbeeld een naamruimte wordt gemaakt 3 дня 1 час terug, en de parameter geeft dit aan 3 дня, wordt deze naamruimte verwijderd. Het werkt ook in de tegenovergestelde richting als de naamruimte wordt gemaakt 2 дня 23 часа terug, en de parameter geeft dit aan 3 дня, wordt deze naamruimte niet verwijderd.

Er is nog een parameter, deze is verantwoordelijk voor hoe vaak alle naamruimten moeten worden gescand en dagen zonder implementatie moeten worden gecontroleerd - checkElkeMinuten. Standaard is dit gelijk 30 минутам.

Hoe werkt dit

In de praktijk heb je nodig:

  1. havenarbeider voor het werken in een geïsoleerde omgeving.
  2. Minikubus zal lokaal een Kubernetes-cluster opzetten.
  3. kubectl — opdrachtregelinterface voor clusterbeheer.

We bouwen lokaal een Kubernetes-cluster op:

$ minikube start --vm-driver=docker
minikube v1.11.0 on Darwin 10.15.5
Using the docker driver based on existing profile.
Starting control plane node minikube in cluster minikube.

Specificeer kubectl gebruik standaard een lokaal cluster:

$ kubectl config use-context minikube
Switched to context "minikube".

Download configuraties voor de productieomgeving:

$ curl https://raw.githubusercontent.com/dmytrostriletskyi/stale-feature-branch-operator/master/configs/production.yml > stale-feature-branch-production-configs.yml

Omdat productieconfiguraties zijn geconfigureerd om oude naamruimten te controleren, en ons nieuw opgerichte cluster deze niet heeft, zullen we de omgevingsvariabele vervangen IS_DEBUG op true. Met deze waarde wordt de parameter afterDaysWithoutDeploy Er wordt geen rekening gehouden met en naamruimten worden dagenlang zonder implementatie niet gecontroleerd, alleen op het voorkomen van de substring (-pr-).

Als je aan bent Linux:

$ sed -i 's|false|true|g' stale-feature-branch-production-configs.yml

Als je aan bent macOS:

$ sed -i "" 's|false|true|g' stale-feature-branch-production-configs.yml

Het project installeren:

$ kubectl apply -f stale-feature-branch-production-configs.yml

Controleren of een bron in het cluster is verschenen StaleFeatureBranch:

$ kubectl api-resources | grep stalefeaturebranches
NAME                 ... APIGROUP                             ... KIND
stalefeaturebranches ... feature-branch.dmytrostriletskyi.com ... StaleFeatureBranch

We controleren of er een operator in het cluster is verschenen:

$ kubectl get pods --namespace stale-feature-branch-operator
NAME                                           ... STATUS  ... AGE
stale-feature-branch-operator-6bfbfd4df8-m7sch ... Running ... 38s

Als u naar de logboeken kijkt, is deze klaar om bronnen te verwerken StaleFeatureBranch:

$ kubectl logs stale-feature-branch-operator-6bfbfd4df8-m7sch -n stale-feature-branch-operator
... "msg":"Operator Version: 0.0.1"}
...
... "msg":"Starting EventSource", ... , "source":"kind source: /, Kind="}
... "msg":"Starting Controller", ...}
... "msg":"Starting workers", ..., "worker count":1}

Wij installeren kant-en-klaar fixtures (kant-en-klare configuraties voor het modelleren van clusterbronnen) voor een bron StaleFeatureBranch:

$ kubectl apply -f https://raw.githubusercontent.com/dmytrostriletskyi/stale-feature-branch-operator/master/fixtures/stale-feature-branch.yml

De configuraties geven aan dat er moet worden gezocht naar naamruimten met een subtekenreeks -pr- eens een 1 минуту.:

apiVersion: feature-branch.dmytrostriletskyi.com/v1
kind: StaleFeatureBranch
metadata:
  name: stale-feature-branch
spec:
  namespaceSubstring: -pr-
  afterDaysWithoutDeploy: 1 
  checkEveryMinutes: 1

De operator heeft gereageerd en is klaar om naamruimten te controleren:

$ kubectl logs stale-feature-branch-operator-6bfbfd4df8-m7sch -n stale-feature-branch-operator
... "msg":"Stale feature branch is being processing.","namespaceSubstring":"-pr-","afterDaysWithoutDeploy":1,"checkEveryMinutes":1,"isDebug":"true"}

Ingesteld fixtures, met twee naamruimten (project-pr-1, project-pr-2) en zij deployments, services, ingress, enzovoort:

$ kubectl apply -f https://raw.githubusercontent.com/dmytrostriletskyi/stale-feature-branch-operator/master/fixtures/first-feature-branch.yml -f https://raw.githubusercontent.com/dmytrostriletskyi/stale-feature-branch-operator/master/fixtures/second-feature-branch.yml
...
namespace/project-pr-1 created
deployment.apps/project-pr-1 created
service/project-pr-1 created
horizontalpodautoscaler.autoscaling/project-pr-1 created
secret/project-pr-1 created
configmap/project-pr-1 created
ingress.extensions/project-pr-1 created
namespace/project-pr-2 created
deployment.apps/project-pr-2 created
service/project-pr-2 created
horizontalpodautoscaler.autoscaling/project-pr-2 created
secret/project-pr-2 created
configmap/project-pr-2 created
ingress.extensions/project-pr-2 created

We controleren of alle bovenstaande bronnen met succes zijn aangemaakt:

$ kubectl get namespace,pods,deployment,service,horizontalpodautoscaler,configmap,ingress -n project-pr-1 && kubectl get namespace,pods,deployment,service,horizontalpodautoscaler,configmap,ingress -n project-pr-2
...
NAME                              ... READY ... STATUS  ... AGE
pod/project-pr-1-848d5fdff6-rpmzw ... 1/1   ... Running ... 67s

NAME                         ... READY ... AVAILABLE ... AGE
deployment.apps/project-pr-1 ... 1/1   ... 1         ... 67s
...

Sinds we inbegrepen zijn debug, naamruimten project-pr-1 и project-pr-2Daarom moeten alle andere bronnen onmiddellijk worden verwijderd zonder rekening te houden met de parameter afterDaysWithoutDeploy. Dit is te zien in de operatorlogboeken:

$ kubectl logs stale-feature-branch-operator-6bfbfd4df8-m7sch -n stale-feature-branch-operator
... "msg":"Namespace should be deleted due to debug mode is enabled.","namespaceName":"project-pr-1"}
... "msg":"Namespace is being processing.","namespaceName":"project-pr-1","namespaceCreationTimestamp":"2020-06-16 18:43:58 +0300 EEST"}
... "msg":"Namespace has been deleted.","namespaceName":"project-pr-1"}
... "msg":"Namespace should be deleted due to debug mode is enabled.","namespaceName":"project-pr-2"}
... "msg":"Namespace is being processing.","namespaceName":"project-pr-2","namespaceCreationTimestamp":"2020-06-16 18:43:58 +0300 EEST"}
... "msg":"Namespace has been deleted.","namespaceName":"project-pr-2"}

Als u de beschikbaarheid van bronnen controleert, staan ​​deze in de status Terminating (verwijderingsproces) of al verwijderd (opdrachtuitvoer is leeg).

$ kubectl get namespace,pods,deployment,service,horizontalpodautoscaler,configmap,ingress -n project-pr-1 && kubectl get namespace,pods,deployment,service,horizontalpodautoscaler,configmap,ingress -n project-pr-2
...

U kunt het creatieproces herhalen fixtures meerdere keren en zorg ervoor dat ze binnen een minuut worden verwijderd.

alternatieven

Wat kan er gedaan worden in plaats van een operator die in een cluster werkt? Er zijn verschillende benaderingen, ze zijn allemaal onvolmaakt (en hun tekortkomingen zijn subjectief), en iedereen beslist voor zichzelf wat het beste is voor een bepaald project:

  1. Verwijder de feature branch tijdens de continue integratieopbouw van de master branch.

    • Om dit te doen, moet je weten welke pull-request betrekking heeft op de commit die wordt gebouwd. Omdat de feature branch-naamruimte de pull request-identifier bevat (het nummer of de naam van de branch), zal de identifier altijd in de commit moeten worden gespecificeerd.
    • Master branch builds mislukken. U hebt bijvoorbeeld de volgende fasen: het project downloaden, tests uitvoeren, het project bouwen, een release maken, meldingen verzenden, de feature branch van de laatste pull-aanvraag wissen. Als de build mislukt bij het verzenden van een melding, moet u alle bronnen in het cluster handmatig verwijderen.
    • Zonder de juiste context is het verwijderen van feature branches in de masterbuild niet vanzelfsprekend.

  2. Webhooks gebruiken (voorbeeld).

    • Dit is misschien niet jouw aanpak. Bijvoorbeeld, binnen Jenkinsondersteunt slechts één type pijplijn de mogelijkheid om de configuraties ervan in de broncode op te slaan. Wanneer u webhooks gebruikt, moet u uw eigen script schrijven om deze te verwerken. Dit script zal in de Jenkins-interface geplaatst moeten worden, wat lastig te onderhouden is.

  3. Schrijven cronjob en voeg een Kubernetes-cluster toe.

    • Tijd besteden aan schrijven en ondersteuning.
    • De operator werkt al in een vergelijkbare stijl, is gedocumenteerd en ondersteund.

Bedankt voor uw aandacht voor het artikel. Link naar het project op Github.

Bron: www.habr.com

Voeg een reactie