Odstránenie zastaranej vetvy funkcií v klastri Kubernetes

Odstránenie zastaranej vetvy funkcií v klastri Kubernetes

Ahoj! Funkcia vetva (známy ako ukážka nasadenia, recenzia aplikácie) – vtedy je nasadená nielen hlavná vetva, ale aj každá požiadavka na stiahnutie na jedinečnú adresu URL. Môžete skontrolovať, či kód funguje v produkčnom prostredí, funkciu možno ukázať iným programátorom alebo produktovým špecialistom. Kým pracujete na požiadavke na stiahnutie, každé nové potvrdenie, aktuálne nasadenie pre starý kód sa vymaže a nové nasadenie pre nový kód sa zavedie. Pri zlúčení požiadavky na stiahnutie do hlavnej vetvy môžu vzniknúť otázky. Už nepotrebujete vetvu funkcií, ale zdroje Kubernetes sú stále v klastri.

Viac o pobočkách funkcií

Jedným z prístupov k vytváraniu vetiev funkcií v Kubernetes je použitie menných priestorov. Stručne povedané, konfigurácia výroby vyzerá takto:

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

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

Pre vetvu funkcie sa vytvorí priestor názvov s jej identifikátorom (napríklad číslom požiadavky na stiahnutie) a nejakým druhom predpony/postfixu (napr. -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
...

Vo všeobecnosti som napísal Operátor Kubernetes (aplikácia, ktorá má prístup k prostriedkom klastra), odkaz na projekt na Github. Odstraňuje menné priestory, ktoré patria k starým vetvám funkcií. Ak v Kubernetes odstránite priestor názvov, automaticky sa odstránia aj ďalšie zdroje v tomto priestore názvov.

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

Môžete si prečítať o tom, ako implementovať vetvy funkcií do klastra tu и tu.

Motivácia

Pozrime sa na typický životný cyklus žiadosti o stiahnutie s nepretržitou integráciou (continuous integration):

  1. Pobočke vložíme nový záväzok.
  2. Na zostavení sa spustia linters a/alebo testy.
  3. Konfigurácie žiadosti o stiahnutie Kubernetes sa generujú za chodu (napríklad jej číslo sa vloží do hotovej šablóny).
  4. Pomocou aplikácie kubectl sa konfigurácie pridajú do klastra (nasadia).
  5. Pull request sa zlúči do hlavnej vetvy.

Keď pracujete s požiadavkou na stiahnutie, každé nové potvrdenie aktuálneho nasadenia pre starý kód sa vymaže a zavedie sa nové nasadenie pre nový kód. Keď sa však požiadavka na stiahnutie zlúči do hlavnej vetvy, vytvorí sa iba hlavná vetva. V dôsledku toho sa ukazuje, že sme už zabudli na požiadavku na stiahnutie a jej prostriedky Kubernetes sú stále v klastri.

Ako používať

Nainštalujte projekt pomocou príkazu nižšie:

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

Vytvorte súbor s nasledujúcim obsahom a nainštalujte ho cez kubectl apply -f:

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

Parameter namespacePodreťazec potrebné na filtrovanie menných priestorov pre požiadavky na stiahnutie z iných menných priestorov. Napríklad, ak má klaster nasledujúce menné priestory: habr-back-end, habr-front-end, habr-back-end-pr-17, habr-back-end-pr-33, potom budú kandidátmi na vymazanie habr-back-end-pr-17, habr-back-end-pr-33.

Parameter afterDaysWithoutDeploy potrebné na odstránenie starých menných priestorov. Napríklad, ak je vytvorený menný priestor 3 дня 1 час späť a parameter označuje 3 дня, tento menný priestor bude odstránený. Funguje to aj v opačnom smere, ak je vytvorený menný priestor 2 дня 23 часа späť a parameter označuje 3 дня, tento menný priestor nebude odstránený.

Existuje ešte jeden parameter, ktorý je zodpovedný za to, ako často kontrolovať všetky menné priestory a kontrolovať dni bez nasadenia - checkEveryMinutes. V predvolenom nastavení je rovnaký 30 минутам.

Ako to funguje

V praxi budete potrebovať:

  1. prístavný robotník pre prácu v izolovanom prostredí.
  2. Minikube lokálne vytvorí klaster Kubernetes.
  3. kubectl — rozhranie príkazového riadka pre správu klastrov.

Lokálne vytvárame klaster Kubernetes:

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

Naznačujeme kubectl predvolene použiť lokálny klaster:

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

Stiahnite si konfigurácie pre produkčné prostredie:

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

Keďže produkčné konfigurácie sú nakonfigurované tak, aby kontrolovali staré menné priestory a náš novovytvorený klaster ich nemá, nahradíme premennú prostredia IS_DEBUG na true. S touto hodnotou parameter afterDaysWithoutDeploy sa neberie do úvahy a menné priestory sa nekontrolujú počas dní bez nasadenia, iba na výskyt podreťazca (-pr-).

Ak ste na Linux:

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

Ak ste na macOS:

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

Inštalácia projektu:

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

Kontrola, či sa zdroj objavil v klastri StaleFeatureBranch:

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

Skontrolujeme, či sa v klastri objavil operátor:

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

Ak sa pozriete na jeho protokoly, je pripravený na spracovanie zdrojov 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}

