ืจื™ืžื•ื•ื•ื™ื ื’ ืึทืŸ ืึทื•ื˜ื“ื™ื™ื˜ื™ื“ ืฉื˜ืจื™ืš ืฆื•ื•ื™ื™ึทื’ ืื™ืŸ ืึท ืงื•ื‘ืขืจื ืขื˜ืขืก ืงื ื•ื™ืœ

ืจื™ืžื•ื•ื•ื™ื ื’ ืึทืŸ ืึทื•ื˜ื“ื™ื™ื˜ื™ื“ ืฉื˜ืจื™ืš ืฆื•ื•ื™ื™ึทื’ ืื™ืŸ ืึท ืงื•ื‘ืขืจื ืขื˜ืขืก ืงื ื•ื™ืœ

ื”ื™! ืฉื˜ืจื™ืš ืฆื•ื•ื™ื™ึทื’ (ืึทืงืึท ื“ื™ืคึผืœื•ื™ ืคืึธืจื•ื™ืกื™ืงืข ื•ื•ื™ื™ึทื–ื•ื ื’, ืึธืคึผืฉืึทืฆื•ื ื’ ืึทืคึผ) - ื“ืึธืก ืื™ื– ื•ื•ืขืŸ ื ื™ื˜ ื‘ืœื•ื™ื– ื“ื™ ื‘ืขืœ ืฆื•ื•ื™ื™ึทื’ ืื™ื– ื“ื™ืคึผืœื•ื™ื“, ืึธื‘ืขืจ ืื•ื™ืš ื™ืขื“ืขืจ ืฆื™ืขืŸ ื‘ืขื˜ืŸ ืฆื• ืึท ื™ื™ื ืฆื™ืง URL. ืื™ืจ ืงืขื ืขืŸ ืงืึธื ื˜ืจืึธืœื™ืจืŸ ืฆื™ ื“ื™ ืงืึธื“ ืึทืจื‘ืขื˜ ืื™ืŸ ืึท ืคึผืจืึธื“ื•ืงืฆื™ืข ืกื•ื•ื™ื•ื•ืข, ื“ื™ ืฉื˜ืจื™ืš ืงืขื ืขืŸ ื–ื™ื™ืŸ ื’ืขื•ื•ื™ื–ืŸ ืฆื• ืื ื“ืขืจืข ืคึผืจืึธื•ื’ืจืึทืžืขืจื– ืึธื“ืขืจ ืคึผืจืึธื“ื•ืงื˜ ืกืคึผืขืฉืึทืœืึทืกืฅ. ื‘ืฉืขืช ืื™ืจ ืึทืจื‘ืขื˜ ืื™ืŸ ืึท ืฆื™ืขืŸ ื‘ืขื˜ืŸ, ื™ืขื“ืขืจ ื ื™ื™ึท ื™ื‘ืขืจื’ืขื‘ืŸ ืงืจืึทื ื˜ ืฆืขื•ื•ื™ืงืœืขืŸ ืคึฟืึทืจ ื“ื™ ืึทืœื˜ ืงืึธื“ ืื™ื– ืื•ื™ืกื’ืขืžืขืงื˜, ืื•ืŸ ื“ื™ ื ื™ื™ึทืข ืฆืขื•ื•ื™ืงืœืขืŸ ืคึฟืึทืจ ื“ื™ ื ื™ื™ึทืข ืงืึธื“ ืื™ื– ืจืึธื•ืœื“ ืื•ื™ืก. ืคึฟืจืื’ืŸ ืงืขืŸ ืื•ื™ืคืฉื˜ื™ื™ืŸ ื•ื•ืขืŸ ืื™ืจ ืฆื•ื ื•ื™ืคื’ื™ืกืŸ ืึท ืฆื™ืขืŸ ื‘ืขื˜ืŸ ืื™ืŸ ื“ื™ ื‘ืขืœ ืฆื•ื•ื™ื™ึทื’. ืื™ืจ ื ื™ื˜ ืžืขืจ ื“ืึทืจืคึฟืŸ ื“ื™ ืฉื˜ืจื™ืš ืฆื•ื•ื™ื™ึทื’, ืึธื‘ืขืจ ื“ื™ Kubernetes ืจืขืกื•ืจืกืŸ ื–ืขื ืขืŸ ื ืึธืš ืื™ืŸ ื“ืขื ืงื ื•ื™ืœ.

