It fuortsmiten fan in ferâldere funksje tûke yn in Kubernetes kluster

It fuortsmiten fan in ferâldere funksje tûke yn in Kubernetes kluster

Hallo! Feature branch (aka ynset foarbyld, resinsje app) - dit is as net allinnich de master tûke wurdt ynset, mar ek elk pull fersyk nei in unike URL. Jo kinne kontrolearje oft de koade wurket yn in produksjeomjouwing de funksje kin wurde toand oan oare programmeurs of produkt spesjalisten. Wylst jo wurkje yn in pull fersyk, wurdt elke nije commit aktuele ynset foar de âlde koade wiske, en de nije ynset foar de nije koade wurdt útrôle. Fragen kinne opkomme as jo in pull-fersyk gearfoege yn 'e mastertûke. Jo hawwe de funksje-tûke net mear nedich, mar de Kubernetes-boarnen binne noch yn it kluster.

Mear oer funksje tûken

Ien oanpak foar it meitsjen fan funksje-tûken yn Kubernetes is it brûken fan nammeromten. Koartsein, de produksjekonfiguraasje sjocht der sa út:

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

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

Foar in funksje-tûke wurdt in nammeromte makke mei syn identifier (bygelyks it pull-oanfraachnûmer) en in soarte fan foarheaksel/postfix (bygelyks, -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
...

Yn 't algemien skreau ik Kubernetes Operator (in applikaasje dy't tagong hat ta klusterboarnen), keppeling nei it projekt op Github. It ferwideret nammeromten dy't hearre ta âlde funksje-tûken. Yn Kubernetes, as jo in nammeromte wiskje, wurde oare boarnen yn dy nammeromte ek automatysk wiske.

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

Jo kinne lêze oer hoe't jo funksje-tûken kinne ymplementearje yn in kluster hjir и hjir.

Motivaasje

Litte wy nei in typyske libbenssyklus fan pull-oanfraach sjen mei trochgeande yntegraasje (continuous integration):

  1. Wy drukke in nije commit nei de branch.
  2. Op de bou wurde linters en/of testen útfierd.
  3. Kubernetes pull fersyk konfiguraasjes wurde oanmakke op 'e fly (Bygelyks, syn getal wurdt ynfoege yn de klear sjabloan).
  4. Mei kubectl applikaasje wurde konfiguraasjes tafoege oan it kluster (ynset).
  5. Pull fersyk wurdt gearfoege yn de master tûke.

Wylst jo wurkje yn in pull fersyk, wurdt elke nije commit aktuele ynset foar de âlde koade wiske, en de nije ynset foar de nije koade wurdt útrôle. Mar as in pull fersyk wurdt gearfoege yn de master tûke, allinne de master tûke wurdt boud. As resultaat docht bliken dat wy it pull-oanfraach al fergetten binne, en har Kubernetes-boarnen binne noch yn it kluster.

Hoe brûke

Ynstallearje it projekt mei it kommando hjirûnder:

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

Meitsje in bestân mei de folgjende ynhâld en ynstallearje fia kubectl apply -f:

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

Parameter nammeromteSubstring nedich om nammeromten te filterjen foar pull-oanfragen fan oare nammeromten. As it kluster bygelyks de folgjende nammeromten hat: habr-back-end, habr-front-end, habr-back-end-pr-17, habr-back-end-pr-33, dan sille kandidaten foar wiskjen wêze habr-back-end-pr-17, habr-back-end-pr-33.

Parameter afterDaysWithoutDeploy nedich om âlde nammeromten te wiskjen. Bygelyks, as nammeromte wurdt oanmakke 3 дня 1 час werom, en de parameter oanjout 3 дня, dizze nammeromte sil wiske wurde. It wurket ek yn 'e tsjinoerstelde rjochting as de nammeromte wurdt makke 2 дня 23 часа werom, en de parameter oanjout 3 дня, dizze nammeromte sil net wiske wurde.

D'r is noch ien parameter, it is ferantwurdlik foar hoe faak alle nammeromten te scannen en dagen te kontrolearjen sûnder ynset - checkEveryMinutes. Standert is it gelyk 30 минутам.

Hoe docht dit wurk

Yn 'e praktyk sille jo nedich wêze:

  1. Havenarbeider foar wurkjen yn in isolearre omjouwing.
  2. Minikube sil lokaal in Kubernetes-kluster ophelje.
  3. kubectl - kommandorigelynterface foar klusterbehear.