Inštalujeme hotové fixtures (hotové konfigurácie na modelovanie prostriedkov klastra) pre prostriedok StaleFeatureBranch:

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

Konfigurácie naznačujú, že sa majú hľadať priestory názvov s podreťazcom -pr- raz za 1 минуту.:

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

Operátor odpovedal a je pripravený skontrolovať menné priestory:

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

Sada fixtures, ktorý obsahuje dva menné priestory (project-pr-1, project-pr-2) a oni deployments, services, ingress, a tak ďalej:

$ 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

Skontrolujeme, či boli všetky vyššie uvedené zdroje úspešne vytvorené:

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

Keďže sme zahrnuli debug, menné priestory project-pr-1 и project-pr-2, preto budú musieť byť všetky ostatné zdroje okamžite vymazané bez zohľadnenia parametra afterDaysWithoutDeploy. Toto je možné vidieť v protokoloch operátora:

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

Ak skontrolujete dostupnosť zdrojov, budú v stave Terminating (proces vymazania) alebo už vymazané (výstup príkazu je prázdny).

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

Proces vytvárania môžete zopakovať fixtures niekoľkokrát a uistite sa, že sú odstránené do minúty.

alternatívy

Čo možno urobiť namiesto operátora, ktorý pracuje v klastri? Existuje niekoľko prístupov, všetky sú nedokonalé (a ich nedostatky sú subjektívne) a každý sa sám rozhodne, čo je pre konkrétny projekt najlepšie:

  1. Odstrániť vetvu funkcie počas nepretržitého integračného zostavovania hlavnej vetvy.

    • Aby ste to dosiahli, musíte vedieť, ktorá požiadavka na stiahnutie sa týka vytváraného odovzdania. Keďže menný priestor vetvy funkcie obsahuje identifikátor žiadosti o stiahnutie – jeho číslo alebo názov vetvy, identifikátor bude musieť byť vždy uvedený v potvrdení.
    • Budovanie hlavnej vetvy zlyháva. Máte napríklad nasledujúce fázy: stiahnuť projekt, spustiť testy, zostaviť projekt, vydať vydanie, odoslať upozornenia, vymazať vetvu funkcie poslednej požiadavky na stiahnutie. Ak zostavenie zlyhá pri odosielaní upozornenia, budete musieť manuálne odstrániť všetky prostriedky v klastri.
    • Bez správneho kontextu nie je vymazanie vetiev funkcií v hlavnej zostave zrejmé.

  2. Používanie webhookov (príklad).

    • Toto nemusí byť váš prístup. Napríklad v Jenkins, iba jeden typ potrubia podporuje možnosť uložiť svoje konfigurácie do zdrojového kódu. Keď používate webhooky, musíte si na ich spracovanie napísať vlastný skript. Tento skript bude musieť byť umiestnený v rozhraní Jenkins, čo je náročné na údržbu.

  3. zapísať Cronjob a pridajte klaster Kubernetes.

    • Tráviť čas písaním a podporou.
    • Operátor už funguje podobným štýlom, je zdokumentovaný a podporovaný.

Ďakujem za pozornosť, ktorú ste venovali článku. Odkaz na projekt na Github.

Zdroj: hab.com

Pridať komentár