Eliminazione di un ramu di funzioni obsoleti in un cluster Kubernetes
Hello! Branca di funziunalità (aka deploy preview, review app) - questu hè quandu ùn hè micca solu implementatu u ramu maestru, ma ancu ogni dumanda di pull à un URL unicu. Pudete verificà se u codice funziona in un ambiente di produzzione a funzione pò esse mostrata à altri programatori o specialisti di produttu. Mentre stai travagliendu in una dumanda di pull, ogni novu cummit currente implementazione per u vechju codice hè sguassatu, è a nova implementazione per u novu codice hè sbulicata. E dumande ponu esse quandu avete unitu una dumanda di pull in u ramu maestru. Ùn avete più bisognu di u ramu di funziunalità, ma i risorse Kubernetes sò sempre in u cluster.
Più nantu à e branche di funziunalità
Un approcciu per fà rami di funziunalità in Kubernetes hè di utilizà spazii di nomi. In breve, a cunfigurazione di a produzzione s'assumiglia cusì:
Per un ramu di funziunalità, un spaziu di nome hè creatu cù u so identificatore (per esempiu, u numeru di dumanda di pull) è un tipu di prefissu / postfix (per esempiu, -pr-):
In generale, aghju scrittu Operatore Kubernetes (una applicazione chì hà accessu à e risorse di cluster), ligame à u prughjettu nantu à Github. Elimina spazii di nomi chì appartenenu à vechji rami di funziunalità. In Kubernetes, se sguassate un spaziu di nomi, altre risorse in quellu spaziu di nomi sò ancu eliminati automaticamente.
$ kubectl get pods --all-namespaces | grep -e "-pr-"
NAMESPACE ... AGE
habr-back-end-pr-264 ... 4d8h
habr-back-end-pr-265 ... 5d7h
Pudete leghje cumu implementà e rami di funziunalità in un cluster ccà и ccà.
Motivazione
Fighjemu un ciclu di vita tipicu di dumanda di pull cù integrazione cuntinua (continuous integration):
Impulsemu un novu impegnu à a filiera.
Nantu à a custruzzione, linters è / o teste sò eseguiti.
I cunfigurazioni di dumanda di pull Kubernetes sò generati nantu à a mosca (per esempiu, u so numeru hè inseritu in u mudellu finitu).
Utilizendu kubectl applica, e cunfigurazioni sò aghjuntu à u cluster (deploy).
Pull request hè unitu in u ramu maestru.
Mentre stai travagliendu in una dumanda di pull, ogni novu cummit currente implementazione per u vechju codice hè sguassatu, è a nova implementazione per u novu codice hè sbulicata. Ma quandu un pull request hè unitu in u ramu maestru, solu u ramu maestru serà custruitu. In u risultatu, ci hè chì avemu digià scurdatu di a dumanda di pull, è i so risorse Kubernetes sò sempre in u cluster.
Parameter namespaceSubstring necessariu per filtrà i spazii di nomi per e richieste di pull da altri spazii di nomi. Per esempiu, se u cluster hà i seguenti spazii di nomi: habr-back-end, habr-front-end, habr-back-end-pr-17, habr-back-end-pr-33, allura i candidati per a cancellazione seranu habr-back-end-pr-17, habr-back-end-pr-33.
Parameter afterDaysWithoutDeploy necessariu per sguassà vechji spazii di nomi. Per esempiu, se u spaziu di nomi hè creatu 3 дня 1 час daretu, è u paràmetru indica 3 дня, stu spaziu di nomi serà sguassatu. Funciona ancu in a direzzione opposta se u namespace hè creatu 2 дня 23 часа daretu, è u paràmetru indica 3 дня, stu namespace ùn serà micca sguassatu.
Ci hè un paràmetru più, hè rispunsevuli di quantu spessu scansà tutti i spazii di nomi è verificate per ghjorni senza implementazione - verificate ogni minutu. Per automaticamente hè uguali 30 минутам.
Minikube susciterà un cluster Kubernetes in u locu.
kubectl - interfaccia di linea di cummanda per a gestione di cluster.
Creemu un cluster Kubernetes in u locu:
$ 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.
Avemu indicatu kubectl aduprà cluster locale per difettu:
$ kubectl config use-context minikube
Switched to context "minikube".
Scaricate e cunfigurazioni per l'ambiente di produzzione:
Siccomu e cunfigurazioni di pruduzzione sò cunfigurate per verificà i vechji spazii di nomi, è u nostru cluster appena risuscitatu ùn li hà micca, rimpiazzeremu a variabile d'ambiente IS_DEBUG nantu true. Cù stu valore u paràmetru afterDaysWithoutDeploy ùn hè micca cunsideratu è i spazii di nomi ùn sò micca verificati per ghjorni senza implementazione, solu per l'occurrence di a substringa (-pr-).
Sè vo site nantu Linux:
$ sed -i 's|false|true|g' stale-feature-branch-production-configs.yml
Sè vo site nantu macOS:
$ sed -i "" 's|false|true|g' stale-feature-branch-production-configs.yml
Avemu verificatu chì un operatore hè apparsu in u cluster:
$ kubectl get pods --namespace stale-feature-branch-operator
NAME ... STATUS ... AGE
stale-feature-branch-operator-6bfbfd4df8-m7sch ... Running ... 38s
Se guardate i so logs, hè prontu à processà e risorse StaleFeatureBranch:
L'operatore hà rispostu è hè prontu à verificà i spazii di nomi:
$ 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"}
Stallà fixtures, chì cuntene dui spazii di nomi (project-pr-1, project-pr-2) è elli deployments, services, ingress, eccetera:
$ 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
Avemu verificatu chì tutte e risorse sopra sò state create bè:
$ 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
...
Dapoi avemu inclusu debug, spazii di nomi project-pr-1 и project-pr-2, dunque tutti l'altri risorse anu da esse sguassati immediatamente senza piglià in contu u paràmetru afterDaysWithoutDeploy. Questu pò esse vistu in i logs di l'operatore:
$ 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"}
Se verificate a dispunibilità di risorse, seranu in u statutu Terminating (processu di eliminazione) o digià sguassatu (l'output di cumanda hè viotu).
$ 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
...
Pudete ripetiri u prucessu di creazione fixtures parechje volte è assicuratevi chì sò eliminati in un minutu.
Alternattivi
Chì pò esse fattu invece di un operatore chì travaglia in un cluster? Ci hè parechje avvicinamenti, tutti sò imperfetti (è i so difetti sò subjectivi), è ognunu decide per ellu stessu ciò chì hè megliu per un prughjettu particulari:
Sguassate u ramu di funzioni durante a custruzzione di integrazione cuntinua di u ramu maestru.
Per fà questu, avete bisognu di sapè quale pull request riguarda l'impegnu chì hè custruitu. Siccomu u spaziu di nomi di ramu di funziunalità cuntene l'identificatore di dumanda di pull - u so numeru, o u nome di u ramu, l'identificatore sempre deve esse specificatu in u commit.
E custruzzioni di u ramu maestru fallenu. Per esempiu, avete e seguenti tappe: scaricate u prughjettu, eseguite testi, custruisce u prugettu, fate un alliberamentu, mandate notificazioni, sguassate u ramu di funziunalità di l'ultima dumanda di pull. Se a custruzione falla quandu invià una notificazione, duverete sguassà tutte e risorse in u cluster manualmente.
Senza un cuntestu propiu, l'eliminazione di e rami di funziunalità in a custruzzione maestra ùn hè micca evidenti.
Questu pò micca esse u vostru approcciu. Per esempiu, in Jenkins, solu un tipu di pipeline sustene a capacità di salvà e so cunfigurazioni in u codice fonte. Quandu utilizate webhooks, avete bisognu di scrive u vostru propiu script per processà. Stu script deve esse postu in l'interfaccia di Jenkins, chì hè difficiule di mantene.
Per scrive Cronjob è aghjunghje un cluster Kubernetes.
Passà u tempu in scrittura è sustegnu.
L'operatore travaglia digià in un stile simili, hè documentatu è supportatu.