УдаляСм ΡƒΡΡ‚Π°Ρ€Π΅Π²ΡˆΡƒΡŽ feature branch Π² Kubernetes кластСрС

УдаляСм ΡƒΡΡ‚Π°Ρ€Π΅Π²ΡˆΡƒΡŽ feature branch Π² Kubernetes кластСрС

ΠŸΡ€ΠΈΠ²Π΅Ρ‚! Feature branch (aka deploy preview, review app) β€” это ΠΊΠΎΠ³Π΄Π° дСплоится Π½Π΅ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ master Π²Π΅Ρ‚ΠΊΠ°, Π½ΠΎ ΠΈ ΠΊΠ°ΠΆΠ΄Ρ‹ΠΉ pull request Π½Π° ΡƒΠ½ΠΈΠΊΠ°Π»ΡŒΠ½Ρ‹ΠΉ URL. МоТно ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΈΡ‚ΡŒ Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚ Π»ΠΈ ΠΊΠΎΠ΄ Π² production-ΠΎΠΊΡ€ΡƒΠΆΠ΅Π½ΠΈΠΈ, Ρ„ΠΈΡ‡Ρƒ ΠΌΠΎΠΆΠ½ΠΎ ΠΏΠΎΠΊΠ°Π·Π°Ρ‚ΡŒ Π΄Ρ€ΡƒΠ³ΠΈΠΌ программистам ΠΈΠ»ΠΈ ΠΏΡ€ΠΎΠ΄ΡƒΠΊΡ‚ΠΎΠ»ΠΎΠ³Π°ΠΌ. Пока Π²Ρ‹ Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚Π΅ Π² pull request’Π΅, ΠΊΠ°ΠΆΠ΄Ρ‹ΠΉ Π½ΠΎΠ²Ρ‹ΠΉ commit Ρ‚Π΅ΠΊΡƒΡ‰ΠΈΠΉ deploy для старого ΠΊΠΎΠ΄Π° удаляСтся, Π° Π½ΠΎΠ²Ρ‹ΠΉ deploy для Π½ΠΎΠ²ΠΎΠ³ΠΎ ΠΊΠΎΠ΄Π° выкатываСтся. Вопросы ΠΌΠΎΠ³ΡƒΡ‚ Π²ΠΎΠ·Π½ΠΈΠΊΠ½ΡƒΡ‚ΡŒ Ρ‚ΠΎΠ³Π΄Π°, ΠΊΠΎΠ³Π΄Π° Π²Ρ‹ смСрдТили pull request Π² master Π²Π΅Ρ‚ΠΊΡƒ. Feature branch Π²Π°ΠΌ большС Π½Π΅ Π½ΡƒΠΆΠ½Π°, Π½ΠΎ рСсурсы Kubernetes всС Π΅Ρ‰Π΅ находятся Π² кластСрС.

Π•Ρ‰Π΅ ΠΏΡ€ΠΎ feature branch’ΠΈ

Один ΠΈΠ· ΠΏΠΎΠ΄Ρ…ΠΎΠ΄ΠΎΠ² ΠΊΠ°ΠΊ ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ feature branch’ΠΈ Π² Kubernetes β€” ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ namespace’Ρ‹. Если ΠΊΡ€Π°Ρ‚ΠΊΠΎ, production ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΠΈ выглядит Ρ‚Π°ΠΊ:

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

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

