Αναπτύξτε εφαρμογές σε πολλαπλά συμπλέγματα Kubernetes με Helm

Πώς το Dailymotion χρησιμοποιεί το Kubernetes: Ανάπτυξη εφαρμογών

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

Από πού ξεκίνησε

Εδώ θα καλύψουμε πώς αναπτύσσουμε τις εφαρμογές μας σε πολλαπλά συμπλέγματα Kubernetes σε όλο τον κόσμο.

Για να αναπτύξουμε πολλά αντικείμενα Kubernetes ταυτόχρονα, χρησιμοποιούμε Πηδάλιο, και όλα τα γραφήματα μας αποθηκεύονται σε ένα αποθετήριο git. Για να αναπτύξουμε μια πλήρη στοίβα εφαρμογών από πολλές υπηρεσίες, χρησιμοποιούμε το λεγόμενο σύνοψη. Ουσιαστικά, αυτό είναι ένα γράφημα που δηλώνει εξαρτήσεις και σας επιτρέπει να αρχικοποιήσετε το API και τις υπηρεσίες του με μία εντολή.

Γράψαμε επίσης ένα μικρό σενάριο Python πάνω από το Helm για να κάνουμε ελέγχους, να δημιουργήσουμε γραφήματα, να προσθέσουμε μυστικά και να αναπτύξουμε εφαρμογές. Όλες αυτές οι εργασίες εκτελούνται σε μια κεντρική πλατφόρμα CI χρησιμοποιώντας μια εικόνα docker.

Πάμε στο θέμα.

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

Ροή εργασιών ανάπτυξης γραφήματος

Χρησιμοποιούμε διακλάδωση για εφαρμογές και αποφασίσαμε να εφαρμόσουμε την ίδια προσέγγιση στα γραφήματα.

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

Κάθε περιβάλλον έχει το δικό του ιδιωτικό αποθετήριο που αποθηκεύει τα γραφήματα μας και χρησιμοποιούμε Χαρτμουσείο με πολύ χρήσιμα API. Με αυτόν τον τρόπο διασφαλίζουμε αυστηρή απομόνωση μεταξύ περιβαλλόντων και πραγματικές δοκιμές γραφημάτων πριν από τη χρήση τους στην παραγωγή.

Αποθετήρια γραφημάτων σε διαφορετικά περιβάλλοντα

Αξίζει να σημειωθεί ότι όταν οι προγραμματιστές πιέζουν έναν κλάδο dev, μια έκδοση του γραφήματος τους προωθείται αυτόματα στο dev Chartmuseum. Έτσι, όλοι οι προγραμματιστές χρησιμοποιούν το ίδιο αποθετήριο προγραμματιστών και πρέπει να καθορίσετε προσεκτικά την έκδοση του γραφήματος, ώστε να μην χρησιμοποιήσετε κατά λάθος τις αλλαγές κάποιου άλλου.

Επιπλέον, το μικρό μας σενάριο Python επικυρώνει αντικείμενα Kubernetes έναντι των προδιαγραφών Kubernetes OpenAPI χρησιμοποιώντας Kubeval, πριν τα δημοσιεύσει στο Chartmusem.

Γενική περιγραφή της ροής εργασιών ανάπτυξης γραφήματος

  1. Ρύθμιση εργασιών αγωγού σύμφωνα με τις προδιαγραφές gazr.io για ποιοτικό έλεγχο (lint, unit-test).
  2. Ωθώντας μια εικόνα docker με εργαλεία Python που αναπτύσσουν τις εφαρμογές μας.
  3. Ρύθμιση του περιβάλλοντος κατά όνομα κλάδου.
  4. Επικύρωση αρχείων yaml Kubernetes χρησιμοποιώντας Kubeval.
  5. Αυτόματη αύξηση της έκδοσης ενός γραφήματος και των γονικών γραφημάτων του (γραφήματα που εξαρτώνται από το γράφημα που αλλάζει).
  6. Υποβολή γραφήματος σε Chartmuseum που ταιριάζει με το περιβάλλον του

Διαχείριση διαφορών μεταξύ συστάδων

Ομοσπονδία Συστάδων

Υπήρχε μια εποχή που χρησιμοποιούσαμε ομοσπονδία συμπλεγμάτων Kubernetes, όπου τα αντικείμενα Kubernetes μπορούσαν να δηλωθούν από ένα μόνο τελικό σημείο API. Προέκυψαν όμως προβλήματα. Για παράδειγμα, ορισμένα αντικείμενα Kubernetes δεν μπορούσαν να δημιουργηθούν στο τελικό σημείο της ομοσπονδίας, καθιστώντας δύσκολη τη διατήρηση ενοποιημένων αντικειμένων και άλλων αντικειμένων για μεμονωμένα συμπλέγματα.

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

Γεω-κατανεμημένη πλατφόρμα

