werf - το εργαλείο μας για CI / CD στο Kubernetes (επισκόπηση και αναφορά βίντεο)

27 Μαΐου στην κεντρική αίθουσα του συνεδρίου DevOpsConf 2019, που πραγματοποιήθηκε στο πλαίσιο του φεστιβάλ RIT++ 2019, ως μέρος της ενότητας "Συνεχής Παράδοση", δόθηκε μια αναφορά "werf - το εργαλείο μας για CI/CD στο Kubernetes". Μιλάει για αυτά προβλήματα και προκλήσεις που αντιμετωπίζουν όλοι κατά την ανάπτυξη στο Kubernetes, καθώς και για αποχρώσεις που μπορεί να μην γίνουν αμέσως αντιληπτές. Αναλύοντας πιθανές λύσεις, δείχνουμε πώς αυτό υλοποιείται σε ένα εργαλείο ανοιχτού κώδικα werf.

Από την παρουσίαση, το βοηθητικό πρόγραμμα μας (παλαιότερα γνωστό ως dapp) έχει φτάσει σε ένα ιστορικό ορόσημο 1000 αστέρια στο GitHub — ελπίζουμε ότι η αυξανόμενη κοινότητα χρηστών του θα κάνει τη ζωή πιο εύκολη για πολλούς μηχανικούς DevOps.

werf - το εργαλείο μας για CI / CD στο Kubernetes (επισκόπηση και αναφορά βίντεο)

Παρουσιάζουμε λοιπόν βίντεο της έκθεσης (~47 λεπτά, πολύ πιο κατατοπιστικό από το άρθρο) και το κύριο απόσπασμα από αυτό σε μορφή κειμένου. Πηγαίνω!

Παράδοση κωδικού στην Kubernetes

Η συζήτηση δεν θα είναι πλέον για το werf, αλλά για το CI/CD στο Kubernetes, υπονοώντας ότι το λογισμικό μας είναι συσκευασμένο σε δοχεία Docker (Μίλησα για αυτό στο Έκθεση 2016), και τα K8 θα χρησιμοποιηθούν για την εκτέλεση του στην παραγωγή (περισσότερα για αυτό στο 2017 έτος).

Πώς είναι η παράδοση στο Kubernetes;

  • Υπάρχει ένα αποθετήριο Git με τον κώδικα και οδηγίες για την κατασκευή του. Η εφαρμογή είναι ενσωματωμένη σε μια εικόνα Docker και δημοσιεύεται στο Μητρώο Docker.
  • Το ίδιο αποθετήριο περιέχει επίσης οδηγίες για τον τρόπο ανάπτυξης και εκτέλεσης της εφαρμογής. Στο στάδιο της ανάπτυξης, αυτές οι οδηγίες αποστέλλονται στο Kubernetes, το οποίο λαμβάνει την επιθυμητή εικόνα από το μητρώο και την εκκινεί.
  • Επιπλέον, συνήθως υπάρχουν δοκιμές. Μερικά από αυτά μπορούν να γίνουν κατά τη δημοσίευση μιας εικόνας. Μπορείτε επίσης (ακολουθώντας τις ίδιες οδηγίες) να αναπτύξετε ένα αντίγραφο της εφαρμογής (σε ξεχωριστό χώρο ονομάτων του K8 ή ένα ξεχωριστό σύμπλεγμα) και να εκτελέσετε δοκιμές εκεί.
  • Τέλος, χρειάζεστε ένα σύστημα CI που λαμβάνει συμβάντα από το Git (ή κλικ κουμπιών) και καλεί όλα τα καθορισμένα στάδια: δημιουργία, δημοσίευση, ανάπτυξη, δοκιμή.

werf - το εργαλείο μας για CI / CD στο Kubernetes (επισκόπηση και αναφορά βίντεο)