Для feature branch создаСтся namespace c Π΅Π΅ ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ‚ΠΎΡ€ΠΎΠΌ (Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, Π½ΠΎΠΌΠ΅Ρ€ pull request’Π°) ΠΈ ΠΊΠ°ΠΊΠΈΠΌ-Ρ‚ΠΎ прСфиксом/постфиксом (Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, -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
...

Π’ ΠΎΠ±Ρ‰Π΅ΠΌ, я написал Kubernetes Operator (ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅, ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ΅ ΠΈΠΌΠ΅Π΅Ρ‚ доступ ΠΊ рСсурсам кластСра), ссылка Π½Π° ΠΏΡ€ΠΎΠ΅ΠΊΡ‚ Π½Π° Github. Он удаляСт namespace’Ρ‹, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ относятся ΠΊ старым feature branch’Π°ΠΌ. Π’ Kubernetes, Ссли ΡƒΠ΄Π°Π»ΠΈΡ‚ΡŒ namespace, Π΄Ρ€ΡƒΠ³ΠΈΠ΅ рСсурсы Π² этом namespace Ρ‚Π°ΠΊΠΆΠ΅ ΡƒΠ΄Π°Π»ΡΡŽΡ‚ΡΡ автоматичСски.

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

ΠŸΡ€ΠΎ Ρ‚ΠΎ ΠΊΠ°ΠΊ Π²Π½Π΅Π΄Ρ€ΠΈΡ‚ΡŒ feature branch’ΠΈ Π² кластСр, ΠΌΠΎΠΆΠ½ΠΎ ΠΏΠΎΡ‡ΠΈΡ‚Π°Ρ‚ΡŒ Ρ‚ΡƒΡ‚ ΠΈ Ρ‚ΡƒΡ‚.

ΠœΠΎΡ‚ΠΈΠ²Π°Ρ†ΠΈΡ

Π”Π°Π²Π°ΠΉΡ‚Π΅ посмотрим Π½Π° Ρ‚ΠΈΠΏΠΈΡ‡Π½Ρ‹ΠΉ ΠΆΠΈΠ·Π½Π΅Π½Π½Ρ‹ΠΉ Ρ†ΠΈΠΊΠ» pull request’a с Π½Π΅ΠΏΡ€Π΅Ρ€Ρ‹Π²Π½ΠΎΠΉ ΠΈΠ½Ρ‚Π΅Π³Ρ€Π°Ρ†ΠΈΠ΅ΠΉ (continuous integration):

  1. ΠŸΡƒΡˆΠΈΠΌ Π½ΠΎΠ²Ρ‹ΠΉ commit Π² Π²Π΅Ρ‚ΠΊΡƒ.
  2. На Π±ΠΈΠ»Π΄Π΅, Π·Π°ΠΏΡƒΡΠΊΠ°ΡŽΡ‚ΡΡ Π»ΠΈΠ½Ρ‚Π΅Ρ€Ρ‹ ΠΈ/ΠΈΠ»ΠΈ тСсты.
  3. На Π»Π΅Ρ‚Ρƒ Ρ„ΠΎΡ€ΠΌΠΈΡ€ΡƒΡŽΡ‚ΡΡ ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΠΈ Kubernetes pull request’a (Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, Π² Π³ΠΎΡ‚ΠΎΠ²Ρ‹ΠΉ шаблон подставляСтся Π΅Π³ΠΎ Π½ΠΎΠΌΠ΅Ρ€).
  4. Π‘ ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ kubectl apply ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΠΈ ΠΏΠΎΠΏΠ°Π΄Π°ΡŽΡ‚ Π² кластСр (deploy).
  5. Pull request сливаСтся Π² master Π²Π΅Ρ‚ΠΊΡƒ.

Пока Π²Ρ‹ Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚Π΅ Π² pull request’Π΅, ΠΊΠ°ΠΆΠ΄Ρ‹ΠΉ Π½ΠΎΠ²Ρ‹ΠΉ commit Ρ‚Π΅ΠΊΡƒΡ‰ΠΈΠΉ deploy для старого ΠΊΠΎΠ΄Π° удаляСтся, Π° Π½ΠΎΠ²Ρ‹ΠΉ deploy для Π½ΠΎΠ²ΠΎΠ³ΠΎ ΠΊΠΎΠ΄Π° выкатываСтся. Но ΠΊΠΎΠ³Π΄Π° pull request сливаСтся Π² master Π²Π΅Ρ‚ΠΊΡƒ, Π±ΡƒΠ΄Π΅Ρ‚ билдится Ρ‚ΠΎΠ»ΡŒΠΊΠΎ master Π²Π΅Ρ‚ΠΊΠ°. Π’ ΠΈΡ‚ΠΎΠ³Π΅ получаСтся, Ρ‡Ρ‚ΠΎ ΠΏΡ€ΠΎ pull request ΠΌΡ‹ ΡƒΠΆΠ΅ Π·Π°Π±Ρ‹Π»ΠΈ, Π° Π΅Π³ΠΎ Kubernetes рСсурсы всС Π΅Ρ‰Π΅ находятся Π² кластСрС.

Как ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ

Π£ΡΡ‚Π°Π½ΠΎΠ²ΠΈΡ‚ΡŒ ΠΏΡ€ΠΎΠ΅ΠΊΡ‚ ΠΊΠΎΠΌΠ°Π½Π΄ΠΎΠΉ Π½ΠΈΠΆΠ΅:

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

Π‘ΠΎΠ·Π΄Π°Ρ‚ΡŒ Ρ„Π°ΠΉΠ» со ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΌ содСрТаниСм ΠΈ ΡƒΡΡ‚Π°Π½ΠΎΠ²ΠΈΡ‚ΡŒ Ρ‡Π΅Ρ€Π΅Π· kubectl apply -f:

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

ΠŸΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ namespaceSubstring Π½ΡƒΠΆΠ΅Π½, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΎΡ‚Ρ„ΠΈΠ»ΡŒΡ‚Ρ€ΠΎΠ²Π°Ρ‚ΡŒ namespace’Ρ‹ для pull request’ΠΎΠ² ΠΎΡ‚ Π΄Ρ€ΡƒΠ³ΠΈΡ… namespace’ΠΎΠ². НапримСр, Ссли Π² кластСрС Π΅ΡΡ‚ΡŒ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠ΅ namespace’Ρ‹: habr-back-end, habr-front-end, habr-back-end-pr-17, habr-back-end-pr-33, Ρ‚ΠΎΠ³Π΄Π° ΠΊΠ°Π½Π΄ΠΈΠ΄Π°Ρ‚Π°ΠΌΠΈ Π½Π° ΡƒΠ΄Π°Π»Π΅Π½ΠΈΠ΅ Π±ΡƒΠ΄ΡƒΡ‚ habr-back-end-pr-17, habr-back-end-pr-33.

ΠŸΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ afterDaysWithoutDeploy Π½ΡƒΠΆΠ΅Π½ Ρ‡Ρ‚ΠΎΠ±Ρ‹, ΡƒΠ΄Π°Π»ΡΡ‚ΡŒ старыС namespace’Ρ‹. НапримСр, Ссли namespace создан 3 дня 1 час Π½Π°Π·Π°Π΄, Π° Π² ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Π΅ ΡƒΠΊΠ°Π·Π°Π½ΠΎ 3 дня, этот namespace Π±ΡƒΠ΄Π΅Ρ‚ ΡƒΠ΄Π°Π»Π΅Π½. Π Π°Π±ΠΎΡ‚Π°Π΅Ρ‚ ΠΈ Π² ΠΎΠ±Ρ€Π°Ρ‚Π½ΡƒΡŽ сторону, Ссли namespace создан 2 дня 23 часа Π½Π°Π·Π°Π΄, Π° Π² ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Π΅ ΡƒΠΊΠ°Π·Π°Π½ΠΎ 3 дня, этот namespace Π½Π΅ Π±ΡƒΠ΄Π΅Ρ‚ ΡƒΠ΄Π°Π»Π΅Π½.

Π•ΡΡ‚ΡŒ Π΅Ρ‰Π΅ ΠΎΠ΄ΠΈΠ½ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€, ΠΎΠ½ ΠΎΡ‚Π²Π΅Ρ‡Π°Π΅Ρ‚ Π·Π° Ρ‚ΠΎ ΠΊΠ°ΠΊ часто ΡΠΊΠ°Π½ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ всС namespace’Ρ‹ ΠΈ ΠΏΡ€ΠΎΠ²Π΅Ρ€ΡΡ‚ΡŒ Π½Π° Π΄Π½ΠΈ Π±Π΅Π· deploy’я β€” checkEveryMinutes. По ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ ΠΎΠ½ Ρ€Π°Π²Π΅Π½ 30 ΠΌΠΈΠ½ΡƒΡ‚Π°ΠΌ.

Как это Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚

На ΠΏΡ€Π°ΠΊΡ‚ΠΈΠΊΠ΅, понадобится:

  1. Docker для Ρ€Π°Π±ΠΎΡ‚Ρ‹ Π² ΠΈΠ·ΠΎΠ»ΠΈΡ€ΠΎΠ²Π°Π½Π½ΠΎΠΌ ΠΎΠΊΡ€ΡƒΠΆΠ΅Π½ΠΈΠΈ.
  2. Minikube ΠΏΠΎΠ΄Π½ΠΈΠΌΠ΅Ρ‚ Kubernetes кластСр локально.
  3. kubectl β€” интСрфСйс ΠΊΠΎΠΌΠ°Π½Π΄Π½ΠΎΠΉ строки для управлСния кластСром.

ПоднимаСм Kubernetes кластСр локально:

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

Π£ΠΊΠ°Π·Ρ‹Π²Π°Π΅ΠΌ kubectl ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Π»ΠΎΠΊΠ°Π»ΡŒΠ½Ρ‹ΠΉ кластСр ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ:

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

Π‘ΠΊΠ°Ρ‡ΠΈΠ²Π°Π΅ΠΌ ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΠΈ для production-срСды:

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

Π’Π°ΠΊ ΠΊΠ°ΠΊ production ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΠΈ настроСны ΠΏΡ€ΠΎΠ²Π΅Ρ€ΡΡ‚ΡŒ старыС namespace’Ρ‹, Π° Π² нашСм Π½ΠΎΠ²ΠΎ поднятом кластСрС ΠΈΡ… Π½Π΅Ρ‚, Π·Π°ΠΌΠ΅Π½ΠΈΠΌ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΡƒΡŽ окруТСния IS_DEBUG Π½Π° true. ΠŸΡ€ΠΈ Ρ‚Π°ΠΊΠΎΠΌ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠΈ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ afterDaysWithoutDeploy Π½Π΅ учитываСтся ΠΈ namespace’Ρ‹ Π½Π΅ ΠΏΡ€ΠΎΠ²Π΅Ρ€ΡΡŽΡ‚ΡΡ Π½Π° Π΄Π½ΠΈ Π±Π΅Π· deploy’я, Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Π½Π° Π²Ρ…ΠΎΠΆΠ΄Π΅Π½ΠΈΠ΅ подстроки (-pr-).

Если Π²Ρ‹ Π½Π° Linux:

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

Если Π²Ρ‹ Π½Π° macOS:

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

УстанавливаСм ΠΏΡ€ΠΎΠ΅ΠΊΡ‚:

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

ΠŸΡ€ΠΎΠ²Π΅Ρ€ΡΠ΅ΠΌ, Ρ‡Ρ‚ΠΎ Π² кластСрС появился рСсурс StaleFeatureBranch:

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

ΠŸΡ€ΠΎΠ²Π΅Ρ€ΡΠ΅ΠΌ, Ρ‡Ρ‚ΠΎ Π² кластСрС появился ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€:

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

Если Π·Π°Π³Π»ΡΠ½ΡƒΡ‚ΡŒ Π² Π΅Π³ΠΎ Π»ΠΎΠ³ΠΈ, ΠΎΠ½ Π³ΠΎΡ‚ΠΎΠ² ΠΎΠ±Ρ€Π°Π±Π°Ρ‚Ρ‹Π²Π°Ρ‚ΡŒ рСсурсы 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}

