
Përshëndetje! Dega feature (në të ashtuquajturën deploy preview, review app) — kjo ndodh kur deployohet jo vetëm dega master, por edhe çdo pull request në një URL unik. Mund të kontrolloni nëse kodi funksionon në ambientin production, dhe funksionin mund ta tregoni programuesve të tjerë ose produktologëve. Ndërsa po punoni në pull request, çdo commit i ri anulon deploy-n aktual për kodin e vjetër, dhe një deploy i ri për kodin e ri hapet. Pyetje mund të lindin kur e keni bashkuar pull request-in në degën master. Dega e funksionit nuk ju nevojitet më, por resurset e Kubernetes ende ndodhen në klaster.
Më shumë për degat e funksionit
Një nga qasjet për të bërë degat e funksionit në Kubernetes është përdorimi i namespace-ve. Nëse do ta thjeshtojmë, konfigurimet e production duken kështu:
kind: Namespace
apiVersion: v1
metadata:
name: habr-back-end
...
kind: Deployment
apiVersion: apps/v1
metadata:
namespace: habr-back-end
spec:
replicas: 3
...Për dega të funksionit krijohet një namespace me identifikuesin e saj (për shembull, numri i pull request-it) dhe një prefiks/postfix të caktuar (për shembull, -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
...Në përgjithësi, unë shkrova Kubernetes Operator (aplikacioni që ka qasje në resurset e klasterit), . Ai heq namespace-t që i përkasin degëve të vjetra të funksioneve. Në Kubernetes, nëse hiqet një namespace, burimet e tjera në atë namespace gjithashtu hiqen automatikisht.
$ kubectl get pods --all-namespaces | grep -e "-pr-"
NAMESPACE ... AGE
habr-back-end-pr-264 ... 4d8h
habr-back-end-pr-265 ... 5d7hPër mënyrën se si të implementoni degët e funksioneve në klaster, mund të lexoni dhe .
Motivimi
Le të shohim një cikël të zakonshëm jetësor të një kërkese për tërheqje me integrimin e vazhdueshëm (integrimi i vazhdueshëm):
- Shtojmë një commit të ri në degë.
- Gjatë ndërtimit, aktivizohen linters dhe/ose testet.
- Në kohë reale formohen konfigurimet e kërkesës për tërheqje në Kubernetes (për shembull, numri i saj vendoset në një shabllon të gatshëm).
- Me ndihmën e kubectl apply, konfigurimet hyjnë në klaster (deploy).
- Kërkesat për tërheqje bashkohen në degën master.
Ndërsa punoni në kërkesën për tërheqje, çdo commit i ri heq deploy-in aktual për kodin e vjetër dhe nxjerr një deploy të ri për kodin e ri. Por kur kërkesa për tërheqje bashkohet në degën master, do të ndërtohet vetëm dega master. Si rezultat, harrojmë për kërkesën për tërheqje, por burimet e saj Kubernetes ende ndodhen në klaster.
Si të përdorim
Instaloni projektin me komandën më poshtë:
$ kubectl apply -f https://raw.githubusercontent.com/dmytrostriletskyi/stale-feature-branch-operator/master/configs/production.ymlKrijo një skedar me përmbajtjen e mëposhtme dhe vendos përmes kubectl apply -f:
apiVersion: feature-branch.dmytrostriletskyi.com/v1
kind: StaleFeatureBranch
metadata:
name: stale-feature-branch
spec:
namespaceSubstring: -pr-
afterDaysWithoutDeploy: 3Parametri namespaceSubstring nevojitet për të filtruar namespace-t për kërkesat e tërheqjes nga namespace të tjera. Për shembull, nëse në klaster ka këto namespace: habr-back-end, habr-front-end, habr-back-end-pr-17, habr-back-end-pr-33, atëherë kandidatët për fshirje do të jenë habr-back-end-pr-17, habr-back-end-pr-33.
Parametri afterDaysWithoutDeploy nevojitet për të fshirë namespace-t e vjetra. Për shembull, nëse namespace është krijuar 3 ditë 1 orë më parë, dhe në parametrin është caktuar 3 ditë, ky namespace do të fshihet. Funksionon edhe në anën tjetër, nëse namespace është krijuar 2 ditë 23 orë më parë, dhe në parametrin është caktuar 3 ditë, ky namespace nuk do të fshihet.
Ka edhe një parametër tjetër, ai përgjigjet për sa shpesh skanohet të gjithë namespace-t dhe kontrollohet për ditët pa deploy — checkEveryMinutes. Në mënyrë të paracaktuar, ai është i barabartë me 30 minuta.
Si funksionon
Në praktikë, do të nevojitet:
- për të punuar në një mjedis të izoluar.
- do të ngrejë klasterin Kubernetes lokal.
- — ndërfaqja e komandave për të menaxhuar klasterin.
Ngremë klasterin Kubernetes lokal:
$ minikube start --vm-driver=docker
minikube v1.11.0 në Darwin 10.15.5
Duke përdorur drejtuesin docker në bazë të profilit ekzistues.
Duke filluar kontrollin e planeve minikube në klasterin minikube.Tregojmë kubectl përdor klasterin lokal si parazgjedhje:
$ kubectl config use-context minikube
Kalova në kontekstin "minikube".Po shkarkojmë konfiguratat për ambientin e production-it:
$ curl https://raw.githubusercontent.com/dmytrostriletskyi/stale-feature-branch-operator/master/configs/production.yml > stale-feature-branch-production-configs.ymlPasi konfiguratat e production-it janë vendosur të kontrollojnë namespace-t e vjetra, dhe në klasterin tonë të sapo krijuar nuk ka asnjë, do të zëvendësojmë variablën e ambientit IS_DEBUG në e vërtetë. Me këtë vlerë, parametri afterDaysWithoutDeploy nuk merret parasysh dhe namespace-t nuk kontrollohen për ditë pa deploy, vetëm për përmbajtjen e nënstringut (-pr-).
Nëse jeni në OpenVPN:
$ sed -i 's|false|true|g' stale-feature-branch-production-configs.ymlNëse jeni në Mac Catalyst:
$ sed -i "" 's|false|true|g' stale-feature-branch-production-configs.ymlPo instalojmë projektin:
$ kubectl apply -f stale-feature-branch-production-configs.ymlPo kontrollojmë që resurset janë shfaqur në klaster StaleFeatureBranch:
$ kubectl api-resources | grep stalefeaturebranches
EMRI ... APIGROUP ... LLOJI
stalefeaturebranches ... feature-branch.dmytrostriletskyi.com ... StaleFeatureBranchPo kontrollojmë që operatori është shfaqur në klaster:
$ kubectl get pods --namespace stale-feature-branch-operator
EMRI ... STATUS ... MOSHA
stale-feature-branch-operator-6bfbfd4df8-m7sch ... Duke funksionuar ... 38sNëse shikoni në logjet e tij, ai është gati të përpunojë resurset StaleFeatureBranch:
$ kubectl logs stale-feature-branch-operator-6bfbfd4df8-m7sch -n stale-feature-branch-operator
... "msg":"Versioni i Operatorit: 0.0.1"}
...
... "msg":"Duke filluar EventSource", ... , "source":"lloji i burimit: /, Lloji="}
... "msg":"Duke filluar Kontrolluesin", ...}
... "msg":"Duke filluar punëtorët", ..., "numri i punëtorëve":1}Instalojmë gotiot fixtures (konfigurime të gatshme për simulimin e burimeve të klasës) për burimin StaleFeatureBranch:
$ kubectl apply -f https://raw.githubusercontent.com/dmytrostriletskyi/stale-feature-branch-operator/master/fixtures/stale-feature-branch.ymlKonfigurimet specifikojnë të kërkojnë namespace’ë me nënpjesën -pr- një herë në 1 minutë.:
apiVersion: feature-branch.dmytrostriletskyi.com/v1
lloji: StaleFeatureBranch
metadata:
emri: stale-feature-branch
spec:
namespaceSubstring: -pr-
afterDaysWithoutDeploy: 1
checkEveryMinutes: 1Operatori ka reaguar dhe është gati të kontrollojë namespace’ët:
$ kubectl logs stale-feature-branch-operator-6bfbfd4df8-m7sch -n stale-feature-branch-operator
... "msg":"Gurëza e branches së vjetra po përshkruhet.","namespaceSubstring":"-pr-","afterDaysWithoutDeploy":1,"checkEveryMinutes":1,"isDebug":"true"}Instalojmë fixtures, që përmban dy namespace’a (project-pr-1, project-pr-2) dhe shërbimet e tyre dispozita, , dhe kështu me radhë:, ingress, dhe kështu me radhë:
$ 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 createdKontrollojmë që të gjitha burimet e lartpërmendura janë krijuar me sukses:
$ 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
...Duke bërë këtë, debug, namespace-të project-pr-1 dhe project-pr-2, gjithashtu të gjitha burimet e tjera, duhet të fshihen menjëherë pa marrë parasysh parametrin afterDaysWithoutDeploy. Në logët e operatorit kjo është e dukshme:
$ kubectl logs stale-feature-branch-operator-6bfbfd4df8-m7sch -n stale-feature-branch-operator
... "msg":"Namespace duhet të fshihet për shkak se moda e debugging është e aktivizuar.","namespaceName":"project-pr-1"}
... "msg":"Namespace është duke u përpunuar.","namespaceName":"project-pr-1","namespaceCreationTimestamp":"2020-06-16 18:43:58 +0300 EEST"}
... "msg":"Namespace është fshirë.","namespaceName":"project-pr-1"}
... "msg":"Namespace duhet të fshihet për shkak se moda e debugging është e aktivizuar.","namespaceName":"project-pr-2"}
... "msg":"Namespace është duke u përpunuar.","namespaceName":"project-pr-2","namespaceCreationTimestamp":"2020-06-16 18:43:58 +0300 EEST"}
... "msg":"Namespace është fshirë.","namespaceName":"project-pr-2"}Nëse kontrolloni disponueshmërinë e burimeve, ato do të jenë në statusin Duke u përfunduar (procesi i fshirjes) ose tashmë janë fshirë (dalja e komandës është e zbrazët).
$ 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
...Mund të përsërisni procesin e krijimit fixtures disa herë dhe të siguroheni që ato do të fshihen brenda një minute.
Alternativat
Çfarë mund të bëni në vend të operatorit që punon në klaster? Ka disa qasje, të gjitha nuk janë të përsosura (dhe disavantazhet e tyre janë subjektive), dhe secili vendos se cila është më e përshtatshme për projektin specifik:
Të fshini branch-in e karakteristikave gjatë ndërtimit të integrimit të vazhdueshëm të branch-it master.
- Për këtë, duhet të dini se cilin pull request i përket commit-it që po ndërtohet. Duke qenë se emri i hapësirës së branch-it të veçorisë përmban identifikuesin e pull request-it — numrin e tij ose emrin e branch-it, identifikuesi gjithmonë duhet të përmendet në commit.
- Ndërtesat e branch-it master dështojnë. Për shembull, keni këto etapa: shkarkoni projektin, ekzekutoni testet, ndërtoni projektin, bëni lëshimin, dërgoni njoftimet, pastroni branch-in e veçorisë së pull request-it të fundit. Nëse ndërtimi dështoi në dërgimin e njoftimit, do t'ju duhet të fshini të gjitha burimet në klaster manualisht.
- Pa kontekst të duhur, fshirja e branch-it të veçorisë në ndërtimin master nuk është e qartë.
Përdorimi i webhook-ve ().
- Mundësisht, kjo nuk është qasja juaj. Për shembull, në , vetëm një lloj pipeline-i mbështet mundësinë për të ruajtur konfigurimet e tij në kodin burimor. Në përdorimin e webhook-ve, duhet të shkruani skriptin tuaj për përpunimin e tyre. Ky skript do të duhet të vendoset në ndërfaqen e Jenkins-it, çka është e vështirë për t'u mbajtur.
Shkruani dhe shtoni klasterin Kubernetes.
- Kosto kohe për të shkruar dhe mbajtur.
- Operatori tashmë funksionon në një stil të ngjashëm, është dokumentuar dhe mbështetet.
Faleminderit për vëmendjen ndaj artikullit. .
Burimi: habr.com