Υπάρχουν μερικές σημαντικές σημειώσεις εδώ:

  1. Γιατί έχουμε αμετάβλητη υποδομή (αμετάβλητη υποδομή), την εικόνα της εφαρμογής που χρησιμοποιείται σε όλα τα στάδια (σκηνοθεσία, παραγωγή κ.λπ.), πρέπει να υπάρχει ένα. Μίλησα για αυτό με περισσότερες λεπτομέρειες και με παραδείγματα. εδώ.
  2. Επειδή ακολουθούμε την υποδομή ως προσέγγιση κώδικα (IaC), ο κωδικός εφαρμογής, οι οδηγίες συναρμολόγησης και εκκίνησης θα πρέπει να είναι ακριβώς σε ένα αποθετήριο. Για περισσότερες πληροφορίες σχετικά με αυτό, βλ την ίδια έκθεση.
  3. Αλυσίδα παράδοσης (διανομή) το βλέπουμε συνήθως ως εξής: η εφαρμογή συναρμολογήθηκε, δοκιμάστηκε, κυκλοφόρησε (στάδιο απελευθέρωσης) και αυτό είναι - η παράδοση πραγματοποιήθηκε. Αλλά στην πραγματικότητα, ο χρήστης παίρνει αυτό που διαθέσατε, όχι τότε όταν το παραδώσατε στην παραγωγή, και όταν μπόρεσε να πάει εκεί και αυτή η παραγωγή λειτούργησε. Πιστεύω λοιπόν ότι η αλυσίδα παράδοσης τελειώνει μόνο στο επιχειρησιακό στάδιο (τρέξιμο), ή ακριβέστερα, ακόμη και τη στιγμή που ο κωδικός αφαιρέθηκε από την παραγωγή (αντικαθιστώντας τον με νέο).

Ας επιστρέψουμε στο παραπάνω σχήμα παράδοσης στο Kubernetes: το εφευρέθηκε όχι μόνο εμείς, αλλά κυριολεκτικά όλοι όσοι ασχολήθηκαν με αυτό το πρόβλημα. Στην πραγματικότητα, αυτό το μοτίβο ονομάζεται πλέον GitOps (μπορείτε να διαβάσετε περισσότερα για τον όρο και τις ιδέες πίσω από αυτόν εδώ). Ας δούμε τα στάδια του σχήματος.

Κατασκευή σκηνής

Φαίνεται ότι μπορείτε να μιλήσετε για τη δημιουργία εικόνων Docker το 2019, όταν όλοι ξέρουν πώς να γράφουν Dockerfiles και να τρέχουν docker build?.. Εδώ είναι οι αποχρώσεις που θα ήθελα να δώσω προσοχή:

  1. Βάρος εικόνας έχει σημασία, άρα χρησιμοποιήστε πολλαπλών σταδίωνγια να αφήσετε στην εικόνα μόνο την εφαρμογή που είναι πραγματικά απαραίτητη για την επέμβαση.
  2. Αριθμός στρώσεων πρέπει να ελαχιστοποιηθεί με το συνδυασμό αλυσίδων από RUN-εντολές σύμφωνα με το νόημα.
  3. Ωστόσο, αυτό προσθέτει προβλήματα αποσφαλμάτωση, γιατί όταν το συγκρότημα κολλάει, πρέπει να βρείτε τη σωστή εντολή από την αλυσίδα που προκάλεσε το πρόβλημα.
  4. Ταχύτητα συναρμολόγησης σημαντικό γιατί θέλουμε να παρουσιάσουμε γρήγορα τις αλλαγές και να δούμε τα αποτελέσματα. Για παράδειγμα, δεν θέλετε να δημιουργείτε ξανά εξαρτήσεις στις βιβλιοθήκες γλωσσών κάθε φορά που δημιουργείτε μια εφαρμογή.
  5. Συχνά από ένα αποθετήριο Git που χρειάζεστε πολλές εικόνες, το οποίο μπορεί να επιλυθεί με ένα σύνολο Dockerfiles (ή ονομασμένα στάδια σε ένα αρχείο) και ένα σενάριο Bash με τη διαδοχική συναρμολόγηση τους.

Αυτή ήταν μόνο η κορυφή του παγόβουνου που όλοι αντιμετωπίζουν. Υπάρχουν όμως και άλλα προβλήματα, συγκεκριμένα:

  1. Συχνά στο στάδιο της συναρμολόγησης χρειαζόμαστε κάτι βουνό (για παράδειγμα, αποθηκεύστε προσωρινά το αποτέλεσμα μιας εντολής όπως το apt σε έναν κατάλογο τρίτου μέρους).
  2. Θέλουμε Πιθανό αντί να γράφει με κέλυφος.
  3. Θέλουμε κατασκευή χωρίς Docker (γιατί χρειαζόμαστε μια πρόσθετη εικονική μηχανή στην οποία πρέπει να ρυθμίσουμε τα πάντα για αυτό, όταν έχουμε ήδη ένα σύμπλεγμα Kubernetes στο οποίο μπορούμε να τρέξουμε κοντέινερ;).
  4. Παράλληλη συναρμολόγηση, το οποίο μπορεί να γίνει κατανοητό με διαφορετικούς τρόπους: διαφορετικές εντολές από το Dockerfile (αν χρησιμοποιείται πολλαπλά στάδια), πολλές δεσμεύσεις του ίδιου αποθετηρίου, πολλά Dockerfiles.
  5. Κατανεμημένη συναρμολόγηση: Θέλουμε να μαζεύουμε πράγματα σε λοβούς που είναι «εφήμερα» γιατί Η κρυφή τους μνήμη εξαφανίζεται, πράγμα που σημαίνει ότι πρέπει να αποθηκευτεί κάπου χωριστά.
  6. Τέλος, ονόμασα την κορυφή των επιθυμιών αυτομαγική: Θα ήταν ιδανικό να πάτε στο αποθετήριο, να πληκτρολογήσετε κάποια εντολή και να λάβετε μια έτοιμη εικόνα, συναρμολογημένη με κατανόηση του πώς και τι πρέπει να κάνετε σωστά. Ωστόσο, προσωπικά δεν είμαι σίγουρος ότι όλες οι αποχρώσεις μπορούν να προβλεφθούν με αυτόν τον τρόπο.