УстанавливаСм Π³ΠΎΡ‚ΠΎΠ²Ρ‹Π΅ fixtures (Π³ΠΎΡ‚ΠΎΠ²Ρ‹Π΅ ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΠΈ для модСлирования рСсурсов кластСра) для рСсурса StaleFeatureBranch:

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

Π’ конфигурациях ΡƒΠΊΠ°Π·Π°Π½ΠΎ ΠΈΡΠΊΠ°Ρ‚ΡŒ namespace’Ρ‹ с подстрокой -pr- Ρ€Π°Π· Π² 1 ΠΌΠΈΠ½ΡƒΡ‚Ρƒ.:

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

ΠžΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€ ΠΎΡ‚Ρ€Π΅Π°Π³ΠΈΡ€ΠΎΠ²Π°Π» ΠΈ Π³ΠΎΡ‚ΠΎΠ² ΠΏΡ€ΠΎΠ²Π΅Ρ€ΡΡ‚ΡŒ namespace’Ρ‹:

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

УстанавливаСм fixtures, содСрТащиС Π΄Π²Π° namespace’Π° (project-pr-1, project-pr-2) ΠΈ ΠΈΡ… deployments, services, ingress, ΠΈ Ρ‚Π°ΠΊ Π΄Π°Π»Π΅Π΅:

