Fjerne en utdatert funksjonsgren i en Kubernetes-klynge

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:

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

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

For en funksjonsgren opprettes et navneområde med sin identifikator (for eksempel pull request-nummeret) og en slags prefiks/postfiks (for eksempel, -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
...

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):

  1. Vi presser en ny forpliktelse til filialen.
  2. På bygget kjøres linters og/eller tester.
  3. Kubernetes pull-forespørselskonfigurasjoner genereres på flukt (for eksempel blir nummeret satt inn i den ferdige malen).
  4. Ved å bruke kubectl application blir konfigurasjoner lagt til klyngen (distribuer).
  5. 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.

Hvordan bruke

Installer prosjektet med kommandoen nedenfor:

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

Lag en fil med følgende innhold 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 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 минутам.

Hvordan fungerer det

I praksis trenger du:

  1. Docker for å jobbe i et isolert miljø.
  2. Minikube vil reise en Kubernetes-klynge lokalt.
  3. 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".

Last ned konfigurasjoner for produksjonsmiljøet:

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

Siden produksjonskonfigurasjoner er konfigurert til å sjekke gamle navnerom, og vår nylig oppbygde klynge ikke har dem, vil vi erstatte miljøvariabelen IS_DEBUGtrue. 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

Installere prosjektet:

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

Kontrollerer at en ressurs har dukket opp i klyngen StaleFeatureBranch:

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

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:

$ 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 monterer ferdig fixtures (ferdige konfigurasjoner for modellering av klyngeressurser) for en ressurs StaleFeatureBranch:

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

Konfigurasjonene indikerer å søke etter navnerom med en understreng -pr- engang i 1 минуту.:

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

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:

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

  2. Bruke webhooks (eksempel).

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

  3. skrive Cronjob og legg til en Kubernetes-klynge.

    • Bruk tid på skriving og støtte.
    • Operatøren jobber allerede i lignende stil, er dokumentert og støttet.

Takk for oppmerksomheten til artikkelen. Link til prosjektet på Github.

Kilde: www.habr.com

Legg til en kommentar