Και εδώ είναι τα έργα:

  • moby/buildkit — ένας κατασκευαστής από την Docker Inc (ήδη ενσωματωμένος στις τρέχουσες εκδόσεις του Docker), ο οποίος προσπαθεί να λύσει όλα αυτά τα προβλήματα.
  • kaniko — ένα πρόγραμμα δημιουργίας από την Google που σας επιτρέπει να δημιουργείτε χωρίς Docker.
  • Buildpacks.io — Η προσπάθεια του CNCF να κάνει αυτόματη μαγεία και, ειδικότερα, μια ενδιαφέρουσα λύση με rebase για επίπεδα.
  • και ένα σωρό άλλα βοηθητικά προγράμματα, όπως π.χ buildah, γνήσια εργαλεία/img...

...και δείτε πόσα αστέρια έχουν στο GitHub. Δηλαδή, από τη μια πλευρά, docker build υπάρχει και μπορεί να κάνει κάτι, αλλά στην πραγματικότητα το θέμα δεν έχει λυθεί πλήρως - απόδειξη αυτού είναι η παράλληλη ανάπτυξη εναλλακτικών συλλεκτών, καθένας από τους οποίους λύνει κάποιο μέρος των προβλημάτων.

Συνέλευση στο werf

Έτσι καταλήξαμε werf (προηγουμένως διάσημο όπως το dapp) — Ένα βοηθητικό πρόγραμμα ανοιχτού κώδικα από την εταιρεία Flant, το οποίο φτιάχνουμε εδώ και πολλά χρόνια. Όλα ξεκίνησαν πριν από 5 χρόνια με σενάρια Bash που βελτιστοποίησαν τη συναρμολόγηση των Dockerfiles και τα τελευταία 3 χρόνια πραγματοποιήθηκε πλήρης ανάπτυξη στο πλαίσιο ενός έργου με το δικό του αποθετήριο Git (πρώτα στο Ruby και μετά ξαναγραφεί σε Go, και ταυτόχρονα μετονομάστηκε). Ποια προβλήματα συναρμολόγησης λύνονται στο werf;

werf - το εργαλείο μας για CI / CD στο Kubernetes (επισκόπηση και αναφορά βίντεο)

Τα προβλήματα που σκιάζονται με μπλε έχουν ήδη υλοποιηθεί, η παράλληλη κατασκευή έγινε στον ίδιο οικοδεσπότη και τα θέματα που επισημαίνονται με κίτρινο σχεδιάζεται να ολοκληρωθούν μέχρι το τέλος του καλοκαιριού.

Στάδιο δημοσίευσης στο μητρώο (δημοσίευση)

Καλέσαμε docker push... - τι μπορεί να είναι δύσκολο για τη μεταφόρτωση μιας εικόνας στο μητρώο; Και τότε τίθεται το ερώτημα: "Τι ετικέτα να βάλω στην εικόνα;" Προκύπτει για τον λόγο που έχουμε Gitflow (ή άλλη στρατηγική Git) και Kubernetes, και η βιομηχανία προσπαθεί να διασφαλίσει ότι αυτό που συμβαίνει στο Kubernetes ακολουθεί αυτό που συμβαίνει στο Git. Άλλωστε, το Git είναι η μόνη μας πηγή αλήθειας.

Τι είναι τόσο δύσκολο σε αυτό; Εξασφάλιση αναπαραγωγιμότητας: από ένα commit στο Git, το οποίο είναι αμετάβλητο στη φύση του (αμετάβλητος), σε μια εικόνα Docker, η οποία θα πρέπει να διατηρηθεί η ίδια.

