Fjernelse af en forældet funktionsgren i en Kubernetes-klynge
Hi! Feature gren (alias deploy preview, review app) - dette er, når ikke kun mastergrenen er implementeret, men også hver pull-anmodning til en unik URL. Du kan kontrollere, om koden fungerer i et produktionsmiljø; funktionen kan vises til andre programmører eller produktspecialister. Mens du arbejder i en pull-anmodning, slettes hver ny commit-aktuel implementering for den gamle kode, og den nye implementering for den nye kode rulles ud. Der kan opstå spørgsmål, når du flettede en pull-anmodning ind i mastergrenen. Du har ikke længere brug for funktionsgrenen, men Kubernetes-ressourcerne er stadig i klyngen.
Mere om funktionsgrene
En tilgang til at lave funktionsgrene i Kubernetes er at bruge navnerum. Kort sagt ser produktionskonfigurationen sådan ud:
Generelt skrev jeg Kubernetes operatør (en applikation, der har adgang til klyngressourcer), link til projektet på Github. Det fjerner navneområder, der hører 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 du implementerer funktionsgrene i en klynge her и her.
Motivation
Lad os se på en typisk pull request-livscyklus med kontinuerlig integration (continuous integration):
Vi presser en ny forpligtelse til filialen.
På bygningen køres linters og/eller tests.
Kubernetes pull-anmodningskonfigurationer genereres med det samme (f.eks. indsættes nummeret i den færdige skabelon).
Ved at bruge kubectl apply tilføjes konfigurationer til klyngen (deploy).
Pull-anmodning flettes ind i mastergrenen.
Mens du arbejder i en pull-anmodning, slettes hver ny commit-aktuel implementering for den gamle kode, og den nye implementering for den nye kode rulles ud. Men når en pull-anmodning flettes ind i mastergrenen, vil kun mastergrenen blive bygget. Som et resultat viser det sig, at vi allerede har glemt pull-anmodningen, og dens Kubernetes-ressourcer er stadig i klyngen.
Parameter navnerumsunderstreng nødvendig for at filtrere navnerum for pull-anmodninger fra andre navnerum. For eksempel, hvis klyngen har følgende navnerum: habr-back-end, habr-front-end, habr-back-end-pr-17, habr-back-end-pr-33, så vil kandidater til sletning være habr-back-end-pr-17, habr-back-end-pr-33.
Parameter afterDaysWithoutDeploy nødvendig for at slette gamle navneområder. For eksempel hvis der oprettes navneområde 3 дня 1 час tilbage, og parameteren angiver 3 дня, vil dette navneområde blive slettet. Det virker også i den modsatte retning, hvis navneområdet oprettes 2 дня 23 часа tilbage, og parameteren angiver 3 дня, vil dette navneområde ikke blive slettet.
Der er en parameter mere, den er ansvarlig for, hvor ofte man skal scanne alle navneområder og tjekke efter dage uden implementering - checkEveryMinutes. Som standard er det ens 30 минутам.
kubectl — kommandolinjegrænseflade til klyngestyring.
Vi rejser 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".
Da produktionskonfigurationer er konfigureret til at kontrollere gamle navnerum, og vores nyligt rejste klynge ikke har dem, erstatter vi miljøvariablen IS_DEBUG på true. Med denne værdi er parameteren afterDaysWithoutDeploy tages ikke i betragtning, og navnerum kontrolleres ikke i dage uden implementering, kun for forekomsten af understrengen (-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
Vi tjekker, at en operatør er dukket op i klyngen:
$ kubectl get pods --namespace stale-feature-branch-operator
NAME ... STATUS ... AGE
stale-feature-branch-operator-6bfbfd4df8-m7sch ... Running ... 38s
Hvis du ser på dens logfiler, er den klar til at behandle ressourcer StaleFeatureBranch:
Operatøren har svaret og er klar til at kontrollere navneområder:
$ 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 dem 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
Vi kontrollerer, at alle ressourcerne ovenfor 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
...
Siden vi inkluderede debug, navnerum project-pr-1 и project-pr-2, derfor skal alle andre ressourcer slettes med det samme uden at tage hensyn til 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 (sletningsproces) eller allerede slettet (kommandooutput 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 man gøre i stedet for en operatør, der arbejder i en klynge? Der er flere tilgange, alle er ufuldkomne (og deres mangler er subjektive), og alle bestemmer selv, hvad der er bedst for et bestemt projekt:
Slet funktionsgren under kontinuerlig integrationsopbygning af mastergren.
For at gøre dette skal du vide, hvilken pull-anmodning, der vedrører den commit, der er ved at blive bygget. Da feature branch namespace indeholder pull request identifikatoren - dets nummer eller navnet på branchen, skal identifikatoren altid angives i commit.
Opbygning af mastergrene mislykkes. For eksempel har du følgende stadier: download projektet, kør test, byg projektet, lav en udgivelse, send notifikationer, ryd featuregrenen af den sidste pull-anmodning. Hvis bygningen mislykkes, når du sender en meddelelse, bliver du nødt til at slette alle ressourcer i klyngen manuelt.
Uden ordentlig kontekst er det ikke indlysende at slette funktionsgrene i masterbuilden.
Dette er muligvis ikke din tilgang. 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 for at behandle dem. Dette script skal placeres i Jenkins-grænsefladen, hvilket er svært at vedligeholde.