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:
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-):
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):
Pobočke vložíme nový záväzok.
Na zostavení sa spustia linters a/alebo testy.
Konfigurácie žiadosti o stiahnutie Kubernetes sa generujú za chodu (napríklad jej číslo sa vloží do hotovej šablóny).
Pomocou aplikácie kubectl sa konfigurácie pridajú do klastra (nasadia).
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.
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 минутам.
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:
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
$ 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:
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:
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é.
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.