ืžืขืจ ื•ื•ืขื’ืŸ ืฉื˜ืจื™ืš ืฆื•ื•ื™ื™ื’ืŸ

ืื™ื™ืŸ ืฆื•ื’ืึทื ื’ ืฆื• ืžืึทื›ืŸ ืฉื˜ืจื™ืš ืฆื•ื•ื™ื™ื’ืŸ ืื™ืŸ Kubernetes ืื™ื– ืฆื• ื ื•ืฆืŸ ื ืึธืžืขืŸ ืกืคึผื™ื™ืกืึทื–. ืื™ืŸ ืงื•ืจืฅ, ื“ื™ ืคึผืจืึธื“ื•ืงืฆื™ืข ืงืึทื ืคื™ื’ื™ืขืจื™ื™ืฉืึทืŸ ืงื•ืงื˜ ื•ื•ื™ ื“ืึธืก:

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

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

ืคึฟืึทืจ ืึท ืฉื˜ืจื™ืš ืฆื•ื•ื™ื™ึทื’, ืึท ื ืึทืžืขืกืคึผืึทืกืข ืื™ื– ื‘ืืฉืืคืŸ ืžื™ื˜ ื–ื™ื™ืŸ ืื™ื“ืขื ื˜ื™ื˜ืขื˜ (ืœืžืฉืœ, ื“ื™ ืฆื™ืขืŸ ื‘ืขื˜ืŸ ื ื•ืžืขืจ) ืื•ืŸ ืึท ืžื™ืŸ ืคื•ืŸ ืคึผืจืขืคื™ืงืก / ืคึผืึธืกื˜ืคื™ืงืก (ืœืžืฉืœ, -ืคึผืจ-):

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

ืื™ืŸ ืึทืœื’ืขืžื™ื™ืŸ, ืื™ืš ื’ืขืฉืจื™ื‘ืŸ ืงื•ื‘ืขืจื ืขื˜ืขืก ืึธืคึผืขืจืึทื˜ืึธืจ (ืึทืŸ ืึทืคึผืœืึทืงื™ื™ืฉืึทืŸ ื•ื•ืึธืก ื”ืื˜ ืึทืงืกืขืก ืฆื• ืงื ื•ื™ืœ ืจืขืกื•ืจืกืŸ), ืœื™ื ืง ืฆื• ื“ื™ ืคึผืจื•ื™ืขืงื˜ ืื•ื™ืฃ Github. ืขืก ืจื™ืžื•ื•ื•ื– ื ืึทืžืขืกืคึผืึทืกืขืก ื•ื•ืึธืก ื’ืขื”ืขืจืŸ ืฆื• ืึทืœื˜ ืฉื˜ืจื™ืš ืฆื•ื•ื™ื™ื’ืŸ. ืื™ืŸ Kubernetes, ืื•ื™ื‘ ืื™ืจ ื•ื™ืกืžืขืงืŸ ืึท ื ืึทืžืขืกืคึผืึทืกืข, ืื ื“ืขืจืข ืจืขืกื•ืจืกืŸ ืื™ืŸ ื“ืขื ื ืึทืžืขืกืคึผืึทืกืข ื–ืขื ืขืŸ ืื•ื™ืš ืื•ื™ื˜ืึธืžืึทื˜ื™ืฉ ืื•ื™ืกื’ืขืžืขืงื˜.

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

ืื™ืจ ืงืขื ื˜ ืœื™ื™ืขื ืขืŸ ื•ื•ืขื’ืŸ ื•ื•ื™ ืฆื• ื™ื ืกื˜ืจื•ืžืขื ื˜ ืฉื˜ืจื™ืš ืฆื•ื•ื™ื™ื’ืŸ ืื™ืŸ ืึท ืงื ื•ื™ืœ ื“ืึธ ะธ ื“ืึธ.

ืžืึธื•ื˜ืึทื•ื•ื™ื™ืฉืึทืŸ

