Fjernelse af en forældet funktionsgren i en Kubernetes-klynge

Fjernelse af en forældet funktionsgren i en Kubernetes-klynge

Hi! Funktionsgren (også kendt som deploy preview, review app) — det er her, at ikke kun masterbranchen implementeres, men også hver pull request til en unik URL. Du kan kontrollere, om koden fungerer i et produktionsmiljø, og funktionen kan vises til andre programmører eller produktchefer. Mens du arbejder på en pull-anmodning, fjerner hver ny commit den nuværende deployment for den gamle kode og udruller en ny deployment for den nye kode. Der kan opstå spørgsmål, når du fletter en pull-anmodning ind i master-branchen. Du behøver ikke længere feature-grenen, men Kubernetes-ressourcerne er stadig i klyngen.

Mere om funktionsgrene

En metode til at oprette feature branches i Kubernetes er at bruge namespaces. Kort sagt ser produktionskonfigurationen således ud:

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

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

For en feature-gren oprettes et navnerum med dets identifikator (f.eks. pull request-nummeret) og et præfiks/postfix (f.eks. -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
...

I hvert fald skrev jeg Kubernetes operatør (en applikation, der har adgang til klyngeressourcer), link til projektet på Github. Den fjerner navnerum, der refererer til gamle funktionsgrene. Hvis du sletter et navneområde i Kubernetes, slettes andre ressourcer i det navneområde også automatisk.

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

Du kan læse om, hvordan man implementerer funktionsgrene i en klynge her и her.

Motivation

Lad os se på en typisk pull request-livcyklus med kontinuerlig integration (continuous integration):

  1. Send en ny commit til branchen.
  2. På build'en køres linters og/eller tests.
  3. Kubernetes pull request-konfigurationer genereres on-the-fly (for eksempel indsættes nummeret i en færdiglavet skabelon).
  4. Ved hjælp af kubectl apply implementeres konfigurationer i klyngen.
  5. Pull-anmodningen flettes ind i master-grenen.

Mens du arbejder på en pull-anmodning, fjerner hver ny commit den nuværende deployment for den gamle kode og udruller en ny deployment for den nye kode. Men når en pull-anmodning flettes ind i master-branchen, er det kun master-branchen, der bliver bygget. Som følge heraf viser det sig, at vi allerede har glemt pull-anmodningen, og dens Kubernetes-ressourcer stadig er i klyngen.

Sådan bruges

Installer projektet med kommandoen nedenfor:

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

Opret en fil med følgende indhold og installer via kubectl apply -f:

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

Parameter navnerumsunderstreng nødvendigt for at filtrere navnerum for pull-anmodninger fra andre navnerum. For eksempel, hvis en klynge har følgende navnerum: habr-back-end, habr-front-end, habr-back-end-pr-17, habr-back-end-pr-33, så vil kandidaterne til fjernelse være habr-back-end-pr-17, habr-back-end-pr-33.

Parameter efterDageUdenImplering nødvendigt at slette gamle navnerum. For eksempel, hvis navnerummet oprettes 3 дня 1 час tilbage, og parameteren angiver 3 дня, vil dette navnerum blive slettet. Fungerer også omvendt, hvis navneområdet oprettes 2 дня 23 часа tilbage, og parameteren angiver 3 дня, dette navnerum vil ikke blive slettet.

Der er endnu en parameter, den er ansvarlig for, hvor ofte alle navnerum skal scannes og kontrolleres for dage uden implementering — tjekHvertMinut. Som standard er den lig med 30 минутам.

Hvordan fungerer denne her

I praksis skal du bruge:

  1. Docker til arbejde i et isoleret miljø.
  2. Minikube vil oprette en Kubernetes-klynge lokalt.
  3. kubectl — kommandolinjegrænseflade til klyngestyring.

Vi opretter en Kubernetes-klynge lokalt:

$ 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.

Angiv kubectl brug lokal klynge som standard:

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

Download konfigurationer til produktionsmiljøet:

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

Da produktionskonfigurationer er indstillet til at kontrollere gamle navnerum, og vores nyligt oprettede klynge ikke har dem, erstatter vi miljøvariablen IS_DEBUGtrue. Med denne værdi er parameteren afterDaysWithoutDeploy tages ikke i betragtning, og navnerum kontrolleres ikke for dage uden implementering, kun for forekomsten af ​​en delstreng (-pr-).

Hvis du er på Linux:

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

Hvis du er på macOS:

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

Installer projektet:

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

Vi kontrollerer, at ressourcen er optrådt i klyngen StaleFeatureBranch:

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

Vi kontrollerer, at operatoren er optrådt i klyngen:

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

Hvis du kigger på dens logfiler, er den klar til at behandle ressourcer. 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}