Wy ferheegje in Kubernetes-kluster lokaal:

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

Wy jouwe oan kubectl brûke standert lokaal kluster:

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

Download konfiguraasjes foar de produksjeomjouwing:

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

Sûnt produksjekonfiguraasjes binne konfigureare om âlde nammeromten te kontrolearjen, en ús nij ferhege kluster hat se net, sille wy de omjouwingsfariabele ferfange IS_DEBUG op true. Mei dizze wearde de parameter afterDaysWithoutDeploy wurdt net yn rekken brocht en nammeromten wurde net kontrolearre foar dagen sûnder ynset, allinich foar it foarkommen fan de substring (-pr-).

As jo ​​binne op Linux:

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

As jo ​​binne op macOS:

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

Ynstallaasje fan it projekt:

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

Kontrolearje dat in boarne is ferskynd yn it kluster StaleFeatureBranch:

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

Wy kontrolearje dat in operator is ferskynd yn it kluster:

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

As jo ​​​​nei har logs sjogge, is it ree om boarnen te ferwurkjen 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}

Wy ynstallearje ready-made fixtures (klear makke konfiguraasjes foar modeling kluster boarnen) foar in boarne StaleFeatureBranch:

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

De konfiguraasjes jouwe oan om te sykjen nei nammeromten mei in substring -pr- ien kear elk 1 минуту.:

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

De operator hat reagearre en is ree om nammeromten te kontrolearjen:

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

Ynstallearje fixtures, mei twa nammeromten (project-pr-1, project-pr-2) en harren deployments, services, ingress, ensafuorthinne:

$ 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

Wy kontrolearje dat alle boarnen hjirboppe mei sukses makke binne:

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

Sûnt wy opnommen debug, nammeromten project-pr-1 и project-pr-2, dêrom moatte alle oare boarnen fuortdaliks wiske wurde sûnder rekken te hâlden mei de parameter afterDaysWithoutDeploy. Dit kin sjoen wurde yn de operator logs:

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

As jo ​​​​de beskikberens fan boarnen kontrolearje, sille se yn 'e status wêze Terminating (ferwidering proses) of al wiske (kommando útfier is leech).

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

Jo kinne it skeppingsproses werhelje fixtures ferskate kearen en soargje derfoar dat se wurde fuortsmiten binnen in minút.

Alternativen

Wat kin dien wurde ynstee fan in operator dy't wurket yn in kluster? D'r binne ferskate oanpak, allegear binne ûnfolslein (en har tekoarten binne subjektyf), en elkenien beslút foar himsels wat it bêste is foar in bepaald projekt:

  1. Funksjetûke wiskje tidens trochgeande yntegraasjebou fan mastertûke.

    • Om dit te dwaan, moatte jo witte hokker pull-fersyk ferwiist nei de commit dy't wurdt boud. Sûnt de nammeromte fan 'e funksje-tûke de identifier foar pull-oanfraach befettet - syn nûmer, of de namme fan' e branch, sil de identifier altyd moatte wurde opjûn yn 'e commit.
    • De bou fan mastertûken mislearret. Jo hawwe bygelyks de folgjende stadia: it projekt downloade, testen útfiere, it projekt bouwe, in release meitsje, notifikaasjes ferstjoere, de funksje-tûke wiskje fan it lêste pull-fersyk. As de build mislearret by it ferstjoeren fan in notifikaasje, moatte jo alle boarnen yn it kluster manuell wiskje.
    • Sûnder juste kontekst is it wiskjen fan funksjetûken yn 'e masterbuild net fanselssprekkend.

  2. Webhooks brûke (foarbyld).

    • Dit kin jo oanpak net wêze. Bygelyks, yn Jenkins, mar ien type pipeline stipet de mooglikheid om syn konfiguraasjes yn 'e boarnekoade te bewarjen. By it brûken fan webhooks moatte jo jo eigen skript skriuwe om se te ferwurkjen. Dit skript sil moatte wurde pleatst yn de Jenkins ynterface, dat is lestich te ûnderhâlden.

  3. Skriuw in berjocht Cronjob en foegje in Kubernetes-kluster ta.

    • Tiid besteegje oan skriuwen en stipe.
    • De operator wurket al yn in ferlykbere styl, is dokumintearre en stipe.

Tankewol foar jo oandacht foar it artikel. Link nei it projekt op Github.

Boarne: www.habr.com

Add a comment