Forigante malmodernan ĉefbranĉon en Kubernetes-areto
Saluton! Karakterizaĵa branĉo (alinome deploji antaŭrigardon, revizian apon) - ĉi tio estas kiam ne nur la majstra branĉo estas deplojita, sed ankaŭ ĉiu tira peto al unika URL. Vi povas kontroli ĉu la kodo funkcias en produktadmedio; la funkcio povas esti montrita al aliaj programistoj aŭ produktaj specialistoj. Dum vi laboras en tirpeto, ĉiu nova kompromisa aktuala deplojo por la malnova kodo estas forigita, kaj la nova deplojo por la nova kodo estas lanĉita. Demandoj povas aperi kiam vi kunfandis tirpeton en la majstran branĉon. Vi ne plu bezonas la ĉefbranĉon, sed la rimedoj de Kubernetes ankoraŭ estas en la areto.
Pli pri ĉefbranĉoj
Unu aliro por fari ĉefbranĉojn en Kubernetes estas uzi nomspacojn. Resume, la produktada agordo aspektas jene:
Ĝenerale, mi skribis Kubernetes Operatoro (aplikaĵo kiu havas aliron al clusterresursoj), ligo al la projekto en Github. Ĝi forigas nomspacojn kiuj apartenas al malnovaj trajtobranĉoj. En Kubernetes, se vi forigas nomspacon, aliaj rimedoj en tiu nomspaco ankaŭ estas aŭtomate forigitaj.
$ kubectl get pods --all-namespaces | grep -e "-pr-"
NAMESPACE ... AGE
habr-back-end-pr-264 ... 4d8h
habr-back-end-pr-265 ... 5d7h
Vi povas legi pri kiel efektivigi karakterizajn branĉojn en areton tie и tie.
Motivacio
Ni rigardu tipan tiran peton-vivciklon kun kontinua integriĝo (continuous integration):
Ni puŝas novan devontigon al la branĉo.
Sur la konstruo, linters kaj/aŭ testoj estas rulitaj.
Kubernetes-tira peto-agordoj estas generitaj sur la flugo (ekzemple, ĝia numero estas enigita en la finitan ŝablonon).
Uzante kubectl apply, agordoj estas aldonitaj al la areto (deplojado).
Tirpeto estas kunfandita en la majstran branĉon.
Dum vi laboras en tirpeto, ĉiu nova kommit-aktuala deplojo por la malnova kodo estas forigita, kaj la nova deplojo por la nova kodo estas lanĉita. Sed kiam tira peto estas kunfandita en la majstran branĉon, nur la majstra branĉo estos konstruita. Rezulte, rezultas, ke ni jam forgesis pri la tirpeto, kaj ĝiaj Kubernetes-resursoj ankoraŭ estas en la areto.
Parametro namespaceSubĉeno bezonata por filtri nomspacojn por tirpetoj de aliaj nomspacoj. Ekzemple, se la areto havas la sekvajn nomspacojn: habr-back-end, habr-front-end, habr-back-end-pr-17, habr-back-end-pr-33, tiam kandidatoj por forigo estos habr-back-end-pr-17, habr-back-end-pr-33.
Parametro postDaysWithoutDeploy bezonata por forigi malnovajn nomspacojn. Ekzemple, se nomspaco estas kreita 3 дня 1 час reen, kaj la parametro indikas 3 дня, ĉi tiu nomspaco estos forigita. Ĝi ankaŭ funkcias en la kontraŭa direkto se la nomspaco estas kreita 2 дня 23 часа reen, kaj la parametro indikas 3 дня, ĉi tiu nomspaco ne estos forigita.
Estas unu plia parametro, ĝi respondecas pri kiom ofte skani ĉiujn nomspacojn kaj kontroli dum tagoj sen deplojo - checkEveryMinutes. Defaŭlte ĝi estas egala 30 минутам.
kubectl — komandlinia interfaco por administrado de clusteroj.
Ni levas Kubernetes-areton loke:
$ 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.
Ni indikas kubectl uzu lokan areton defaŭlte:
$ kubectl config use-context minikube
Switched to context "minikube".
Ĉar produktadaj agordoj estas agorditaj por kontroli malnovajn nomspacojn, kaj nia lastatempe levita areto ne havas ilin, ni anstataŭigos la mediovariablon. IS_DEBUG sur true. Kun ĉi tiu valoro la parametro afterDaysWithoutDeploy ne estas konsiderata kaj nomspacoj ne estas kontrolitaj dum tagoj sen deplojiĝo, nur por la okazo de la subĉeno (-pr-).
Se vi estas sur Linux:
$ sed -i 's|false|true|g' stale-feature-branch-production-configs.yml
Se vi estas sur macOS:
$ sed -i "" 's|false|true|g' stale-feature-branch-production-configs.yml
$ kubectl get pods --namespace stale-feature-branch-operator
NAME ... STATUS ... AGE
stale-feature-branch-operator-6bfbfd4df8-m7sch ... Running ... 38s
Se vi rigardas ĝiajn protokolojn, ĝi pretas prilabori rimedojn StaleFeatureBranch:
La funkciigisto respondis kaj pretas kontroli nomspacojn:
$ 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"}
Instali fixtures, enhavante du nomspacojn (project-pr-1, project-pr-2) kaj ilin deployments, services, ingress, kaj tiel plu:
$ 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
Ni kontrolas, ke ĉiuj ĉi-supraj rimedoj estas sukcese kreitaj:
$ 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
...
Ĉar ni inkludis debug, nomspacoj project-pr-1 и project-pr-2, tial ĉiuj aliaj rimedoj devos esti tuj forigitaj sen konsideri la parametron afterDaysWithoutDeploy. Ĉi tio videblas en la protokoloj:
$ 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 vi kontrolas la haveblecon de rimedoj, ili estos en la stato Terminating (forigprocezo) aŭ jam forigita (komanda eligo estas malplena).
$ 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
...
Vi povas ripeti la krean procezon fixtures plurajn fojojn kaj certigu, ke ili estas forigitaj ene de minuto.
Alternativoj
Kion oni povas fari anstataŭ operatoro, kiu laboras en areto? Estas pluraj aliroj, ĉiuj ili estas neperfektaj (kaj iliaj mankoj estas subjektivaj), kaj ĉiu mem decidas, kio estas plej bona por aparta projekto:
Forigi trajtobranĉon dum kontinua integriga konstruo de majstra branĉo.
Por fari tion, vi devas scii, kiu tira peto rilatas al la kommit kiu estas konstruita. Ĉar la trajtobranĉa nomspaco enhavas la tirpeton-identigilon - ĝian numeron, aŭ la nomon de la branĉo, la identigilo ĉiam devos esti specifita en la kommit.
Majstraj branĉokonstruoj malsukcesas. Ekzemple, vi havas la sekvajn stadiojn: elŝuti la projekton, ruli testojn, konstrui la projekton, fari liberigon, sendi sciigojn, forigi la funkciobranĉon de la lasta tirpeto. Se la konstruo malsukcesas dum sendado de sciigo, vi devos forigi ĉiujn rimedojn en la areto permane.
Sen taŭga kunteksto, forigi ĉefbranĉojn en la majstra konstruo ne estas evidenta.
Ĉi tio eble ne estas via aliro. Ekzemple, en Jenkins, nur unu speco de dukto subtenas la kapablon konservi ĝiajn agordojn en la fontkodo. Kiam vi uzas rethokojn, vi devas skribi vian propran skripton por prilabori ilin. Ĉi tiu skripto devos esti metita en la Jenkins-interfacon, kiu estas malfacile konservi.