Είναι επίσης σημαντικό για εμάς καθορίσει την προέλευση, γιατί θέλουμε να καταλάβουμε από ποιο commit δημιουργήθηκε η εφαρμογή που τρέχει στο Kubernetes (τότε μπορούμε να κάνουμε διαφοροποιήσεις και παρόμοια πράγματα).

Στρατηγικές προσθήκης ετικετών

Το πρώτο είναι απλό git tag. Έχουμε ένα μητρώο με μια εικόνα με ετικέτα 1.0. Η Kubernetes έχει σκηνή και παραγωγή, όπου ανεβάζεται αυτή η εικόνα. Στο Git κάνουμε commits και κάποια στιγμή κάνουμε tag 2.0. Το συλλέγουμε σύμφωνα με τις οδηγίες από το αποθετήριο και το τοποθετούμε στο μητρώο με την ετικέτα 2.0. Το ανοίγουμε στη σκηνή και, αν όλα πάνε καλά, τότε στην παραγωγή.

werf - το εργαλείο μας για CI / CD στο Kubernetes (επισκόπηση και αναφορά βίντεο)

Το πρόβλημα με αυτήν την προσέγγιση είναι ότι πρώτα ορίσαμε την ετικέτα, και μόνο μετά τη δοκιμάσαμε και την κυκλοφόρησε. Γιατί; Πρώτον, είναι απλώς παράλογο: εκδίδουμε μια έκδοση λογισμικού που δεν έχουμε καν δοκιμάσει ακόμα (δεν μπορούμε να κάνουμε διαφορετικά, γιατί για να ελέγξουμε, πρέπει να βάλουμε μια ετικέτα). Δεύτερον, αυτή η διαδρομή δεν είναι συμβατή με το Gitflow.

Η δεύτερη επιλογή - git commit + ετικέτα. Ο κύριος κλάδος έχει μια ετικέτα 1.0; για αυτό στο μητρώο - μια εικόνα που αναπτύσσεται στην παραγωγή. Επιπλέον, το σύμπλεγμα Kubernetes έχει περιγράμματα προεπισκόπησης και σταδιοποίησης. Στη συνέχεια ακολουθούμε το Gitflow: στον κύριο κλάδο για ανάπτυξη (develop) δημιουργούμε νέες δυνατότητες, με αποτέλεσμα να γίνει δέσμευση με το αναγνωριστικό #c1. Το συλλέγουμε και το δημοσιεύουμε στο μητρώο χρησιμοποιώντας αυτό το αναγνωριστικό (#c1). Με το ίδιο αναγνωριστικό ανοίγουμε για προεπισκόπηση. Το ίδιο κάνουμε και με τις δεσμεύσεις #c2 и #c3.