ืœืึธืžื™ืจ ืงื•ืงืŸ ืื™ืŸ ืึท ื˜ื™ืคึผื™ืฉ ืœื™ื™ืคืกื™ื™ืง ืคื•ืŸ ืฆื™ืขืŸ ื‘ืขื˜ืŸ ืžื™ื˜ ืงืขืกื™ื™ื“ืขืจื“ื™ืง ื™ื ืึทื’ืจื™ื™ืฉืึทืŸ (continuous integration):

  1. ืžื™ืจ ืฉื˜ื•ืคึผืŸ ืึท ื ื™ื™ึท ื™ื‘ืขืจื’ืขื‘ืŸ ืฆื• ื“ื™ ืฆื•ื•ื™ื™ึทื’.
  2. ืื•ื™ืฃ ื“ื™ ื‘ื•ื™ืขืŸ, ืœื™ื ื˜ืขืจื– ืื•ืŸ / ืึธื“ืขืจ ื˜ืขืกืฅ ื–ืขื ืขืŸ ืœื•ื™ืคืŸ.
  3. ืงื•ื‘ืขืจื ืขื˜ืขืก ืฆื™ืขืŸ ื‘ืขื˜ืŸ ืงืึทื ืคื™ื’ื™ืขืจื™ื™ืฉืึทื ื– ื–ืขื ืขืŸ ื“ื–ืฉืขื ืขืจื™ื™ื˜ืึทื“ ืื•ื™ืฃ ื“ื™ ืคืœื™ืขืŸ (ืœืžืฉืœ, ื–ื™ื™ึทืŸ ื ื•ืžืขืจ ืื™ื– ื™ื ืกืขืจื˜ืึทื“ ืื™ืŸ ื“ื™ ืคืึทืจื˜ื™ืง ืžื•ืกื˜ืขืจ).
  4. ื ื™ืฆืŸ kubectl ืึทืคึผืœื™ื™ื–, ืงืึทื ืคื™ื’ื™ืขืจื™ื™ืฉืึทื ื– ื–ืขื ืขืŸ ืžื•ืกื™ืฃ ืฆื• ื“ื™ ืงื ื•ื™ืœ (ืฆืขื•ื•ื™ืงืœืขืŸ).
  5. ืฆื™ืขืŸ ื‘ืขื˜ืŸ ืื™ื– ืžืขืจื“ื–ืฉื“ ืื™ืŸ ื“ื™ ื‘ืขืœ ืฆื•ื•ื™ื™ึทื’.

ื‘ืฉืขืช ืื™ืจ ืึทืจื‘ืขื˜ ืื™ืŸ ืึท ืฆื™ืขืŸ ื‘ืขื˜ืŸ, ื™ืขื“ืขืจ ื ื™ื™ึท ื™ื‘ืขืจื’ืขื‘ืŸ ืงืจืึทื ื˜ ืฆืขื•ื•ื™ืงืœืขืŸ ืคึฟืึทืจ ื“ื™ ืึทืœื˜ ืงืึธื“ ืื™ื– ืื•ื™ืกื’ืขืžืขืงื˜, ืื•ืŸ ื“ื™ ื ื™ื™ึทืข ืฆืขื•ื•ื™ืงืœืขืŸ ืคึฟืึทืจ ื“ื™ ื ื™ื™ึทืข ืงืึธื“ ืื™ื– ืจืึธื•ืœื“ ืื•ื™ืก. ืื‘ืขืจ ื•ื•ืขืŸ ืึท ืฆื™ืขืŸ ื‘ืขื˜ืŸ ืื™ื– ืžืขืจื“ื–ืฉื“ ืื™ืŸ ื“ื™ ื‘ืขืœ ืฆื•ื•ื™ื™ึทื’, ื ืึธืจ ื“ื™ ื‘ืขืœ ืฆื•ื•ื™ื™ึทื’ ื•ื•ืขื˜ ื–ื™ื™ืŸ ื’ืขื‘ื•ื™ื˜. ื•ื•ื™ ืึท ืจืขื–ื•ืœื˜ืึทื˜, ืขืก ื˜ื•ืจื ืก ืื•ื™ืก ืึทื– ืžื™ืจ ื”ืึธื‘ืŸ ืฉื•ื™ืŸ ืคืืจื’ืขืกืŸ ื•ื•ืขื’ืŸ ื“ื™ ืฆื™ืขืŸ ื‘ืขื˜ืŸ, ืื•ืŸ ื–ื™ื™ึทืŸ 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

