Odstranění zastaralé větve funkcí v clusteru Kubernetes

Odstranění zastaralé větve funkcí v clusteru Kubernetes

Ahoj! Hlavní větev (aka deploy preview, review app) – to je, když je nasazena nejen hlavní větev, ale také každý požadavek na stažení na jedinečnou adresu URL. Můžete zkontrolovat, zda kód funguje v produkčním prostředí, funkci lze ukázat ostatním programátorům nebo produktovým specialistům. Zatímco pracujete s žádostí o stažení, každé nové potvrzení aktuálního nasazení pro starý kód je odstraněno a je zavedeno nové nasazení pro nový kód. Otázky mohou nastat, když sloučíte požadavek na stažení do hlavní větve. Větev funkcí již nepotřebujete, ale prostředky Kubernetes jsou stále v clusteru.

Více o větvích funkcí

Jedním z přístupů k vytváření větví funkcí v Kubernetes je použití jmenných prostorů. Stručně řečeno, produkční konfigurace vypadá takto:

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

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

Pro větev funkcí je vytvořen jmenný prostor s jeho identifikátorem (například číslem požadavku na stažení) a nějakým druhem předpony/postfixu (např. -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
...

Obecně jsem napsal Operátor Kubernetes (aplikace, která má přístup ke zdrojům clusteru), odkaz na projekt na Github. Odstraňuje jmenné prostory, které patří do starých větví funkcí. Pokud v Kubernetes odstraníte obor názvů, automaticky se odstraní i další prostředky v tomto oboru názvů.

$ 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 přečíst o tom, jak implementovat větve funkcí do clusteru zde и zde.

Motivace

Podívejme se na typický životní cyklus požadavku na stažení s nepřetržitou integrací (continuous integration):

  1. Vložíme nový commit do větve.
  2. Na sestavení se provádějí lintry a/nebo testy.
  3. Konfigurace požadavku na vytažení Kubernetes se generují za běhu (jeho číslo se například vloží do hotové šablony).
  4. Pomocí kubectl apply se konfigurace přidají do clusteru (nasadí).
  5. Pull request je sloučen do hlavní větve.

Zatímco pracujete s žádostí o stažení, každé nové potvrzení aktuálního nasazení pro starý kód je odstraněno a je zavedeno nové nasazení pro nový kód. Ale když je požadavek na stažení začleněn do hlavní větve, bude sestaven pouze hlavní větev. V důsledku toho se ukazuje, že jsme již zapomněli na požadavek na stažení a jeho prostředky Kubernetes jsou stále v clusteru.

Jak používat

Nainstalujte projekt pomocí příkazu níže:

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

Vytvořte soubor s následujícím obsahem a nainstalujte přes kubectl apply -f:

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

Parametr jmenný prostorPodřetězec potřebné k filtrování jmenných prostorů pro žádosti o stažení z jiných jmenných prostorů. Pokud má cluster například následující jmenné prostory: habr-back-end, habr-front-end, habr-back-end-pr-17, habr-back-end-pr-33, pak budou kandidáty na smazání habr-back-end-pr-17, habr-back-end-pr-33.

Parametr afterDaysWithoutDeploy potřebné k odstranění starých jmenných prostorů. Například pokud je vytvořen jmenný prostor 3 дня 1 час zpět a parametr ukazuje 3 дня, bude tento jmenný prostor smazán. Funguje to i v opačném směru, pokud je vytvořen jmenný prostor 2 дня 23 часа zpět a parametr ukazuje 3 дня, tento jmenný prostor nebude smazán.

Existuje ještě jeden parametr, který je zodpovědný za to, jak často skenovat všechny jmenné prostory a kontrolovat dny bez nasazení - checkEveryMinutes. Ve výchozím nastavení se rovná 30 минутам.

Jak to funguje

V praxi budete potřebovat:

  1. přístavní dělník pro práci v izolovaném prostředí.
  2. Minikube lokálně zvedne cluster Kubernetes.
  3. kubectl — rozhraní příkazového řádku pro správu clusteru.

Lokálně vytváříme cluster 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.

Uveďte kubectl ve výchozím nastavení použít místní cluster:

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

Stáhněte si konfigurace pro produkční prostředí:

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

Protože produkční konfigurace jsou nakonfigurovány tak, aby kontrolovaly staré jmenné prostory a náš nově vytvořený cluster je nemá, nahradíme proměnnou prostředí IS_DEBUG na true. S touto hodnotou parametr afterDaysWithoutDeploy se nebere v úvahu a jmenné prostory se nekontrolují po dobu dnů bez nasazení, pouze na výskyt podřetězce (-pr-).

Pokud jste na Linux:

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

Pokud jste na macOS:

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

Instalace projektu:

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

Kontrola, zda se prostředek objevil v clusteru StaleFeatureBranch:

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

Zkontrolujeme, zda se v clusteru objevil operátor:

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

Pokud se podíváte na jeho protokoly, je připraven zpracovávat zdroje 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}