Όταν καταλάβαμε ότι υπάρχουν αρκετά χαρακτηριστικά, αρχίζουμε να σταθεροποιούμε τα πάντα. Δημιουργήστε ένα υποκατάστημα στο Git release_1.1 (στη βάση #c3 του develop). Δεν χρειάζεται να συλλέξετε αυτήν την έκδοση, γιατί... αυτό έγινε στο προηγούμενο βήμα. Επομένως, μπορούμε απλά να το προωθήσουμε στη σκηνή. Διορθώνουμε σφάλματα #c4 και παρομοίως να αναπτυχθεί στη σκηνή. Παράλληλα, βρίσκεται σε εξέλιξη η ανάπτυξη develop, από όπου λαμβάνονται περιοδικά αλλαγές release_1.1. Κάποια στιγμή, λαμβάνουμε ένα commit μεταγλωττισμένο και ανεβασμένο στο staging, με το οποίο είμαστε ευχαριστημένοι (#c25).

Στη συνέχεια συγχωνεύουμε (με γρήγορη προώθηση) τον κλάδο απελευθέρωσης (release_1.1) στο master. Βάζουμε μια ετικέτα με τη νέα έκδοση σε αυτό το commit (1.1). Αλλά αυτή η εικόνα έχει ήδη συλλεχθεί στο μητρώο, επομένως για να μην τη συλλέξουμε ξανά, απλώς προσθέτουμε μια δεύτερη ετικέτα στην υπάρχουσα εικόνα (τώρα έχει ετικέτες στο μητρώο #c25 и 1.1). Μετά από αυτό, το βγάζουμε στην παραγωγή.

Υπάρχει ένα μειονέκτημα ότι μόνο μία εικόνα μεταφορτώνεται στη σκηνή (#c25), και στην παραγωγή είναι κάπως διαφορετικό (1.1), αλλά γνωρίζουμε ότι «φυσικά» πρόκειται για την ίδια εικόνα από το μητρώο.

werf - το εργαλείο μας για CI / CD στο Kubernetes (επισκόπηση και αναφορά βίντεο)

Το πραγματικό μειονέκτημα είναι ότι δεν υπάρχει υποστήριξη για δεσμεύσεις συγχώνευσης, πρέπει να κάνετε fast-forward.

Μπορούμε να πάμε παρακάτω και να κάνουμε ένα κόλπο... Ας δούμε ένα παράδειγμα απλού Dockerfile:

FROM ruby:2.3 as assets
RUN mkdir -p /app
WORKDIR /app
COPY . ./
RUN gem install bundler && bundle install
RUN bundle exec rake assets:precompile
CMD bundle exec puma -C config/puma.rb

FROM nginx:alpine
COPY --from=assets /app/public /usr/share/nginx/www/public

Ας δημιουργήσουμε ένα αρχείο από αυτό σύμφωνα με την ακόλουθη αρχή:

  • SHA256 από τα αναγνωριστικά των εικόνων που χρησιμοποιούνται (ruby:2.3 и nginx:alpine), τα οποία είναι αθροίσματα ελέγχου του περιεχομένου τους·
  • όλες οι ομάδες (RUN, CMD και ούτω καθεξής.);
  • SHA256 από αρχεία που προστέθηκαν.

... και πάρτε το άθροισμα ελέγχου (και πάλι SHA256) από ένα τέτοιο αρχείο. Αυτό υπογραφή όλα όσα καθορίζουν τα περιεχόμενα της εικόνας Docker.

werf - το εργαλείο μας για CI / CD στο Kubernetes (επισκόπηση και αναφορά βίντεο)

Ας επιστρέψουμε στο διάγραμμα και αντί για δεσμεύσεις θα χρησιμοποιήσουμε τέτοιες υπογραφές, δηλ. επισημάνετε εικόνες με υπογραφές.

werf - το εργαλείο μας για CI / CD στο Kubernetes (επισκόπηση και αναφορά βίντεο)

Τώρα, όταν είναι απαραίτητο, για παράδειγμα, η συγχώνευση αλλαγών από έκδοση σε κύρια, μπορούμε να κάνουμε μια πραγματική δέσμευση συγχώνευσης: θα έχει διαφορετικό αναγνωριστικό, αλλά την ίδια υπογραφή. Με το ίδιο αναγνωριστικό θα διαθέσουμε την εικόνα στην παραγωγή.

Το μειονέκτημα είναι ότι τώρα δεν θα είναι δυνατό να προσδιοριστεί τι είδους δέσμευση ωθήθηκε στην παραγωγή - τα αθροίσματα ελέγχου λειτουργούν μόνο προς μία κατεύθυνση. Αυτό το πρόβλημα επιλύεται με ένα επιπλέον επίπεδο με μεταδεδομένα - θα σας πω περισσότερα αργότερα.

Προσθήκη ετικετών σε werf

Στο werf προχωρήσαμε ακόμα παραπέρα και ετοιμαζόμαστε να κάνουμε μια κατανεμημένη κατασκευή με μια κρυφή μνήμη που δεν είναι αποθηκευμένη σε ένα μηχάνημα... Έτσι, χτίζουμε δύο τύπους εικόνων Docker, τις ονομάζουμε στάδιο и εικόνα.

Το αποθετήριο werf Git αποθηκεύει οδηγίες ειδικές για το build που περιγράφουν τα διαφορετικά στάδια της κατασκευής (πριν την Εγκατάσταση, εγκαθιστώ, πριν από την εγκατάσταση, setup). Συλλέγουμε την εικόνα του πρώτου σταδίου με μια υπογραφή που ορίζεται ως το άθροισμα ελέγχου των πρώτων βημάτων. Στη συνέχεια προσθέτουμε τον πηγαίο κώδικα, για τη νέα εικόνα σταδίου υπολογίζουμε το άθροισμα ελέγχου της... Οι πράξεις αυτές επαναλαμβάνονται για όλα τα στάδια, με αποτέλεσμα να λαμβάνουμε ένα σύνολο εικόνων σταδίου. Στη συνέχεια φτιάχνουμε την τελική εικόνα, η οποία περιέχει και μεταδεδομένα για την προέλευσή της. Και επισημαίνουμε αυτήν την εικόνα με διαφορετικούς τρόπους (λεπτομέρειες αργότερα).

werf - το εργαλείο μας για CI / CD στο Kubernetes (επισκόπηση και αναφορά βίντεο)

Ας υποθέσουμε ότι μετά από αυτό εμφανίζεται μια νέα δέσμευση στην οποία έχει αλλάξει μόνο ο κωδικός της εφαρμογής. Τι θα συμβεί? Για αλλαγές κώδικα, θα δημιουργηθεί ένα patch και θα προετοιμαστεί μια νέα εικόνα σταδίου. Η υπογραφή του θα καθοριστεί ως το άθροισμα ελέγχου της παλιάς εικόνας της σκηνής και της νέας ενημέρωσης κώδικα. Μια νέα τελική εικόνα θα σχηματιστεί από αυτήν την εικόνα. Παρόμοια συμπεριφορά θα συμβεί με αλλαγές σε άλλα στάδια.

Έτσι, οι εικόνες σταδίου είναι μια κρυφή μνήμη που μπορεί να αποθηκευτεί κατανεμημένη και οι εικόνες που έχουν ήδη δημιουργηθεί από αυτήν μεταφορτώνονται στο Μητρώο Docker.

werf - το εργαλείο μας για CI / CD στο Kubernetes (επισκόπηση και αναφορά βίντεο)

Καθαρισμός του μητρώου

Δεν μιλάμε για τη διαγραφή επιπέδων που παρέμειναν να κρέμονται μετά από διαγραμμένες ετικέτες - αυτή είναι μια τυπική δυνατότητα του ίδιου του Μητρώου Docker. Μιλάμε για μια κατάσταση όπου συσσωρεύονται πολλές ετικέτες Docker και καταλαβαίνουμε ότι δεν χρειαζόμαστε πλέον κάποιες από αυτές, αλλά καταλαμβάνουν χώρο (ή/και πληρώνουμε γι' αυτό).

Ποιες είναι οι στρατηγικές καθαρισμού;

  1. Δεν μπορείς να κάνεις τίποτα μην καθαρίζεις. Μερικές φορές είναι πραγματικά πιο εύκολο να πληρώσετε λίγο για επιπλέον χώρο από το να ξετυλίξετε ένα τεράστιο κουβάρι ετικετών. Αλλά αυτό λειτουργεί μόνο μέχρι ένα ορισμένο σημείο.
  2. Πλήρης επαναφορά. Εάν διαγράψετε όλες τις εικόνες και δημιουργήσετε ξανά μόνο τις τρέχουσες στο σύστημα CI, ενδέχεται να προκύψει πρόβλημα. Εάν το κοντέινερ επανεκκινηθεί στην παραγωγή, θα φορτωθεί μια νέα εικόνα - μια εικόνα που δεν έχει δοκιμαστεί ακόμη από κανέναν. Αυτό σκοτώνει την ιδέα της αμετάβλητης υποδομής.
  3. Μπλε πράσινο. Ένα μητρώο άρχισε να ξεχειλίζει - ανεβάζουμε εικόνες σε ένα άλλο. Το ίδιο πρόβλημα με την προηγούμενη μέθοδο: σε ποιο σημείο μπορείτε να διαγράψετε το μητρώο που έχει αρχίσει να ξεχειλίζει;
  4. Με το καιρο. Να διαγραφούν όλες οι εικόνες παλαιότερες από 1 μήνα; Σίγουρα όμως θα υπάρξει μια υπηρεσία που δεν έχει ενημερωθεί εδώ και ένα μήνα...
  5. Μη αυτόματα καθορίστε τι μπορεί ήδη να διαγραφεί.

Υπάρχουν δύο πραγματικά βιώσιμες επιλογές: μην καθαρίζετε ή συνδυασμό μπλε-πράσινου + χειροκίνητα. Στην τελευταία περίπτωση, μιλάμε για το εξής: όταν καταλάβετε ότι είναι ώρα να καθαρίσετε το μητρώο, δημιουργείτε ένα νέο και προσθέτετε όλες τις νέες εικόνες σε αυτό κατά τη διάρκεια, για παράδειγμα, ενός μήνα. Και μετά από ένα μήνα, δείτε ποια pod στο Kubernetes εξακολουθούν να χρησιμοποιούν το παλιό μητρώο και μεταφέρετέ τα επίσης στο νέο μητρώο.

Σε τι φτάσαμε werf? Συλλέγουμε:

  1. Git head: όλες οι ετικέτες, όλοι οι κλάδοι - υποθέτοντας ότι χρειαζόμαστε ό,τι έχει επισημανθεί στο Git στις εικόνες (και αν όχι, τότε πρέπει να το διαγράψουμε στο ίδιο το Git).
  2. όλα τα pods που αντλούνται αυτήν τη στιγμή στο Kubernetes.
  3. παλιά ReplicaSets (αυτό που κυκλοφόρησε πρόσφατα), και σκοπεύουμε επίσης να σαρώσουμε τις εκδόσεις Helm και να επιλέξουμε εκεί τις πιο πρόσφατες εικόνες.

... και δημιουργήστε μια λίστα επιτρεπόμενων από αυτό το σύνολο - μια λίστα εικόνων που δεν θα διαγράψουμε. Καθαρίζουμε όλα τα άλλα, μετά βρίσκουμε ορφανές εικόνες σκηνής και τις διαγράφουμε επίσης.

Στάδιο ανάπτυξης

Αξιόπιστη δηλωτική ικανότητα

Το πρώτο σημείο στο οποίο θα ήθελα να επιστήσω την προσοχή κατά την ανάπτυξη είναι η διάθεση της ενημερωμένης διαμόρφωσης πόρων, που δηλώνεται δηλωτικά. Το αρχικό έγγραφο YAML που περιγράφει πόρους Kubernetes είναι πάντα πολύ διαφορετικό από το αποτέλεσμα που εκτελείται πραγματικά στο σύμπλεγμα. Επειδή το Kubernetes προσθέτει στη διαμόρφωση:

  1. αναγνωριστικά·
  2. πληροφορίες υπηρεσίας·
  3. πολλές προεπιλεγμένες τιμές.
  4. ενότητα με την τρέχουσα κατάσταση·
  5. αλλαγές που έγιναν ως μέρος του webhook αποδοχής·
  6. το αποτέλεσμα της εργασίας διαφόρων ελεγκτών (και του χρονοπρογραμματιστή).

Επομένως, όταν εμφανίζεται μια νέα διαμόρφωση πόρων (νέος), δεν μπορούμε απλώς να πάρουμε και να αντικαταστήσουμε την τρέχουσα, "ζωντανή" διαμόρφωση με αυτήν (ζω). Για να γίνει αυτό θα πρέπει να συγκρίνουμε νέος με την τελευταία εφαρμοσμένη διαμόρφωση (τελευταία εφαρμογή) και κυλήστε επάνω ζω έλαβε έμπλαστρο.

Αυτή η προσέγγιση ονομάζεται Συγχώνευση 2 κατευθύνσεων. Χρησιμοποιείται, για παράδειγμα, στο Helm.

Υπάρχει επίσης Συγχώνευση 3 κατευθύνσεων, που διαφέρει στο ότι:

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

Αναπτύσσουμε 1000+ εφαρμογές με το Helm, επομένως ζούμε στην πραγματικότητα με τη συγχώνευση 2 κατευθύνσεων. Ωστόσο, έχει μια σειρά από προβλήματα που έχουμε λύσει με τα patches μας, τα οποία βοηθούν τον Helm να λειτουργεί κανονικά.

Πραγματική κατάσταση διάθεσης

Αφού το σύστημά μας CI δημιουργήσει μια νέα διαμόρφωση για το Kubernetes με βάση το επόμενο συμβάν, το μεταδίδει για χρήση (ισχύουν) σε ένα σύμπλεγμα - χρησιμοποιώντας Helm ή kubectl apply. Στη συνέχεια, εμφανίζεται η ήδη περιγραφείσα συγχώνευση N-way, στην οποία το Kubernetes API ανταποκρίνεται εγκριτικά στο σύστημα CI, και αυτό στον χρήστη του.

werf - το εργαλείο μας για CI / CD στο Kubernetes (επισκόπηση και αναφορά βίντεο)

Ωστόσο, υπάρχει ένα τεράστιο πρόβλημα: τελικά επιτυχημένη εφαρμογή δεν σημαίνει επιτυχημένη διάθεση. Εάν η Kubernetes κατανοήσει ποιες αλλαγές πρέπει να εφαρμοστούν και τις εφαρμόσει, δεν γνωρίζουμε ακόμα ποιο θα είναι το αποτέλεσμα. Για παράδειγμα, η ενημέρωση και η επανεκκίνηση των pod στο frontend μπορεί να είναι επιτυχής, αλλά όχι στο backend και θα λάβουμε διαφορετικές εκδόσεις των εικόνων της εφαρμογής που εκτελούνται.

Για να γίνουν τα πάντα σωστά, αυτό το σχήμα απαιτεί έναν πρόσθετο σύνδεσμο - έναν ειδικό ανιχνευτή που θα λαμβάνει πληροφορίες κατάστασης από το Kubernetes API και θα τις μεταδίδει για περαιτέρω ανάλυση της πραγματικής κατάστασης των πραγμάτων. Δημιουργήσαμε μια βιβλιοθήκη ανοιχτού κώδικα στο Go - κυβόσκυλο (δείτε την ανακοίνωσή του εδώ), το οποίο λύνει αυτό το πρόβλημα και είναι ενσωματωμένο στο werf.

Η συμπεριφορά αυτού του tracker σε επίπεδο werf διαμορφώνεται χρησιμοποιώντας σχολιασμούς που τοποθετούνται σε Deployments ή StatefulSets. Κύριος σχολιασμός - fail-mode - κατανοεί τις ακόλουθες έννοιες:

  • IgnoreAndContinueDeployProcess — αγνοούμε τα προβλήματα ανάπτυξης αυτού του στοιχείου και συνεχίζουμε την ανάπτυξη·
  • FailWholeDeployProcessImmediately — ένα σφάλμα σε αυτό το στοιχείο διακόπτει τη διαδικασία ανάπτυξης.
  • HopeUntilEndOfDeployProcess — ελπίζουμε ότι αυτό το στοιχείο θα λειτουργήσει μέχρι το τέλος της ανάπτυξης.

Για παράδειγμα, αυτός ο συνδυασμός πόρων και τιμών σχολιασμού fail-mode:

werf - το εργαλείο μας για CI / CD στο Kubernetes (επισκόπηση και αναφορά βίντεο)

Όταν αναπτύσσουμε για πρώτη φορά, η βάση δεδομένων (MongoDB) μπορεί να μην είναι ακόμη έτοιμη - Οι αναπτύξεις θα αποτύχουν. Αλλά μπορείτε να περιμένετε τη στιγμή για να ξεκινήσει και η ανάπτυξη θα συνεχίσει να γίνεται.

Υπάρχουν δύο ακόμη σχολιασμοί για το kubedog στο werf:

  • failures-allowed-per-replica — ο αριθμός των επιτρεπόμενων πτώσεων για κάθε αντίγραφο·
  • show-logs-until — ρυθμίζει τη στιγμή μέχρι την οποία το werf εμφανίζει (στο stdout) αρχεία καταγραφής από όλα τα αναπτυγμένα λοβία. Η προεπιλογή είναι PodIsReady (για να αγνοήσουμε μηνύματα που πιθανότατα δεν θέλουμε όταν η κυκλοφορία αρχίζει να έρχεται στο pod), αλλά οι τιμές είναι επίσης έγκυρες: ControllerIsReady и EndOfDeploy.

Τι άλλο θέλουμε από την ανάπτυξη;

Εκτός από τα δύο σημεία που έχουν ήδη περιγραφεί, θα θέλαμε:

  • για να δει κούτσουρα - και μόνο τα απαραίτητα, και όχι όλα στη σειρά.
  • πίστα πρόοδο, γιατί αν η δουλειά μένει «σιωπηλά» για αρκετά λεπτά, είναι σημαντικό να καταλάβουμε τι συμβαίνει εκεί.
  • έχουν αυτόματη επαναφορά σε περίπτωση που κάτι πήγε στραβά (και επομένως είναι κρίσιμο να γνωρίζουμε την πραγματική κατάσταση της ανάπτυξης). Η διάθεση πρέπει να είναι ατομική: είτε φτάνει μέχρι το τέλος, είτε όλα επιστρέφουν στην προηγούμενη κατάστασή τους.

Αποτελέσματα της

Για εμάς ως εταιρεία, για να εφαρμόσουμε όλες τις περιγραφόμενες αποχρώσεις σε διαφορετικά στάδια παράδοσης (κατασκευή, δημοσίευση, ανάπτυξη), αρκεί ένα σύστημα CI και ένα βοηθητικό πρόγραμμα werf.

Αντί για συμπέρασμα:

werf - το εργαλείο μας για CI / CD στο Kubernetes (επισκόπηση και αναφορά βίντεο)

Με τη βοήθεια του werf, έχουμε σημειώσει καλή πρόοδο στην επίλυση μεγάλου αριθμού προβλημάτων για τους μηχανικούς DevOps και θα ήμασταν ευτυχείς εάν η ευρύτερη κοινότητα τουλάχιστον δοκίμαζε αυτό το βοηθητικό πρόγραμμα στην πράξη. Θα είναι πιο εύκολο να επιτύχετε ένα καλό αποτέλεσμα μαζί.

Βίντεο και διαφάνειες

Βίντεο από την παράσταση (~47 λεπτά):

Παρουσίαση της έκθεσης:

PS

Άλλες αναφορές για το Kubernetes στο ιστολόγιό μας:

Πηγή: www.habr.com

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