Κατάργηση ενός ξεπερασμένου κλάδου χαρακτηριστικών σε ένα σύμπλεγμα Kubernetes

Κατάργηση ενός ξεπερασμένου κλάδου χαρακτηριστικών σε ένα σύμπλεγμα Kubernetes

Γεια σας! Κλάδος χαρακτηριστικών (γνωστός και ως προεπισκόπηση ανάπτυξης, εφαρμογή ελέγχου) - αυτό συμβαίνει όταν αναπτύσσεται όχι μόνο ο κύριος κλάδος, αλλά και κάθε αίτημα έλξης σε μια μοναδική διεύθυνση 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
...

Για μια διακλάδωση χαρακτηριστικών, δημιουργείται ένας χώρος ονομάτων με το αναγνωριστικό του (για παράδειγμα, τον αριθμό αιτήματος έλξης) και κάποιο είδος προθέματος/postfix (για παράδειγμα, -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 (μια εφαρμογή που έχει πρόσβαση σε πόρους συμπλέγματος), σύνδεσμος για το έργο στο 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. Στο build, εκτελούνται τα linters και/ή οι δοκιμές.
  3. Οι διαμορφώσεις αιτημάτων έλξης Kubernetes δημιουργούνται εν κινήσει (για παράδειγμα, ο αριθμός του εισάγεται στο έτοιμο πρότυπο).
  4. Χρησιμοποιώντας την εφαρμογή kubectl, προστίθενται διαμορφώσεις στο σύμπλεγμα (deploy).
  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

Παράμετρος namespaceSubstring απαιτείται για το φιλτράρισμα των χώρων ονομάτων για αιτήματα έλξης από άλλους χώρους ονομάτων. Για παράδειγμα, εάν το σύμπλεγμα έχει τους ακόλουθους χώρους ονομάτων: 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 дня, αυτός ο χώρος ονομάτων δεν θα διαγραφεί.

Υπάρχει μια ακόμη παράμετρος, είναι υπεύθυνη για το πόσο συχνά γίνεται σάρωση όλων των χώρων ονομάτων και έλεγχος για ημέρες χωρίς ανάπτυξη - checkEveryMiutes. Από προεπιλογή ισούται με 30 минутам.

Πώς λειτουργεί;

Στην πράξη, θα χρειαστείτε:

  1. Λιμενεργάτης για εργασία σε απομονωμένο περιβάλλον.
  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".

Λήψη διαμορφώσεων για το περιβάλλον παραγωγής:

$ 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. Χρήση webhooks (παράδειγμα).

    • Αυτή μπορεί να μην είναι η προσέγγισή σας. Για παράδειγμα, σε Jenkins, μόνο ένας τύπος αγωγού υποστηρίζει τη δυνατότητα αποθήκευσης των διαμορφώσεών του στον πηγαίο κώδικα. Όταν χρησιμοποιείτε webhook, πρέπει να γράψετε το δικό σας σενάριο για να τα επεξεργαστείτε. Αυτό το σενάριο θα πρέπει να τοποθετηθεί στη διεπαφή Jenkins, η οποία είναι δύσκολο να διατηρηθεί.

  3. Γράψτε Cronjob και προσθέστε ένα σύμπλεγμα Kubernetes.

    • Αφιερώστε χρόνο στη συγγραφή και υποστήριξη.
    • Ο χειριστής λειτουργεί ήδη με παρόμοιο στυλ, είναι τεκμηριωμένος και υποστηρίζεται.

Σας ευχαριστώ για την προσοχή σας στο άρθρο. Σύνδεσμος με το έργο στο Github.

Πηγή: www.habr.com

Προσθέστε ένα σχόλιο