$ 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

ΠŸΡ€ΠΎΠ²Π΅Ρ€ΡΠ΅ΠΌ, Ρ‡Ρ‚ΠΎ всС рСсурсы Π²Ρ‹ΡˆΠ΅ ΡƒΡΠΏΠ΅ΡˆΠ½ΠΎ созданы:

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

Π’Π°ΠΊ ΠΊΠ°ΠΊ ΠΌΡ‹ Π²ΠΊΠ»ΡŽΡ‡ΠΈΠ»ΠΈ debug, namespace’Ρ‹ project-pr-1 ΠΈ project-pr-2, ΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎ ΠΈ всС ΠΎΡΡ‚Π°Π»ΡŒΠ½Ρ‹Π΅ рСсурсы, Π΄ΠΎΠ»ΠΆΠ½Ρ‹ Π±ΡƒΠ΄ΡƒΡ‚ сразу ΡƒΠ΄Π°Π»ΠΈΡ‚ΡŒΡΡ Π½Π΅ учитывая ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ afterDaysWithoutDeploy. Π’ Π»ΠΎΠ³Π°Ρ… ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€Π° это Π²ΠΈΠ΄Π½ΠΎ:

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

Если ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΈΡ‚ΡŒ Π½Π°Π»ΠΈΡ‡ΠΈΠ΅ рСсурсов, ΠΎΠ½ΠΈ Π±ΡƒΠ΄ΡƒΡ‚ Π² статусС Terminating (процСсс удалСния) ΠΈΠ»ΠΈ ΡƒΠΆΠ΅ ΡƒΠ΄Π°Π»Π΅Π½Ρ‹ (Π²Ρ‹Π²ΠΎΠ΄ ΠΊΠΎΠΌΠ°Π½Π΄Ρ‹ пуст).

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