Η πλατφόρμα μας αυτή τη στιγμή διανέμεται σε 6 περιοχές - 3 τοπικά και 3 στο cloud.


Κατανεμημένη ανάπτυξη

Global Helm αξίες

4 παγκόσμιες τιμές Helm σάς επιτρέπουν να προσδιορίσετε διαφορές μεταξύ των συστάδων. Όλα τα γραφήματα μας έχουν προεπιλεγμένες ελάχιστες τιμές.

global:
  cloud: True
  env: staging
  region: us-central1
  clusterName: staging-us-central1

Παγκόσμιες αξίες

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

  • «σύννεφο»: Έχουμε μια υβριδική πλατφόρμα Kubernetes. Για παράδειγμα, το API μας αναπτύσσεται σε ζώνες GCP και στα κέντρα δεδομένων μας.
  • "env": Ορισμένες τιμές ενδέχεται να αλλάξουν για περιβάλλοντα μη παραγωγής. Για παράδειγμα, ορισμοί πόρων και διαμορφώσεις αυτόματης κλιμάκωσης.
  • "region": Αυτές οι πληροφορίες βοηθούν στον προσδιορισμό της θέσης του συμπλέγματος και μπορούν να χρησιμοποιηθούν για τον προσδιορισμό κοντινών τελικών σημείων για εξωτερικές υπηρεσίες.
  • "ClusterName": εάν και πότε θέλουμε να ορίσουμε μια τιμή για ένα μεμονωμένο σύμπλεγμα.

Ιδού ένα συγκεκριμένο παράδειγμα:

{{/* Returns Horizontal Pod Autoscaler replicas for GraphQL*/}}
{{- define "graphql.hpaReplicas" -}}
{{- if eq .Values.global.env "prod" }}
{{- if eq .Values.global.region "europe-west1" }}
minReplicas: 40
{{- else }}
minReplicas: 150
{{- end }}
maxReplicas: 1400
{{- else }}
minReplicas: 4
maxReplicas: 20
{{- end }}
{{- end -}}

Παράδειγμα προτύπου τιμόνι

Αυτή η λογική ορίζεται σε ένα βοηθητικό πρότυπο για να αποφευχθεί η ακαταστασία του Kubernetes YAML.

Ανακοίνωση Αίτησης

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

releases:
  - foo.world

foo.world:                # Release name
  services:               # List of dailymotion's apps/projects
    foobar:
      chart_name: foo-foobar
      repo: [email protected]:dailymotion/foobar
      contexts:
        prod-europe-west1:
          deployments:
            - name: foo-bar-baz
              replicas: 18
            - name: another-deployment
              replicas: 3

Ορισμός υπηρεσίας

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


Βήματα ανάπτυξης Jenkins

Τι γίνεται με τα μυστικά;

Όσον αφορά την ασφάλεια, παρακολουθούμε όλα τα μυστικά από διαφορετικά μέρη και τα αποθηκεύουμε σε ένα μοναδικό θησαυροφυλάκιο Θόλος στο Παρίσι.

Τα εργαλεία ανάπτυξης μας εξάγουν μυστικές τιμές από το Vault και, όταν έρθει η ώρα ανάπτυξης, τις εισάγουν στο Helm.

Για να γίνει αυτό, ορίσαμε μια αντιστοίχιση μεταξύ των μυστικών στο Vault και των μυστικών που χρειάζονται οι εφαρμογές μας:

secrets:                                                                                                                                                                                                        
     - secret_id: "stack1-app1-password"                                                                                                                                                                                  
       contexts:                                                                                                                                                                                                   
         - name: "default"                                                                                                                                                                                         
           vaultPath: "/kv/dev/stack1/app1/test"                                                                                                                                                               
           vaultKey: "password"                                                                                                                                                                                    
         - name: "cluster1"                                                                                                                                                                           
           vaultPath: "/kv/dev/stack1/app1/test"                                                                                                                                                               
           vaultKey: "password"

  • Έχουμε ορίσει γενικούς κανόνες που πρέπει να ακολουθείτε κατά την εγγραφή μυστικών στο Vault.
  • Αν ισχύει το μυστικό σε ένα συγκεκριμένο πλαίσιο ή σύμπλεγμα, πρέπει να προσθέσετε μια συγκεκριμένη καταχώρηση. (Εδώ το σύμπλεγμα περιβάλλοντος1 έχει τη δική του τιμή για το μυστικό stack-app1-password).
  • Διαφορετικά χρησιμοποιείται η τιμή από προεπιλογή.
  • Για κάθε στοιχείο αυτής της λίστας στο Kubernetes μυστικό εισάγεται ένα ζεύγος κλειδιού-τιμής. Επομένως, το μυστικό πρότυπο στα γραφήματα μας είναι πολύ απλό.

