Fjerne en utdatert funksjonsgren i en Kubernetes-klynge
Hei! Funksjonsgren (aka distribusjon forhåndsvisning, gjennomgang app) - dette er når ikke bare hovedgrenen er distribuert, men også hver pull-forespørsel til en unik URL. Du kan sjekke om koden fungerer i et produksjonsmiljø; funksjonen kan vises til andre programmerere eller produktspesialister. Mens du jobber med en pull-forespørsel, slettes hver nye commit gjeldende distribusjon for den gamle koden, og den nye distribusjonen for den nye koden rulles ut. Spørsmål kan oppstå når du slo sammen en pull-forespørsel inn i mastergrenen. Du trenger ikke lenger funksjonsgrenen, men Kubernetes-ressursene er fortsatt i klyngen.
Mer om funksjonsgrener
En tilnærming til å lage funksjonsgrener i Kubernetes er å bruke navnerom. Kort fortalt ser produksjonskonfigurasjonen slik ut:
For en funksjonsgren opprettes et navneområde med sin identifikator (for eksempel pull request-nummeret) og en slags prefiks/postfiks (for eksempel, -pr-):
Generelt skrev jeg Kubernetes-operatør (en applikasjon som har tilgang til klyngeressurser), lenke til prosjektet på Github. Den fjerner navneområder som tilhører gamle funksjonsgrener. I Kubernetes, hvis du sletter et navneområde, slettes også andre ressurser i det navneområdet 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 lese om hvordan du implementerer funksjonsgrener i en klynge her и her.
Motivasjon
La oss se på en typisk pull request-livssyklus med kontinuerlig integrasjon (continuous integration):
Vi presser en ny forpliktelse til filialen.
På bygget kjøres linters og/eller tester.
Kubernetes pull-forespørselskonfigurasjoner genereres på flukt (for eksempel blir nummeret satt inn i den ferdige malen).
Ved å bruke kubectl application blir konfigurasjoner lagt til klyngen (distribuer).
Pull-forespørsel slås sammen til hovedgrenen.
Mens du jobber med en pull-forespørsel, slettes hver nye commit, gjeldende distribusjon for den gamle koden, og den nye distribusjonen for den nye koden rulles ut. Men når en pull-forespørsel slås sammen til mastergrenen, vil bare mastergrenen bli bygget. Som et resultat viser det seg at vi allerede har glemt pull-forespørselen, og Kubernetes-ressursene er fortsatt i klyngen.
Parameter navneområde understreng nødvendig for å filtrere navnerom for pull-forespørsler fra andre navnerom. For eksempel, hvis klyngen har følgende navnerom: habr-back-end, habr-front-end, habr-back-end-pr-17, habr-back-end-pr-33, da vil kandidater for sletting være habr-back-end-pr-17, habr-back-end-pr-33.
Parameter afterDaysWithoutDeploy nødvendig for å slette gamle navneområder. For eksempel hvis navneområde opprettes 3 дня 1 час tilbake, og parameteren indikerer 3 дня, vil dette navneområdet bli slettet. Det fungerer også i motsatt retning hvis navneområdet opprettes 2 дня 23 часа tilbake, og parameteren indikerer 3 дня, dette navneområdet vil ikke bli slettet.
Det er en parameter til, den er ansvarlig for hvor ofte du skal skanne alle navneområder og se etter dager uten distribusjon - sjekkEveryMinutes. Som standard er den lik 30 минутам.
kubectl — kommandolinjegrensesnitt for klyngeadministrasjon.
Vi oppretter 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.
Indikerer kubectl bruk lokal klynge som standard:
$ kubectl config use-context minikube
Switched to context "minikube".
Siden produksjonskonfigurasjoner er konfigurert til å sjekke gamle navnerom, og vår nylig oppbygde klynge ikke har dem, vil vi erstatte miljøvariabelen IS_DEBUG på true. Med denne verdien parameteren afterDaysWithoutDeploy tas ikke med i betraktningen og navneområder sjekkes ikke i dager uten distribusjon, kun for forekomsten av 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 sjekker at en operatør har dukket opp 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å loggene, er den klar til å behandle ressurser StaleFeatureBranch:
Operatøren har svart og er klar til å sjekke 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"}
Satt fixtures, som inneholder to navneområder (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 sjekker at alle ressursene ovenfor er opprettet:
$ 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 inkluderte debug, navneområder project-pr-1 и project-pr-2, derfor må alle andre ressurser slettes umiddelbart uten å ta hensyn til parameteren afterDaysWithoutDeploy. Dette kan sees 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 sjekker tilgjengeligheten av ressurser, vil de være i statusen Terminating (sletteprosess) eller allerede slettet (kommandoutgangen er tom).
$ 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 gjenta opprettelsesprosessen fixtures flere ganger og sørg for at de fjernes innen et minutt.
alternativer
Hva kan gjøres i stedet for en operatør som jobber i en klynge? Det er flere tilnærminger, alle er ufullkomne (og deres mangler er subjektive), og alle bestemmer selv hva som er best for et bestemt prosjekt:
Slett funksjonsgren under kontinuerlig integrasjonsbygging av mastergren.
For å gjøre dette må du vite hvilken pull-forespørsel som gjelder forpliktelsen som bygges. Siden funksjonsgrennavneområdet inneholder pull request-identifikatoren - dens nummer, eller navnet på grenen, vil identifikatoren alltid måtte spesifiseres i commit.
Bygging av mastergrener mislykkes. For eksempel har du følgende stadier: last ned prosjektet, kjør tester, bygg prosjektet, lag en utgivelse, send varsler, fjern funksjonsgrenen til den siste pull-forespørselen. Hvis byggingen mislykkes når du sender et varsel, må du slette alle ressursene i klyngen manuelt.
Uten riktig kontekst er det ikke åpenbart å slette funksjonsgrener i hovedbygget.
Dette er kanskje ikke din tilnærming. For eksempel i Jenkins, bare én type rørledning støtter muligheten til å lagre konfigurasjonene i kildekoden. Når du bruker webhooks, må du skrive ditt eget skript for å behandle dem. Dette skriptet må plasseres i Jenkins-grensesnittet, som er vanskelig å vedlikeholde.