ΠœΠΎΠΆΠ΅Ρ‚Π΅ ΠΏΠΎΠ²Ρ‚ΠΎΡ€ΠΈΡ‚ΡŒ процСсс создания fixtures нСсколько Ρ€Π°Π· ΠΈ ΡƒΠ±Π΅Π΄ΠΈΡ‚ΡŒΡΡ, Ρ‡Ρ‚ΠΎ ΠΎΠ½ΠΈ Π±ΡƒΠ΄ΡƒΡ‚ ΡƒΠ΄Π°Π»Π΅Π½Ρ‹ Π² Ρ‚Π΅Ρ‡Π΅Π½ΠΈΠ΅ ΠΌΠΈΠ½ΡƒΡ‚Ρ‹.

ΠΠ»ΡŒΡ‚Π΅Ρ€Π½Π°Ρ‚ΠΈΠ²Ρ‹

Π§Ρ‚ΠΎ ΠΌΠΎΠΆΠ½ΠΎ ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ вмСсто ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€Π°, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚ Π² кластСрС? ΠŸΠΎΠ΄Ρ…ΠΎΠ΄ΠΎΠ² нСсколько, всС ΠΎΠ½ΠΈ Π½Π΅ΠΈΠ΄Π΅Π°Π»ΡŒΠ½Ρ‹ (ΠΈ ΠΈΡ… нСдостатки ΡΡƒΠ±ΡŠΠ΅ΠΊΡ‚ΠΈΠ²Π½Ρ‹), ΠΈ ΠΊΠ°ΠΆΠ΄Ρ‹ΠΉ сам Ρ€Π΅ΡˆΠ°Π΅Ρ‚ Ρ‡Ρ‚ΠΎ Π»ΡƒΡ‡ΡˆΠ΅ всСго ΠΏΠΎΠ΄ΠΎΠΉΠ΄Π΅Ρ‚ Π½Π° ΠΊΠΎΠ½ΠΊΡ€Π΅Ρ‚Π½ΠΎΠΌ ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π΅:

  1. Π£Π΄Π°Π»ΡΡ‚ΡŒ feature branch Π²ΠΎ врСмя Π±ΠΈΠ»Π΄Π° Π½Π΅ΠΏΡ€Π΅Ρ€Ρ‹Π²Π½ΠΎΠΉ ΠΈΠ½Ρ‚Π΅Π³Ρ€Π°Ρ†ΠΈΠΈ master Π²Π΅Ρ‚ΠΊΠΈ.

    • Для этого Π½Π°Π΄ΠΎ Π·Π½Π°Ρ‚ΡŒ ΠΊΠ°ΠΊΠΎΠΉ pull request относится ΠΊ commit’Ρƒ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ билдится. Π’Π°ΠΊ ΠΊΠ°ΠΊ feature branch namespace содСрТит Π² сСбС ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ‚ΠΎΡ€ pull request’a β€” Π΅Π³ΠΎ Π½ΠΎΠΌΠ΅Ρ€, ΠΈΠ»ΠΈ Π½Π°Π·Π²Π°Π½ΠΈΠ΅ Π²Π΅Ρ‚ΠΊΠΈ, ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ‚ΠΎΡ€ всСгда придСтся ΡƒΠΊΠ°Π·Ρ‹Π²Π°Ρ‚ΡŒ Π² commit’e.
    • Π‘ΠΈΠ»Π΄Ρ‹ master Π²Π΅Ρ‚ΠΎΠΊ фСйлятся. НапримСр, Ρƒ вас ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠ΅ этапы: ΡΠΊΠ°Ρ‡Π°Ρ‚ΡŒ ΠΏΡ€ΠΎΠ΅ΠΊΡ‚, Π·Π°ΠΏΡƒΡΡ‚ΠΈΡ‚ΡŒ тСсты, ΡΠΎΠ±Ρ€Π°Ρ‚ΡŒ ΠΏΡ€ΠΎΠ΅ΠΊΡ‚, ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ Ρ€Π΅Π»ΠΈΠ·, ΠΎΡ‚ΠΏΡ€Π°Π²ΠΈΡ‚ΡŒ увСдомлСния, ΠΎΡ‡ΠΈΡΡ‚ΠΈΡ‚ΡŒ feature branch послСднСго pull request’a. Если Π±ΠΈΠ»Π΄ сфСйлится Π½Π° ΠΎΡ‚ΠΏΡ€Π°Π²ΠΊΠ΅ увСдомлСния, Π²Π°ΠΌ придСтся ΡƒΠ΄Π°Π»ΡΡ‚ΡŒ всС рСсурсы Π² кластСрС Ρ€ΡƒΠΊΠ°ΠΌΠΈ.
    • Π‘Π΅Π· Π΄ΠΎΠ»ΠΆΠ½ΠΎΠ³ΠΎ контСкста, ΡƒΠ΄Π°Π»Π΅Π½ΠΈΠ΅ feature branch’ΠΈ Π² master Π±ΠΈΠ»Π΄Π΅ Π½Π΅ΠΎΡ‡Π΅Π²ΠΈΠ΄Π½ΠΎ.

  2. ИспользованиС webhook’ΠΎΠ² (ΠΏΡ€ΠΈΠΌΠ΅Ρ€).

    • Π’ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ, это Π½Π΅ ваш ΠΏΠΎΠ΄Ρ…ΠΎΠ΄. НапримСр, Π² Jenkins, Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΎΠ΄ΠΈΠ½ Π²ΠΈΠ΄ ΠΏΠ°ΠΉΠΏΠ»Π°ΠΉΠ½Π° ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°Π΅Ρ‚ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡ‚ΡŒ ΡΠΎΡ…Ρ€Π°Π½ΡΡ‚ΡŒ Π΅Π³ΠΎ ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΠΈ Π² исходном ΠΊΠΎΠ΄Π΅. ΠŸΡ€ΠΈ использовании webhook’ΠΎΠ² Π½ΡƒΠΆΠ½ΠΎ Π½Π°ΠΏΠΈΡΠ°Ρ‚ΡŒ свой скрипт для ΠΈΡ… ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ. Π­Ρ‚ΠΎΡ‚ скрипт придСтся Ρ€Π°Π·ΠΌΠ΅Ρ‰Π°Ρ‚ΡŒ Π² интСрфСйсС Jenkins’Π°, Ρ‡Ρ‚ΠΎ Ρ‚Ρ€ΡƒΠ΄Π½ΠΎ ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°Ρ‚ΡŒ.

  3. ΠΠ°ΠΏΠΈΡΠ°Ρ‚ΡŒ Cronjob ΠΈ Π΄ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ Kubernetes кластСр.

    • Π—Π°Ρ‚Ρ€Π°Ρ‚Π° Π²Ρ€Π΅ΠΌΠ΅Π½ΠΈ Π½Π° написаниС ΠΈ ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΡƒ.
    • ΠžΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€ ΡƒΠΆΠ΅ Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚ Π² ΠΏΠΎΠ΄ΠΎΠ±Π½ΠΎΠΌ стилС, Π·Π°Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚ΠΈΡ€ΠΎΠ²Π°Π½ ΠΈ поддСрТиваСтся.

Бпасибо Π·Π° Π²Π½ΠΈΠΌΠ°Π½ΠΈΠ΅ ΠΊ ΡΡ‚Π°Ρ‚ΡŒΠ΅. Бсылка Π½Π° ΠΏΡ€ΠΎΠ΅ΠΊΡ‚ Π½Π° Github.

Π˜ΡΡ‚ΠΎΡ‡Π½ΠΈΠΊ: habr.com