Vi installerer færdiglavede fixtures (færdige konfigurationer til modellering af klyngeressourcer) for ressourcen StaleFeatureBranch:

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

Konfigurationerne angiver, at der skal søges efter navnerum med en delstreng -pr- engang en 1 минуту.:

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

Operatoren har svaret og er klar til at kontrollere navnerum:

$ 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"}

Indstil fixtures, der indeholder to navnerum (project-pr-1, project-pr-2) og deres deployments, services, ingress, og så videre:

$ 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

Lad os kontrollere, at alle ovenstående ressourcer er blevet oprettet:

$ 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
...

Da vi har inkluderet debug, navnerum project-pr-1 и project-pr-2derfor skal alle andre ressourcer slettes øjeblikkeligt uden at tage højde for parameteren afterDaysWithoutDeploy. Dette kan ses i operatørloggene:

$ 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"}

Hvis du tjekker tilgængeligheden af ​​ressourcer, vil de være i status Terminating (sletteproces) eller allerede slettet (kommandooutputtet er tomt).

$ 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
...

Du kan gentage oprettelsesprocessen fixtures flere gange og sørg for, at de fjernes inden for et minut.

alternativer

Hvad kan der gøres i stedet for operatøren, der arbejder i klyngen? Der er flere tilgange, og de er ikke alle ideelle (og deres mangler er subjektive), og alle bestemmer selv, hvad der er bedst egnet til et specifikt projekt:

  1. Slet funktionsgrenen under kontinuerlig integrationsopbygning af mastergrenen.

    • For at gøre dette skal du vide, hvilken pull request der relaterer sig til den commit, der bygges. Da feature-branch-navnerummet indeholder pull request-id'et - dets nummer eller branch-navn, skal identifikatoren altid angives i commit'en.
    • Master branch builds mislykkes. For eksempel har du følgende faser: download projektet, kør tests, byg projektet, lav en udgivelse, send notifikationer, ryd funktionsgrenen fra den sidste pull-anmodning. Hvis buildet mislykkes, når der sendes en notifikation, skal du slette alle ressourcer i klyngen manuelt.
    • Uden korrekt kontekst er det ikke indlysende at fjerne en funktionsgren i et masterbuild.

  2. Brug af webhooks (eksempel).

    • Dette er måske ikke din fremgangsmåde. For eksempel i Jenkins, kun én type pipeline understøtter muligheden for at gemme dens konfigurationer i kildekoden. Når du bruger webhooks, skal du skrive dit eget script til at håndtere dem. Dette script skulle hostes i Jenkins-grænsefladen, hvilket er vanskeligt at vedligeholde.

  3. skrive Cronjob og tilføj en Kubernetes-klynge.

    • Tid brugt på skrivning og support.
    • Operatøren arbejder allerede på en lignende måde, er dokumenteret og understøttet.

Tak for din opmærksomhed på artiklen. Link til projektet på Github.

Kilde: www.habr.com

Køb pålidelig hosting til websteder med DDoS-beskyttelse, VPS VDS-servere 🔥 Køb pålidelig webhosting med DDoS-beskyttelse, VPS VDS-servere | ProHoster