ืคึผืึทืจืึทืžืขื˜ืขืจ 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 ื“ืืจืฃ ืฆื• ื•ื™ืกืžืขืงืŸ ืึทืœื˜ ื ืึธืžืขืŸ ืกืคึผื™ื™ืกืึทื–. ืคึฟืึทืจ ื‘ื™ื™ึทืฉืคึผื™ืœ, ืื•ื™ื‘ ื ืึทืžืขืกืคึผืึทืกืข ืื™ื– ื‘ืืฉืืคืŸ 3 ะดะฝั 1 ั‡ะฐั ืฆื•ืจื™ืง, ืื•ืŸ ื“ืขืจ ืคึผืึทืจืึทืžืขื˜ืขืจ ื™ื ื“ื™ืงื™ื™ืฅ 3 ะดะฝั, ื“ืขื ื ืึธืžืขืŸ ืคึผืœืึทืฅ ื•ื•ืขื˜ ื•ื•ืขืจืŸ ืื•ื™ืกื’ืขืžืขืงื˜. ืขืก ืื•ื™ืš ืึทืจื‘ืขื˜ ืื™ืŸ ื“ื™ ืคืึทืจืงืขืจื˜ ืจื™ื›ื˜ื•ื ื’ ืื•ื™ื‘ ื“ื™ ื ืึทืžืขืกืคึผืึทืกืข ืื™ื– ื‘ืืฉืืคืŸ 2 ะดะฝั 23 ั‡ะฐัะฐ ืฆื•ืจื™ืง, ืื•ืŸ ื“ืขืจ ืคึผืึทืจืึทืžืขื˜ืขืจ ื™ื ื“ื™ืงื™ื™ืฅ 3 ะดะฝั, ื“ืขื ื ืึธืžืขืŸ ืคึผืœืึทืฅ ื•ื•ืขื˜ ื ื™ื˜ ื–ื™ื™ืŸ ืื•ื™ืกื’ืขืžืขืงื˜.

ืขืก ืื™ื– ื ืึธืš ืื™ื™ืŸ ืคึผืึทืจืึทืžืขื˜ืขืจ, ืขืก ืื™ื– ืคืึทืจืึทื ื˜ื•ื•ืึธืจื˜ืœืขืš ืคึฟืึทืจ ื•ื•ื™ ืึธืคื˜ ืฆื• ื™ื‘ืขืจืงื•ืงืŸ ืึทืœืข ื ืึทืžืขืกืคึผืึทืกืขืก ืื•ืŸ ื˜ืฉืขืง ืคึฟืึทืจ ื˜ืขื’ ืึธืŸ ื“ื™ืคึผืœื•ื™ืžืึทื ื˜ - ื˜ืฉืขืง ื™ืขื“ืขืจ ืžื™ื ื•ื˜. ื“ื•ืจืš ืคืขืœื™ืงื™ื™ึทื˜ ืขืก ืื™ื– ื’ืœื™ื™ึทืš 30 ะผะธะฝัƒั‚ะฐะผ.

ื•ื•ื™ ืขืก ื•ื•ืึธืจืงืก

ืื™ืŸ ืคื™ืจ, ืื™ืจ ื•ื•ืขื˜ ื“ืึทืจืคึฟืŸ:

  1. ื“ืึธืงืงืขืจ ืคึฟืึทืจ ืืจื‘ืขื˜ืŸ ืื™ืŸ ืึทืŸ ืืคื’ืขื–ื•ื ื“ืขืจื˜ ืกื•ื•ื™ื•ื•ืข.
  2. ืžื™ื ื™ืงื•ื‘ืข ื•ื•ืขื˜ ื›ืึทืคึผืŸ ืึท ืงื•ื‘ืขืจื ืขื˜ืขืก ืงื ื•ื™ืœ ืœืึธื•ืงืึทืœื™.
  3. kubectl - ื‘ืึทืคึฟืขืœืŸ ืฉื•ืจื” ืฆื•ื‘ื™ื ื“ ืคึฟืึทืจ ืงื ื•ื™ืœ ืคืึทืจื•ื•ืึทืœื˜ื•ื ื’.

