Uklanjanje zastarjele grane funkcije u Kubernetes klasteru

Uklanjanje zastarjele grane funkcije u Kubernetes klasteru

Zdravo! Značajka grana (aka deploy preview, review app) - ovo je kada se ne postavlja samo glavna grana, već i svaki zahtjev za povlačenjem na jedinstveni URL. Možete provjeriti funkcionira li kod u proizvodnom okruženju; funkcija se može pokazati drugim programerima ili stručnjacima za proizvode. Dok radite u zahtjevu za povlačenjem, svaka nova trenutna implementacija urezivanja za stari kod se briše, a nova implementacija za novi kod se uvodi. Mogu se pojaviti pitanja kada spojite zahtjev za povlačenje u glavnu granu. Više vam nije potrebna grana funkcija, ali Kubernetes resursi su i dalje u klasteru.

Više o granama karakteristika

Jedan pristup pravljenju grana karakteristika u Kubernetesu je korištenje prostora imena. Ukratko, proizvodna konfiguracija izgleda ovako:

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

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

Za granu karakteristika kreira se prostor imena sa svojim identifikatorom (na primjer, brojem zahtjeva za povlačenjem) i nekom vrstom prefiksa/postfiksa (na primjer, -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
...

Generalno, napisao sam Kubernetes Operator (aplikacija koja ima pristup resursima klastera), link do projekta na Githubu. Uklanja prostore imena koji pripadaju starim granama karakteristika. U Kubernetesu, ako izbrišete imenski prostor, automatski se brišu i drugi resursi u tom imenskom prostoru.

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

Možete pročitati o tome kako implementirati grane karakteristika u klaster ovdje и ovdje.

Motivacija

Pogledajmo tipičan životni ciklus zahtjeva za povlačenjem sa kontinuiranom integracijom (continuous integration):

  1. Guramo novo urezivanje u granu.
  2. Na izgradnji se pokreću linteri i/ili testovi.
  3. Kubernetes konfiguracije zahtjeva za povlačenjem se generišu u hodu (na primjer, njegov broj se ubacuje u gotov šablon).
  4. Koristeći kubectl apply, konfiguracije se dodaju u klaster (deploy).
  5. Zahtjev za povlačenjem je spojen u glavnu granu.

Dok radite u zahtjevu za povlačenjem, svaka nova trenutna implementacija urezivanja za stari kod se briše, a nova implementacija za novi kod se uvodi. Ali kada se zahtjev za povlačenjem spoji u glavnu granu, izgradit će se samo glavna grana. Kao rezultat toga, ispostavilo se da smo već zaboravili na zahtjev za izvlačenje, a njegovi Kubernetes resursi su još uvijek u klasteru.

Kako koristiti

Instalirajte projekat naredbom ispod:

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

Kreirajte datoteku sa sljedećim sadržajem i instalirajte putem kubectl apply -f:

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

Parametar namespaceSubstring potrebno za filtriranje imenskih prostora za zahtjeve za povlačenjem iz drugih imenskih prostora. Na primjer, ako klaster ima sljedeće imenske prostore: habr-back-end, habr-front-end, habr-back-end-pr-17, habr-back-end-pr-33, tada će biti kandidati za brisanje habr-back-end-pr-17, habr-back-end-pr-33.

Parametar afterDaysWithoutDeploy potrebno za brisanje starih imenskih prostora. Na primjer, ako se kreira imenski prostor 3 дня 1 час nazad, a parametar pokazuje 3 дня, ovaj imenski prostor će biti obrisan. Također radi u suprotnom smjeru ako se kreira imenski prostor 2 дня 23 часа nazad, a parametar pokazuje 3 дня, ovaj imenski prostor neće biti obrisan.

Postoji još jedan parametar, on je odgovoran za koliko često skenirati sve imenske prostore i provjeravati dane bez implementacije - checkEveryMinutes. Podrazumevano je jednako 30 минутам.

Kako ovo radi

U praksi će vam trebati:

  1. doker za rad u izolovanom okruženju.
  2. Minikube će podići Kubernetes klaster lokalno.
  3. kubectl — interfejs komandne linije za upravljanje klasterom.

Lokalno podižemo Kubernetes klaster:

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

Navedite kubectl koristi lokalni klaster prema zadanim postavkama:

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

Preuzmite konfiguracije za proizvodno okruženje:

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

Budući da su proizvodne konfiguracije konfigurirane za provjeru starih imenskih prostora, a naš novopodignut klaster ih nema, zamijenit ćemo varijablu okruženja IS_DEBUG na true. Sa ovom vrijednošću parametar afterDaysWithoutDeploy se ne uzima u obzir i prostori imena se ne provjeravaju danima bez postavljanja, samo za pojavu podniza (-pr-).

Ako ste uključeni Linux:

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

Ako ste uključeni macOS:

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

Instalacija projekta:

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

Provjera da se resurs pojavio u klasteru StaleFeatureBranch:

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

Provjeravamo da li se u klasteru pojavio operator:

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

Ako pogledate njegove zapise, spreman je za obradu resursa 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}

