Eliminarea unei ramuri de caracteristici învechite dintr-un cluster Kubernetes

Eliminarea unei ramuri de caracteristici învechite dintr-un cluster Kubernetes

Hi! Ramura caracteristică (alias previzualizarea implementării, aplicația de revizuire) - atunci nu numai ramura principală este implementată, ci și fiecare solicitare de extragere la o adresă URL unică. Puteți verifica dacă codul funcționează într-un mediu de producție; caracteristica poate fi afișată altor programatori sau specialiști în produse. În timp ce lucrați la o cerere de extragere, fiecare nouă comitere, implementarea curentă pentru codul vechi este ștearsă, iar implementarea nouă pentru codul nou este lansată. Pot apărea întrebări când ați îmbinat o cerere de extragere în ramura principală. Nu mai aveți nevoie de ramura caracteristică, dar resursele Kubernetes sunt încă în cluster.

Mai multe despre ramurile caracteristice

O abordare a creării de ramuri de caracteristici în Kubernetes este utilizarea spațiilor de nume. Pe scurt, configurația de producție arată astfel:

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

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

Pentru o ramură de caracteristică, un spațiu de nume este creat cu identificatorul său (de exemplu, numărul cererii de extragere) și un fel de prefix/postfix (de exemplu, -relatii cu publicul-):

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 general, am scris Operator Kubernetes (o aplicație care are acces la resursele clusterului), link către proiectul de pe Github. Îndepărtează spațiile de nume care aparțin ramurilor de caracteristici vechi. În Kubernetes, dacă ștergeți un spațiu de nume, celelalte resurse din acel spațiu de nume sunt, de asemenea, șterse automat.

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

Puteți citi despre cum să implementați ramuri de caracteristici într-un cluster aici и aici.

Motivație

Să ne uităm la un ciclu de viață tipic al cererii de extragere cu integrare continuă (continuous integration):

  1. Impingem un nou angajament către filială.
  2. Pe build, sunt rulate linters și/sau teste.
  3. Configurațiile de solicitare de extragere Kubernetes sunt generate din mers (de exemplu, numărul său este inserat în șablonul final).
  4. Folosind kubectl apply, configurațiile sunt adăugate la cluster (deploy).
  5. Solicitarea de tragere este îmbinată în ramura principală.

În timp ce lucrați la o cerere de extragere, fiecare nouă comitere, implementarea curentă pentru codul vechi este ștearsă, iar implementarea nouă pentru codul nou este lansată. Dar când o cerere de extragere este îmbinată în ramura principală, va fi construită doar ramura principală. Ca rezultat, se dovedește că am uitat deja de cererea de extragere, iar resursele sale Kubernetes sunt încă în cluster.

Cum să utilizați

Instalați proiectul cu comanda de mai jos:

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

Creați un fișier cu următorul conținut și instalați prin kubectl apply -f:

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

Parametru namespaceSubstring necesare pentru a filtra spațiile de nume pentru cererile de extragere din alte spații de nume. De exemplu, dacă clusterul are următoarele spații de nume: habr-back-end, habr-front-end, habr-back-end-pr-17, habr-back-end-pr-33, atunci candidații pentru ștergere vor fi habr-back-end-pr-17, habr-back-end-pr-33.

Parametru afterDaysWithoutDeploy necesare pentru a șterge spațiile de nume vechi. De exemplu, dacă este creat un spațiu de nume 3 дня 1 час înapoi, iar parametrul indică 3 дня, acest spațiu de nume va fi șters. De asemenea, funcționează în direcția opusă dacă este creat spațiul de nume 2 дня 23 часа înapoi, iar parametrul indică 3 дня, acest spațiu de nume nu va fi șters.

Mai există un parametru, acesta este responsabil pentru cât de des să scanați toate spațiile de nume și să verificați zilele fără implementare - checkEveryMinutes. Implicit este egal cu 30 минутам.

Cum funcționează