ืžื™ืจ ื›ืึทืคึผืŸ ืึท ืงื•ื‘ืขืจื ืขื˜ืขืก ืงื ื•ื™ืœ ืœืึธื•ืงืึทืœื™:

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

ืืจืืคืงืืคื™ืข ืงืึทื ืคื™ื’ื™ืขืจื™ื™ืฉืึทื ื– ืคึฟืึทืจ ื“ื™ ืคึผืจืึธื“ื•ืงืฆื™ืข ืกื•ื•ื™ื•ื•ืข:

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

ื–ื™ื ื˜ ืคึผืจืึธื“ื•ืงืฆื™ืข ืงืึทื ืคื™ื’ื™ืขืจื™ื™ืฉืึทื ื– ื–ืขื ืขืŸ ืงืึทื ืคื™ื’ื™ืขืจื“ ืฆื• ืงืึธื ื˜ืจืึธืœื™ืจืŸ ืึทืœื˜ ื ืึธืžืขืŸ ืกืคึผื™ื™ืกืึทื–, ืื•ืŸ ืื•ื ื“ื–ืขืจ ื ื™ื™ ืื•ื™ืคืฉื˜ื™ื™ืŸ ืงื ื•ื™ืœ ื˜ื•ื˜ ื ื™ืฉื˜ ื”ืึธื‘ืŸ ื–ื™ื™, ืžื™ืจ ื•ื•ืขืœืŸ ืคืึทืจื‘ื™ื™ึทื˜ืŸ ื“ื™ ืกื•ื•ื™ื•ื•ืข ื‘ื™ื™ึทื˜ืขื•ื•ื“ื™ืง IS_DEBUG ืื•ื™ืฃ true. ืžื™ื˜ ื“ืขื ื•ื•ืขืจื˜ ื“ืขืจ ืคึผืึทืจืึทืžืขื˜ืขืจ afterDaysWithoutDeploy ืื™ื– ื ื™ืฉื˜ ื’ืขื ื•ืžืขืŸ ืื™ืŸ ื—ืฉื‘ื•ืŸ ืื•ืŸ ื ืึทืžืขืกืคึผืึทืกืขืก ื–ืขื ืขืŸ ื ื™ืฉื˜ ืึธืคึผื’ืขืฉื˜ืขืœื˜ ืคึฟืึทืจ ื˜ืขื’ ืึธืŸ ืฆืขื•ื•ื™ืงืœืขืŸ, ื‘ืœื•ื™ื– ืคึฟืึทืจ ื“ื™ ืคึผืึทืกื™ืจื•ื ื’ ืคื•ืŸ ื“ื™ ืกื•ื‘ืกื˜ืจื™ื ื’ (-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

ื“ื™ ืงืึทื ืคื™ื’ื™ืขืจื™ื™ืฉืึทื ื– ืึธื ื•ื•ื™ื™ึทื–ืŸ ืฆื• ื–ื•ื›ืŸ ืคึฟืึทืจ ื ืึธืžืขืŸ ืกืคึผื™ื™ืกืึทื– ืžื™ื˜ ืึท ืกื•ื‘ืกื˜ืจื™ื ื’ -pr- ืึทืžืึธืœ ื™ืขื“ืขืจ 1 ะผะธะฝัƒั‚ัƒ.:

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

ื“ืขืจ ืึธืคึผืขืจืึทื˜ืึธืจ ื”ืื˜ ืืคื’ืขืจื•ืคืŸ ืื•ืŸ ืื™ื– ื’ืจื™ื™ื˜ ืฆื• ืงืึธื ื˜ืจืึธืœื™ืจืŸ ื“ื™ ื ืึธืžืขืŸ ืกืคึผื™ื™ืกืึทื–:

$ 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, ืžื™ื˜ ืฆื•ื•ื™ื™ ื ืึธืžืขืŸ ืกืคึผื™ื™ืกืึทื– (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, ื ืึธืžืขืŸ ืกืคึผื™ื™ืกืึทื– 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. ื•ื™ืกืžืขืงืŸ ืฉื˜ืจื™ืš ืฆื•ื•ื™ื™ึทื’ ื‘ืขืฉืึทืก ืงืขืกื™ื™ื“ืขืจื“ื™ืง ื™ื ืึทื’ืจื™ื™ืฉืึทืŸ ื‘ื•ื™ืขืŸ ืคื•ืŸ ื‘ืขืœ ืฆื•ื•ื™ื™ึทื’.

    • ืฆื• ื˜ืึธืŸ ื“ืึธืก, ืื™ืจ ื“ืึทืจืคึฟืŸ ืฆื• ื•ื•ื™ืกืŸ ื•ื•ืึธืก ืฆื™ืขืŸ ื‘ืขื˜ืŸ ืฉื™ื™ืš ืฆื• ื“ื™ ื™ื‘ืขืจื’ืขื‘ืŸ ื•ื•ืึธืก ืื™ื– ื’ืขื‘ื•ื™ื˜. ื–ื™ื ื˜ ื“ื™ ืฉื˜ืจื™ืš ืฆื•ื•ื™ื™ึทื’ ื ืึทืžืขืกืคึผืึทืกืข ื›ึผื•ืœืœ ื“ื™ ืฆื™ืขืŸ ื‘ืขื˜ืŸ ื™ื“ืขื ื˜ื™ืคื™ืขืจ - ื–ื™ื™ืŸ ื ื•ืžืขืจ, ืึธื“ืขืจ ื“ื™ ื ืึธืžืขืŸ ืคื•ืŸ ื“ื™ ืฆื•ื•ื™ื™ึทื’, ื“ื™ ืื™ื“ืขื ื˜ื™ื˜ืขื˜ ื•ื•ืขื˜ ืฉื˜ืขื ื“ื™ืง ื–ื™ื™ืŸ ืกืคึผืขืกื™ืคื™ืขื“ ืื™ืŸ ื“ื™ ื™ื‘ืขืจื’ืขื‘ืŸ.
    • ืžืึทืกื˜ืขืจ ืฆื•ื•ื™ื™ึทื’ ื‘ื•ื™ืขืŸ ื–ืขื ืขืŸ ืคื™ื™ืœื™ื ื’. ืคึฟืึทืจ ื‘ื™ื™ึทืฉืคึผื™ืœ, ืื™ืจ ื”ืึธื‘ืŸ ื“ื™ ืคืืœื’ืขื ื“ืข ืกื˜ืึทื’ืขืก: ืืจืืคืงืืคื™ืข ื“ื™ ืคึผืจื•ื™ืขืงื˜, ืœื•ื™ืคืŸ ื˜ืขืกืฅ, ื‘ื•ื™ืขืŸ ื“ื™ ืคึผืจื•ื™ืขืงื˜, ืžืึทื›ืŸ ืึท ืžืขืœื“ื•ื ื’, ืฉื™ืงืŸ ื ืึธื•ื˜ืึทืคืึทืงื™ื™ืฉืึทื ื–, ื•ื™ืกืžืขืงืŸ ื“ื™ ืฉื˜ืจื™ืš ืฆื•ื•ื™ื™ึทื’ ืคื•ืŸ ื“ื™ ืœืขืฆื˜ืข ืฆื™ืขืŸ ื‘ืขื˜ืŸ. ืื•ื™ื‘ ื“ื™ ื‘ื•ื™ืขืŸ ืคื™ื™ืœื– ื•ื•ืขืŸ ืื™ืจ ืฉื™ืงืŸ ืึท ืึธื ื–ืึธื’, ืื™ืจ ื•ื•ืขื˜ ื”ืึธื‘ืŸ ืฆื• ื•ื™ืกืžืขืงืŸ ืึทืœืข ืจืขืกื•ืจืกืŸ ืื™ืŸ ื“ืขื ืงื ื•ื™ืœ ืžืึทื ื™ื•ืึทืœื™.
    • ืึธืŸ ื’ืขื”ืขืจื™ืง ืงืึธื ื˜ืขืงืกื˜, ื“ื™ืœื™ื˜ื™ื ื’ ืฉื˜ืจื™ืš ืฆื•ื•ื™ื™ื’ืŸ ืื™ืŸ ื“ื™ ื‘ืขืœ ื‘ื•ื™ืขืŸ ืื™ื– ื ื™ืฉื˜ ืงืœืึธืจ ื•ื•ื™ ื“ืขืจ ื˜ืึธื’.

  2. ื ื™ืฆืŸ ื•ื•ืขื‘ื”ืึธืึธืงืก (ื‘ื™ื™ึทืฉืคึผื™ืœ).

    • ื“ืึธืก ืงืขืŸ ื ื™ืฉื˜ ื–ื™ื™ืŸ ื“ื™ื™ืŸ ืฆื•ื’ืึทื ื’. ืคึฟืึทืจ ื‘ื™ื™ึทืฉืคึผื™ืœ, ืื™ืŸ ื“ื–ืฉืขื ืงื™ื ืก, ื‘ืœื•ื™ื– ืื™ื™ืŸ ื˜ื™ืคึผ ืคื•ืŸ ืจืขืจื  - ืœื™ื ื™ืข ืฉื˜ื™ืฆื˜ ื“ื™ ืคื™ื™ื™ืงื™ื™ื˜ ืฆื• ืจืึทื˜ืขื•ื•ืขืŸ ื–ื™ื™ึทืŸ ืงืึทื ืคื™ื’ื™ืขืจื™ื™ืฉืึทื ื– ืื™ืŸ ื“ื™ ืžืงื•ืจ ืงืึธื“. ื•ื•ืขืŸ ืื™ืจ ื ื•ืฆืŸ ื•ื•ืขื‘ื”ืึธืึธืงืก, ืื™ืจ ื“ืึทืจืคึฟืŸ ืฆื• ืฉืจื™ื™ึทื‘ืŸ ื“ื™ื™ืŸ ืื™ื™ื’ืขื ืข ืฉืจื™ืคื˜ ืฆื• ืคึผืจืึธืฆืขืก ื–ื™ื™. ื“ืขื ืฉืจื™ืคื˜ ื•ื•ืขื˜ ื–ื™ื™ืŸ ื’ืขืฉื˜ืขืœื˜ ืื™ืŸ ื“ื™ Jenkins ืฆื•ื‘ื™ื ื“, ื•ื•ืึธืก ืื™ื– ืฉื•ื•ืขืจ ืฆื• ื˜ื™ื™ึทื ืขืŸ.

  3. ืฆื• ืฉืจื™ื™ื‘ืŸ Cronjob ืื•ืŸ ืœื™ื™ื’ืŸ ืึท ืงื•ื‘ืขืจื ืขื˜ืขืก ืงื ื•ื™ืœ.

    • ืกืคึผืขื ื“ื™ื ื’ ืฆื™ื™ื˜ ืื•ื™ืฃ ืฉืจื™ื™ื‘ืŸ ืื•ืŸ ืฉื˜ื™ืฆืŸ.
    • ื“ืขืจ ืึธืคึผืขืจืึทื˜ืึธืจ ืฉื•ื™ืŸ ืึทืจื‘ืขื˜ ืื™ืŸ ืึท ืขื ืœืขืš ื ื•ืกื—, ืื™ื– ื“ืึทืงื™ื•ืžืขื ื˜ืึทื“ ืื•ืŸ ื’ืขืฉื˜ื™ืฆื˜.

ื“ืื ืง ืื™ืจ ืคึฟืึทืจ ื“ื™ื™ืŸ ื•ืคืžืขืจืงื–ืึทืžืงื™ื™ื˜ ืฆื• ื“ืขื ืึทืจื˜ื™ืงืœ. ืœื™ื ืง ืฆื• ื“ื™ ืคึผืจื•ื™ืขืงื˜ ืื•ื™ืฃ Github.

ืžืงื•ืจ: www.habr.com

ืœื™ื™ื’ืŸ ืึท ื‘ืึทืžืขืจืงื•ื ื’