Ugrađujemo gotove fixtures (gotove konfiguracije za modeliranje resursa klastera) za resurs StaleFeatureBranch:

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

Konfiguracije ukazuju na traženje imenskih prostora sa podnizom -pr- jednom svaki 1 минуту.:

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

Operater je odgovorio i spreman je da provjeri imenske prostore:

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

Instalirajte fixtures, koji sadrži dva imenska prostora (project-pr-1, project-pr-2) i njih deployments, services, ingress, i tako dalje:

$ 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

Provjeravamo da li su svi gore navedeni resursi uspješno kreirani:

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

Pošto smo uključili debug, imenski prostori project-pr-1 и project-pr-2, stoga će svi ostali resursi morati biti odmah obrisani bez uzimanja u obzir parametra afterDaysWithoutDeploy. Ovo se može vidjeti u logovima operatera:

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

Ako provjerite dostupnost resursa, oni će biti u statusu Terminating (proces brisanja) ili već obrisan (izlaz komande je prazan).

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

Možete ponoviti proces kreiranja fixtures nekoliko puta i provjerite jesu li uklonjeni u roku od jedne minute.

Alternative

Šta se može učiniti umjesto operatera koji radi u klasteru? Postoji nekoliko pristupa, svi su nesavršeni (a njihovi nedostaci su subjektivni) i svako za sebe odlučuje šta je najbolje za određeni projekat:

  1. Izbrišite granu funkcije tokom kontinuirane integracije glavne grane.

    • Da biste to učinili, morate znati koji zahtjev za povlačenjem se odnosi na urezivanje koje se gradi. Budući da imenski prostor grane funkcije sadrži identifikator zahtjeva za povlačenjem - njegov broj ili ime grane, identifikator će uvijek morati biti specificiran u urezivanju.
    • Gradnje glavne grane ne uspijevaju. Na primjer, imate sljedeće faze: preuzimanje projekta, pokretanje testova, izrada projekta, izdavanje, slanje obavijesti, brisanje grane funkcije posljednjeg zahtjeva za povlačenjem. Ako izgradnja ne uspije prilikom slanja obavijesti, morat ćete ručno izbrisati sve resurse u klasteru.
    • Bez odgovarajućeg konteksta, brisanje grana karakteristika u glavnoj verziji nije očigledno.

  2. Koristeći webhooks (primer).

    • Ovo možda nije vaš pristup. Na primjer, u Jenkins, samo jedan tip cjevovoda podržava mogućnost spremanja svojih konfiguracija u izvorni kod. Kada koristite webhookove, morate napisati vlastitu skriptu za njihovu obradu. Ova skripta će se morati postaviti u Jenkinsov interfejs, koji je teško održavati.

  3. Da pišem Cronjob i dodajte Kubernetes klaster.

    • Trošenje vremena na pisanje i podršku.
    • Operater već radi u sličnom stilu, dokumentiran je i podržan.

Hvala vam na pažnji prema članku. Link do projekta na Githubu.

izvor: www.habr.com

Dodajte komentar