
Hälsningar! Funktionsgren (även känd som distribuera förhandsvisning, granska app) — det är då inte bara huvudgrenen distribueras, utan även varje pull-förfrågan till en unik URL. Du kan kontrollera om koden fungerar i en produktionsmiljö, och funktionen kan visas för andra programmerare eller produktchefer. Medan du arbetar med en pull request tar varje ny commit bort den aktuella distributionen för den gamla koden och lanserar en ny distribution för den nya koden. Frågor kan uppstå när du sammanfogar en pull-förfrågan i huvudgrenen. Du behöver inte längre funktionsgrenen, men Kubernetes-resurserna finns fortfarande i klustret.
Mer om funktionsgrenar
Ett sätt att skapa funktionsgrenar i Kubernetes är att använda namnrymder. Kortfattat ser produktionskonfigurationen ut så här:
kind: Namespace
apiVersion: v1
metadata:
name: habr-back-end
...
kind: Deployment
apiVersion: apps/v1
metadata:
namespace: habr-back-end
spec:
replicas: 3
...
För en funktionsgren skapas ett namnutrymme med dess identifierare (till exempel pull request-numret) och något prefix/postfix (till exempel -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
...
Hur som helst, jag skrev Kubernetes-operatör (en applikation som har åtkomst till klusterresurser), . Den tar bort namnrymder som refererar till gamla funktionsgrenar. Om du tar bort ett namnutrymme i Kubernetes tas även andra resurser i det namnutrymmet bort automatiskt.
$ kubectl get pods --all-namespaces | grep -e "-pr-"
NAMESPACE ... AGE
habr-back-end-pr-264 ... 4d8h
habr-back-end-pr-265 ... 5d7h
Du kan läsa om hur man implementerar funktionsgrenar i ett kluster и .
Motivation
Låt oss ta en titt på en typisk livscykel för pull requests med kontinuerlig integration (continuous integration):
- Skicka en ny commit till grenen.
- På bygget körs linters och/eller tester.
- Kubernetes pull request-konfigurationer genereras i farten (till exempel ersätts dess nummer med en färdig mall).
- Med hjälp av kubectl apply distribueras konfigurationer till klustret.
- Pull-begäran slås samman med master-grenen.
Medan du arbetar med en pull request tar varje ny commit bort den aktuella distributionen för den gamla koden och lanserar en ny distribution för den nya koden. Men när en pull-förfrågan sammanfogas med master-grenen, kommer endast master-grenen att byggas. Det visar sig därför att vi redan har glömt bort pull-förfrågan, och dess Kubernetes-resurser finns fortfarande i klustret.
Hur man använder
Installera projektet med kommandot nedan:
$ kubectl apply -f https://raw.githubusercontent.com/dmytrostriletskyi/stale-feature-branch-operator/master/configs/production.yml
Skapa en fil med följande innehåll och installera via kubectl apply -f:
apiVersion: feature-branch.dmytrostriletskyi.com/v1
kind: StaleFeatureBranch
metadata:
name: stale-feature-branch
spec:
namespaceSubstring: -pr-
afterDaysWithoutDeploy: 3
Parameter namnrymdsubsträng behövs för att filtrera namnrymder för pull-förfrågningar från andra namnrymder. Till exempel, om ett kluster har följande namnrymder: habr-back-end, habr-front-end, habr-back-end-pr-17, habr-back-end-pr-33, då kommer kandidaterna för avsättning att vara habr-back-end-pr-17, habr-back-end-pr-33.
Parameter efterDagarUtanDistribuering behövs för att ta bort gamla namnrymder. Till exempel, om namnrymden skapas 3 дня 1 час tillbaka, och parametern indikerar 3 дня, kommer detta namnrymd att raderas. Fungerar även tvärtom, om namnrymden skapas 2 дня 23 часа tillbaka, och parametern indikerar 3 дня, kommer detta namnrymd inte att raderas.
Det finns ytterligare en parameter, den ansvarar för hur ofta alla namnrymder ska genomsökas och kontrolleras om det finns dagar utan distribution — kontrolleraVarjeMinut. Som standard är den lika med 30 минутам.
Hur fungerar den här
I praktiken behöver du:
- för arbete i en isolerad miljö.
- kommer att sätta upp ett Kubernetes-kluster lokalt.
- — kommandoradsgränssnitt för klusterhantering.
Vi skapar ett Kubernetes-kluster lokalt:
$ 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.
Vi indikerar kubectl använd lokalt kluster som standard:
$ kubectl config use-context minikube
Switched to context "minikube".
Ladda ner konfigurationer för produktionsmiljön:
$ curl https://raw.githubusercontent.com/dmytrostriletskyi/stale-feature-branch-operator/master/configs/production.yml > stale-feature-branch-production-configs.yml
Eftersom produktionskonfigurationerna är inställda på att kontrollera gamla namnrymder, och vårt nyligen skapade kluster inte har dem, kommer vi att ersätta miljövariabeln IS_DEBUG på true. Med detta värde parametern afterDaysWithoutDeploy beaktas inte och namnrymder kontrolleras inte för dagar utan distribution, endast för förekomsten av en delsträng (-pr-).
Om du är på Linux:
$ sed -i 's|false|true|g' stale-feature-branch-production-configs.yml
Om du är på macOS:
$ sed -i "" 's|false|true|g' stale-feature-branch-production-configs.yml
Installera projektet:
$ kubectl apply -f stale-feature-branch-production-configs.yml
Vi kontrollerar att resursen har dykt upp i klustret StaleFeatureBranch:
$ kubectl api-resources | grep stalefeaturebranches
NAME ... APIGROUP ... KIND
stalefeaturebranches ... feature-branch.dmytrostriletskyi.com ... StaleFeatureBranch
Vi kontrollerar att operatorn har dykt upp i klustret:
$ kubectl get pods --namespace stale-feature-branch-operator
NAME ... STATUS ... AGE
stale-feature-branch-operator-6bfbfd4df8-m7sch ... Running ... 38s
Om du tittar på dess loggar är den redo att bearbeta resurser. 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}
Vi installerar färdiga fixtures (färdiga konfigurationer för modellering av klusterresurser) för resursen StaleFeatureBranch:
$ kubectl apply -f https://raw.githubusercontent.com/dmytrostriletskyi/stale-feature-branch-operator/master/fixtures/stale-feature-branch.yml
Konfigurationerna anger att söka efter namnrymder med en delsträng -pr- en gång varje 1 минуту.:
apiVersion: feature-branch.dmytrostriletskyi.com/v1
kind: StaleFeatureBranch
metadata:
name: stale-feature-branch
spec:
namespaceSubstring: -pr-
afterDaysWithoutDeploy: 1
checkEveryMinutes: 1
Operatorn har svarat och är redo att kontrollera namnrymder:
$ 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"}
Ställ fixtures, som innehåller två namnrymder (project-pr-1, project-pr-2) och deras deployments, services, ingress, och så vidare:
$ 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
Låt oss kontrollera att alla resurser ovan har skapats:
$ 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
...
Eftersom vi har inkluderat debug, namnrymder project-pr-1 и project-pr-2, därför måste alla andra resurser omedelbart raderas utan att ta hänsyn till parametern afterDaysWithoutDeploy. Detta kan ses i operatörsloggarna:
$ 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"}
Om du kontrollerar tillgängligheten för resurser kommer de att visas i statusen Terminating (borttagningsprocess) eller redan raderad (kommandoutdata är tom).
$ 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
...
Du kan upprepa skapandeprocessen fixtures flera gånger och se till att de tas bort inom en minut.
alternativ
Vad kan göras istället för operatören som arbetar i klustret? Det finns flera tillvägagångssätt, alla är inte idealiska (och deras brister är subjektiva), och alla bestämmer själva vad som passar bäst för ett specifikt projekt:
-
Ta bort funktionsgrenen under kontinuerlig integrationsbyggande av huvudgrenen.
- För att göra detta behöver du veta vilken pull request som relaterar till den commit som byggs. Eftersom funktionsgrenens namnrymd innehåller pull request-identifieraren - dess nummer eller grennamn - måste identifieraren alltid anges i commit-filen.
- Byggnader av huvudgrenar misslyckas. Till exempel har du följande steg: ladda ner projektet, köra tester, bygga projektet, göra en release, skicka aviseringar, rensa funktionsgrenen från den senaste pull-förfrågan. Om bygget misslyckas när ett meddelande skickas måste du ta bort alla resurser i klustret manuellt.
- Utan korrekt kontext är det inte uppenbart att ta bort en funktionsgren i en huvudversion.
-
Använda webhooks ().
- Detta kanske inte är din strategi. Till exempel i , endast en typ av pipeline stöder möjligheten att spara sina konfigurationer i källkoden. När du använder webhooks måste du skriva ditt eget skript för att hantera dem. Det här skriptet skulle behöva lagras i Jenkins-gränssnittet, vilket är svårt att underhålla.
-
skriva och lägg till ett Kubernetes-kluster.
- Tid som läggs ner på skrivande och support.
- Operatören arbetar redan på ett liknande sätt, är dokumenterad och har stöd.
Tack för din uppmärksamhet på artikeln. .
Källa: will.com