apiVersion: v1
data:
{{- range $key,$value := .Values.secrets }}
  {{ $key }}: {{ $value | b64enc | quote }}
{{ end }}
kind: Secret
metadata:
  name: "{{ .Chart.Name }}"
  labels:
    chartVersion: "{{ .Chart.Version }}"
    tillerVersion: "{{ .Capabilities.TillerVersion.SemVer }}"
type: Opaque

Προβλήματα και περιορισμοί

Εργασία με πολλαπλά αποθετήρια

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

Η διαχείριση γενικευμένων διαγραμμάτων είναι μια ταλαιπωρία

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

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

Ενημέρωση πολλαπλών αρχείων διαμόρφωσης

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

Τα δικαιώματα Jenkins είναι πολύ επεκταμένα στο Vault

Έχουμε ένα τώρα AppRole, που διαβάζει όλα τα μυστικά από το Vault.

Η διαδικασία επαναφοράς δεν είναι αυτοματοποιημένη

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

Προχωράμε προς το GitOps

Ο στόχος μας

Θέλουμε να επιστρέψουμε το γράφημα στο αποθετήριο της εφαρμογής που αναπτύσσει.

Η ροή εργασίας θα είναι η ίδια με την ανάπτυξη. Για παράδειγμα, όταν ένας κλάδος πιέζεται για master, η ανάπτυξη θα ενεργοποιηθεί αυτόματα. Η κύρια διαφορά μεταξύ αυτής της προσέγγισης και της τρέχουσας ροής εργασίας θα είναι αυτή όλα θα διαχειρίζονται in git (η ίδια η εφαρμογή και ο τρόπος που αναπτύσσεται στο Kubernetes).

Υπάρχουν πολλά πλεονεκτήματα:

  • Πολύ σαφέστερη για τον προγραμματιστή. Είναι πιο εύκολο να μάθετε πώς να εφαρμόζετε αλλαγές σε ένα τοπικό γράφημα.
  • Μπορεί να καθοριστεί ο ορισμός ανάπτυξης υπηρεσίας ίδια θέση με τον κωδικό υπηρεσία.
  • Διαχείριση της αφαίρεσης γενικευμένων γραφημάτων. Η υπηρεσία θα έχει τη δική της έκδοση Helm. Αυτό θα σας επιτρέψει να διαχειριστείτε τον κύκλο ζωής της εφαρμογής (επιστροφή, αναβάθμιση) στο μικρότερο επίπεδο, ώστε να μην επηρεαστούν άλλες υπηρεσίες.
  • Οφέλη του git για διαχείριση γραφήματος: αναίρεση αλλαγών, αρχείο καταγραφής ελέγχου κ.λπ. Εάν χρειάζεται να αναιρέσετε μια αλλαγή σε ένα γράφημα, μπορείτε να το κάνετε χρησιμοποιώντας το git. Η ανάπτυξη ξεκινά αυτόματα.
  • Μπορείτε να εξετάσετε τη βελτίωση της ροής εργασιών ανάπτυξης με εργαλεία όπως Σκαλωσιά, με το οποίο οι προγραμματιστές μπορούν να δοκιμάσουν αλλαγές σε ένα πλαίσιο κοντά στην παραγωγή.

Μετανάστευση σε δύο βήματα

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

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

apiVersion: "v1"
kind: "DailymotionRelease"
metadata:
  name: "app1.ns1"
  environment: "dev"
  branch: "mybranch"
spec:
  slack_channel: "#admin"
  chart_name: "app1"
  scaling:
    - context: "dev-us-central1-0"
      replicas:
        - name: "hermes"
          count: 2
    - context: "dev-europe-west1-0"
      replicas:
        - name: "app1-deploy"
          count: 2
  secrets:
    - secret_id: "app1"
      contexts:
        - name: "default"
          vaultPath: "/kv/dev/ns1/app1/test"
          vaultKey: "password"
        - name: "dev-europe-west1-0"
          vaultPath: "/kv/dev/ns1/app1/test"
          vaultKey: "password"

  • 1 κυκλοφορία ανά εφαρμογή (χωρίς γενικευμένα διαγράμματα).
  • Γραφήματα στο αποθετήριο git της εφαρμογής.

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

Εδώ προσπαθήσαμε να περιγράψουμε την πρόοδό μας στη ροή εργασιών ανάπτυξης εφαρμογών τα τελευταία χρόνια, κάτι που οδήγησε σε σκέψεις σχετικά με την προσέγγιση GitOps. Δεν έχουμε φτάσει ακόμα στον στόχο και θα αναφέρουμε τα αποτελέσματα, αλλά τώρα είμαστε πεπεισμένοι ότι κάναμε το σωστό όταν αποφασίσαμε να απλοποιήσουμε τα πάντα και να τα φέρουμε πιο κοντά στις συνήθειες των προγραμματιστών.

Πηγή: www.habr.com

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