Montujeme již hotové fixtures (hotové konfigurace pro modelování klastrových prostředků) pro prostředek StaleFeatureBranch:

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

Konfigurace indikují hledání jmenných prostorů pomocí podřetězce -pr- jednou v 1 минуту.:

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

Operátor odpověděl a je připraven zkontrolovat jmenné prostory:

$ 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, obsahující dva jmenné prostory (project-pr-1, project-pr-2) a oni deployments, services, ingress, a tak dále:

$ 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

Zkontrolujeme, že všechny výše uvedené zdroje byly úspěšně vytvořeny:

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

Protože jsme zahrnuli debug, jmenné prostory project-pr-1 и project-pr-2, proto budou muset být všechny ostatní zdroje okamžitě smazány bez zohlednění parametru afterDaysWithoutDeploy. To lze vidět v protokolech 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"}

Pokud zkontrolujete dostupnost zdrojů, budou ve stavu Terminating (proces mazání) nebo již smazané (výstup příkazu je prázdný).

$ 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áření můžete opakovat fixtures několikrát a ujistěte se, že jsou odstraněny do minuty.

Alternativy

Co lze udělat místo operátora, který pracuje v clusteru? Existuje několik přístupů, všechny jsou nedokonalé (a jejich nedostatky jsou subjektivní) a každý se sám rozhodne, co je pro konkrétní projekt nejlepší:

  1. Odstranit větev prvků během průběžného integračního sestavení hlavní větve.

    • Chcete-li to provést, musíte vědět, který požadavek na stažení se vztahuje k sestavovanému potvrzení. Vzhledem k tomu, že jmenný prostor větve funkce obsahuje identifikátor požadavku na stažení – jeho číslo nebo název větve, bude muset být identifikátor vždy uveden v potvrzení.
    • Sestavení hlavní větve selhává. Máte například následující fáze: stáhnout projekt, spustit testy, sestavit projekt, vytvořit vydání, odeslat upozornění, vymazat větev funkce posledního požadavku na stažení. Pokud sestavení selže při odesílání upozornění, budete muset ručně odstranit všechny prostředky v clusteru.
    • Bez správného kontextu není odstranění větví prvků v hlavním sestavení zřejmé.

  2. Použití webhooků (příklad).

    • To nemusí být váš přístup. Například v Jenkins, pouze jeden typ potrubí podporuje možnost uložit své konfigurace do zdrojového kódu. Když používáte webhooky, musíte si k jejich zpracování napsat vlastní skript. Tento skript bude muset být umístěn v rozhraní Jenkins, což je obtížné na údržbu.

  3. Napište Cron práce a přidejte cluster Kubernetes.

    • Trávit čas psaním a podporou.
    • Operátor již funguje podobným stylem, je zdokumentován a podporován.

Děkuji za pozornost věnovanou článku. Odkaz na projekt na Github.

Zdroj: www.habr.com

Přidat komentář