În practică, veți avea nevoie de:

  1. Docher pentru lucrul într-un mediu izolat.
  2. Minikube va ridica un cluster Kubernetes la nivel local.
  3. kubectl — interfață de linie de comandă pentru managementul clusterului.

Creăm un cluster Kubernetes la nivel local:

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

Vă indicăm kubectl utilizați clusterul local în mod implicit:

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

Descărcați configurații pentru mediul de producție:

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

Deoarece configurațiile de producție sunt configurate pentru a verifica spațiile de nume vechi, iar clusterul nostru nou creat nu le are, vom înlocui variabila de mediu IS_DEBUG pe true. Cu această valoare parametrul afterDaysWithoutDeploy nu este luată în considerare și spațiile de nume nu sunt verificate zile fără implementare, doar pentru apariția subșirului (-pr-).

Dacă ești pe Linux:

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

Dacă ești pe macOS:

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

Instalarea proiectului:

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

Verificarea faptului că o resursă a apărut în cluster StaleFeatureBranch:

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

Verificăm dacă un operator a apărut în cluster:

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

Dacă vă uitați la jurnalele sale, este gata să proceseze resurse 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}

Instalăm gata făcute fixtures (configurații gata făcute pentru modelarea resurselor cluster) pentru o resursă StaleFeatureBranch:

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

Configurațiile indică căutarea spațiilor de nume cu un subșir -pr- odata in 1 минуту.:

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

Operatorul a răspuns și este gata să verifice spațiile de nume:

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

Set fixtures, care conține două spații de nume (project-pr-1, project-pr-2) și ei deployments, services, ingress, și așa mai departe:

$ 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

Verificăm dacă toate resursele de mai sus au fost create cu succes:

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

Din moment ce am inclus debug, spații de nume project-pr-1 и project-pr-2, prin urmare toate celelalte resurse vor trebui șterse imediat fără a lua în considerare parametrul afterDaysWithoutDeploy. Acest lucru poate fi văzut în jurnalele operatorului:

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

Dacă verificați disponibilitatea resurselor, acestea vor fi în stare Terminating (proces de ștergere) sau deja șters (ieșirea comenzii este goală).

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

Puteți repeta procesul de creare fixtures de mai multe ori și asigurați-vă că sunt îndepărtate într-un minut.

alternative

Ce se poate face în locul unui operator care lucrează într-un cluster? Există mai multe abordări, toate sunt imperfecte (iar deficiențele lor sunt subiective) și fiecare decide singur ce este mai bine pentru un anumit proiect:

  1. Ștergeți ramura caracteristică în timpul construcției de integrare continuă a ramurii principale.

    • Pentru a face acest lucru, trebuie să știți ce cerere de extragere se referă la commit-ul care este construit. Deoarece spațiul de nume al ramurilor caracteristice conține identificatorul cererii de extragere - numărul său sau numele ramurii, identificatorul va trebui întotdeauna specificat în commit.
    • Construcțiile de ramuri principale eșuează. De exemplu, aveți următoarele etape: descărcați proiectul, rulați teste, construiți proiectul, faceți o lansare, trimiteți notificări, ștergeți ramura caracteristică a ultimei cereri de extragere. Dacă compilarea eșuează la trimiterea unei notificări, va trebui să ștergeți manual toate resursele din cluster.
    • Fără context adecvat, ștergerea ramurilor caracteristice din versiunea principală nu este evidentă.

  2. Folosind webhook-uri (exemplu).

    • Este posibil să nu fie abordarea ta. De exemplu, în Jenkins, doar un tip de conductă acceptă capacitatea de a-și salva configurațiile în codul sursă. Când utilizați webhook-uri, trebuie să vă scrieți propriul script pentru a le procesa. Acest script va trebui să fie plasat în interfața Jenkins, care este greu de întreținut.

  3. scrie Cronjob și adăugați un cluster Kubernetes.

    • Petreceți timp scrisului și asistenței.
    • Operatorul lucrează deja într-un stil similar, este documentat și susținut.

Vă mulțumim pentru atenția acordată articolului. Link către proiect pe Github.

Sursa: www.habr.com

Adauga un comentariu