
Ahoj! Funkční větev (neboli nasazení náhledu, aplikační kontrola) — to je situace, kdy se nasazuje nejen master větev, ale také každý pull request na unikátní URL. Můžete ověřit, zda kód funguje v produkčním prostředí, a funkci lze ukázat ostatním programátorům nebo produktovým specialistům. Dokud pracujete na pull requestu, každý nový commit aktuální nasazení pro starý kód se odstraňuje a nové nasazení pro nový kód se provádí. Otázky mohou nastat, když jste sloučili pull request do master větve. Funkční větev vám už není potřeba, ale prostředky Kubernetes stále zůstávají v clusteru.
Další o funkčních větvích
Jedním z přístupů, jak vytvořit funkční větve v Kubernetes, je použít namespace. Pokud stručně, 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 funkční větev se vytváří namespace s jejím identifikátorem (například číslo pull requestu) a nějakým prefixem/sufixem (například, -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 Kubernetes Operator (aplikace, která má přístup k prostředkům clusteru), . Odstraňuje namespace, které se vztahují ke starým funkčním větvím. V Kubernetes, pokud odstraňujete namespace, ostatní prostředky v tomto namespace jsou také automaticky odstraněny.
$ kubectl get pods --all-namespaces | grep -e "-pr-"
NAMESPACE ... AGE
habr-back-end-pr-264 ... 4d8h
habr-back-end-pr-265 ... 5d7hO tom, jak zavést funkční větve do clusteru, si můžete přečíst a .
Motivace
Podívejme se na typický životní cyklus pull requestu s kontinuální integrací (kontinuální integrace):
- Odesíláme nový commit na větev.
- Při buildu se spouštějí lintry a/nebo testy.
- Na žádost se dynamicky vytvářejí konfigurace Kubernetes pull requestu (například se do připravené šablony vloží jeho číslo).
- Pomocí kubectl apply se konfigurace dostanou do clusteru (nasazení).
- Pull request se sloučí do master větve.
Dokud pracujete na pull requestu, každé nové nasazení pro starý kód se odstraňuje a nové nasazení pro nový kód se provádí. Ale když se pull request sloučí do master větve, bude se buildit pouze master větev. Nakonec to vypadá tak, že jsme na pull request už zapomněli, ale jeho prostředky Kubernetes stále zůstávají v clusteru.
Jak používat
Nainstalujte projekt pomocí následujícího příkazu:
$ kubectl apply -f https://raw.githubusercontent.com/dmytrostriletskyi/stale-feature-branch-operator/master/configs/production.ymlVytvořte soubor s následujícím obsahem a nainstalujte jej prostřednictvím kubectl apply -f:
apiVersion: feature-branch.dmytrostriletskyi.com/v1
kind: StaleFeatureBranch
metadata:
name: stale-feature-branch
spec:
namespaceSubstring: -pr-
afterDaysWithoutDeploy: 3Parameter namespaceSubstring potřebný k filtrování namespaces pro pull requesty z jiných namespaces. Například, pokud v klastru existují následující namespaces: habr-back-end, habr-front-end, habr-back-end-pr-17, habr-back-end-pr-33, pak kandidáty na odstranění budou habr-back-end-pr-17, habr-back-end-pr-33.
Parameter afterDaysWithoutDeploy potřebný k odstraňování starých namespaces. Například, pokud byl namespace vytvořen 3 dny 1 hodina zpět, a v parametru je uvedeno 3 dny, tento namespace bude odstraněn. Pracuje i naopak, pokud byl namespace vytvořen 2 dny 23 hodin zpět, a v parametru je uvedeno 3 dny, tento namespace nebude odstraněn.
Existuje ještě jeden parametr, který určuje, jak často prohledávat všechny namespaces a kontrolovat dny bez deploye — checkEveryMinutes. Ve výchozím nastavení je rovný 30 minutám.
Jak to funguje
V praxi bude potřeba:
- pro práci v izolovaném prostředí.
- spustí Kubernetes klastr lokálně.
- — rozhraní příkazového řádku pro správu klastru.
Spouštíme Kubernetes klastr lokálně:
$ minikube start --vm-driver=docker
minikube v1.11.0 na Darwin 10.15.5
Používá ovladač docker na základě existujícího profilu.
Spouští řídicí uzel minikube v klastru minikube.Určte kubectl používat lokální klastr jako výchozí:
$ kubectl config use-context minikube
Přepnuto na kontext "minikube".Stahujeme konfigurace pro production prostředí:
$ curl https://raw.githubusercontent.com/dmytrostriletskyi/stale-feature-branch-operator/master/configs/production.yml > stale-feature-branch-production-configs.ymlJelikož jsou produkční konfigurace nastaveny na kontrolu starých namespaces a v našem nově spuštěném klastru nejsou, nahradíme proměnnou prostředí IS_DEBUG na true. Při takové hodnotě se parametr afterDaysWithoutDeploy nehodnotí a namespaces se nekontrolují na dny bez deploye, pouze na přítomnost podřetězce (-pr-).
Pokud jste na Linux:
$ sed -i 's|false|true|g' stale-feature-branch-production-configs.ymlPokud jste na macOS:
$ sed -i "" 's|false|true|g' stale-feature-branch-production-configs.ymlInstalujeme projekt:
$ kubectl apply -f stale-feature-branch-production-configs.ymlKontrolujeme, že v klastru se objevil zdroj StaleFeatureBranch:
$ kubectl api-resources | grep stalefeaturebranches
NAME ... APIGROUP ... KIND
stalefeaturebranches ... feature-branch.dmytrostriletskyi.com ... StaleFeatureBranchKontrolujeme, že v klastru se objevil operátor:
$ kubectl get pods --namespace stale-feature-branch-operator
NAME ... STATUS ... AGE
stale-feature-branch-operator-6bfbfd4df8-m7sch ... Probíhá ... 38sPokud se podíváte do jeho logů, je připraven zpracovávat zdroje StaleFeatureBranch:
$ kubectl logs stale-feature-branch-operator-6bfbfd4df8-m7sch -n stale-feature-branch-operator
... "msg":"Verze operátoru: 0.0.1"}
...
... "msg":"Spouštím EventSource", ... , "source":"kind source: /, Kind="}
... "msg":"Spouštím Řídicí jednotku", ...}
... "msg":"Spouštím pracovníky", ..., "počet pracovníků":1}Instalujeme hotové fixtures (hotové konfigurace pro modelování zdrojů clustera) pro zdroj StaleFeatureBranch:
$ kubectl apply -f https://raw.githubusercontent.com/dmytrostriletskyi/stale-feature-branch-operator/master/fixtures/stale-feature-branch.ymlV konfiguracích je uvedeno hledat namespace s podřetězcem -pr- jednou za 1 minutu.:
apiVersion: feature-branch.dmytrostriletskyi.com/v1
kind: StaleFeatureBranch
metadata:
name: stale-feature-branch
spec:
namespaceSubstring: -pr-
afterDaysWithoutDeploy: 1
checkEveryMinutes: 1Operátor reagoval a je připraven kontrolovat namespace:
$ 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"}Instalujeme fixtures, obsahující dva namespace (project-pr-1, project-pr-2) a jejich nasazení, služby, 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 createdKontrolujeme, že všechny výše zmíněné 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 zapnuli debug, namespace project-pr-1 a project-pr-2, tedy i všechny ostatní zdroje, by měly být ihned smazány bez ohledu na parametr afterDaysWithoutDeploy. V logech operátora je to vidět:
$ 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ž odstraněny (výstup příkazu 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
...Můžete zopakovat proces vytváření fixtures Několikrát a ujistit se, že budou odstraněny během minuty.
Alternativy
Co lze udělat místo operátora, který funguje v clusteru? Přístupů je několik, všechny jsou nedokonalé (a jejich nedostatky jsou subjektivní), a každý si musí rozhodnout, co nejlépe vyhovuje konkrétnímu projektu:
Odstranit feature branch během buildu master větve kontinuální integrace.
- K tomu je třeba vědět, který pull request se vztahuje k commit’u, který se právě sestavuje. Protože namespace feature branch obsahuje identifikátor pull requestu — jeho číslo nebo název větve, identifikátor je vždy třeba uvádět v commitu.
- Buildy master větví selhávají. Například máte následující kroky: stáhnout projekt, spustit testy, sestavit projekt, udělat release, odeslat oznámení, vyčistit feature branch posledního pull requestu. Pokud build selže při odesílání oznámení, budete muset ručně odstranit všechny prostředky v clusteru.
- Bez potřebného kontextu není odstranění feature branch v master buildu očividné.
Použití webhooků ().
- Možná to není váš přístup. Například v , pouze jeden typ pipeline podporuje možnost uchovávat svou konfiguraci v source kódu. Při použití webhooků je třeba napsat vlastní skript pro jejich zpracování. Tento skript bude třeba umístit do rozhraní Jenkins, což se obtížně udržuje.
Napsat a přidat Kubernetes cluster.
- Náklady na čas při psaní a údržbě.
- Operátor již funguje v podobném stylu, je zdokumentován a podporován.
Děkuji za pozornost k článku. .
Zdroj: habr.com
