Συμβουλές & κόλπα Kubernetes: για την τοπική ανάπτυξη και την τηλεπαρουσία

Συμβουλές & κόλπα Kubernetes: για την τοπική ανάπτυξη και την τηλεπαρουσία

Μας ρωτούν όλο και περισσότερο για την ανάπτυξη μικροϋπηρεσιών στο Kubernetes. Οι προγραμματιστές, ειδικά των γλωσσών που διερμηνεύονται, θέλουν να διορθώσουν γρήγορα τον κώδικα στο αγαπημένο τους IDE και να δουν το αποτέλεσμα χωρίς να περιμένουν την κατασκευή/ανάπτυξη - απλά πατώντας το F5. Και όταν επρόκειτο για μια μονολιθική εφαρμογή, αρκούσε να εγκαταστήσετε τοπικά μια βάση δεδομένων και έναν διακομιστή ιστού (στο Docker, VirtualBox...), και στη συνέχεια να απολαύσετε αμέσως την ανάπτυξη. Με την κοπή των μονόλιθων σε microservices και την άφιξη των Kubernetes, με την εμφάνιση εξαρτήσεων μεταξύ τους, τα πάντα έγινε λίγο πιο δύσκολο. Όσο περισσότερες από αυτές τις μικροϋπηρεσίες, τόσο περισσότερα προβλήματα. Για να απολαύσετε ξανά την ανάπτυξη, πρέπει να σηκώσετε περισσότερα από ένα ή δύο δοχεία Docker, και μερικές φορές ακόμη και περισσότερα από μια ντουζίνα... Γενικά, όλο αυτό μπορεί να πάρει πολύ χρόνο, καθώς πρέπει επίσης να είναι ενημερωμένο .

Σε διαφορετικούς χρόνους δοκιμάσαμε διαφορετικές λύσεις στο πρόβλημα. Και θα ξεκινήσω με τις συσσωρευμένες λύσεις ή απλά «δεκανίκια».

1. Πατερίτσες

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

  1. Στο pod των περιβαλλόντων ανάπτυξης (dev/review), εκκινείται ένα πρόσθετο κοντέινερ με πρόσβαση SSH και προώθηση του δημόσιου κλειδιού SSH του προγραμματιστή που θα δεσμεύσει/εγκαταστήσει την εφαρμογή.
  2. Στο αρχικό στάδιο (εντός του δοχείου prepare-app) μεταφέρετε τον κωδικό στο emptyDirγια να έχετε πρόσβαση στον κώδικα από τα κοντέινερ της εφαρμογής και τον διακομιστή SSH.

Συμβουλές & κόλπα Kubernetes: για την τοπική ανάπτυξη και την τηλεπαρουσία

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

Διαμορφώσεις

1.1. αξίες.yaml

ssh_pub_key:
  vasya.pupkin: <ssh public key in base64> 

Εδώ vasya.pupkin είναι η τιμή της μεταβλητής ${GITLAB_USER_LOGIN}.

1.2. ανάπτυξη.yaml

...
{{ if eq .Values.global.debug "yes" }}
      volumes:
      - name: ssh-pub-key
        secret:
          defaultMode: 0600
          secretName: {{ .Chart.Name }}-ssh-pub-key
      - name: app-data
        emptyDir: {}
      initContainers:
      - name: prepare-app
{{ tuple "backend" . | include "werf_container_image" | indent 8 }}
        volumeMounts:
        - name: app-data
          mountPath: /app-data
        command: ["bash", "-c", "cp -ar /app/* /app-data/" ]
{{ end }}
      containers:
{{ if eq .Values.global.debug "yes" }}
      - name: ssh
        image: corbinu/ssh-server
        volumeMounts:
        - name: ssh-pub-key
          readOnly: true
          mountPath: /root/.ssh/authorized_keys
          subPath: authorized_keys
        - name: app-data
          mountPath: /app
        ports:
        - name: ssh
          containerPort: 22
          protocol: TCP
{{ end }}
      - name: backend
        volumeMounts:
{{ if eq .Values.global.debug "yes" }}
        - name: app-data
          mountPath: /app
{{ end }}
        command: ["/usr/sbin/php-fpm7.2", "--fpm-config", "/etc/php/7.2/php-fpm.conf", "-F"]
...

1.3. μυστικό.yaml

{{ if eq .Values.global.debug "yes" }}
apiVersion: v1
kind: Secret
metadata:
  name: {{ .Chart.Name }}-ssh-pub-key
type: Opaque
data:
  authorized_keys: "{{ first (pluck .Values.global.username .Values.ssh_pub_key) }}"
{{ end }}

Τελική αφή

Μετά από αυτό το μόνο που μένει είναι η μεταφορά απαιτούμενες μεταβλητές gitlab-ci.yml:

dev:
  stage: deploy
  script:
   - type multiwerf && source <(multiwerf use 1.0 beta)
   - type werf && source <(werf ci-env gitlab --tagging-strategy tag-or-branch --verbose)
   - werf deploy
     --namespace ${CI_PROJECT_NAME}-stage
     --set "global.env=stage"
     --set "global.git_rev=${CI_COMMIT_SHA}"
     --set "global.debug=yes"
     --set "global.username=${GITLAB_USER_LOGIN}"
 tags:
   - build

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

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

  • την ανάγκη να τελειοποιήσουμε το διάγραμμα Helm, το οποίο καθιστά δύσκολη την ανάγνωση στο μέλλον.
  • μπορεί να χρησιμοποιηθεί μόνο από το άτομο που ανέπτυξε την υπηρεσία.
  • πρέπει να θυμάστε να το συγχρονίσετε με τον τοπικό κατάλογο με τον κώδικα και να το δεσμεύσετε στο Git.

2. Τηλεπαρουσία

Σχέδιο Τηλεπαρουσία είναι γνωστό εδώ και πολύ καιρό, αλλά εμείς, όπως λένε, «δεν καταφέραμε να το δοκιμάσουμε σοβαρά στην πράξη». Ωστόσο, η ζήτηση έχει κάνει τη δουλειά της και τώρα είμαστε στην ευχάριστη θέση να μοιραστούμε την εμπειρία μας, η οποία μπορεί να είναι χρήσιμη στους αναγνώστες του ιστολογίου μας - ειδικά επειδή δεν έχει υπάρξει ακόμη άλλο υλικό για την Telepresence στον κόμβο.

Με λίγα λόγια, όλα αποδείχτηκαν όχι τόσο τρομακτικά. Τοποθετήσαμε όλες τις ενέργειες που απαιτούν εκτέλεση από την πλευρά του προγραμματιστή σε ένα αρχείο κειμένου Helm chart που ονομάζεται NOTES.txt. Έτσι, μετά την ανάπτυξη της υπηρεσίας στο Kubernetes, ο προγραμματιστής βλέπει οδηγίες για την εκκίνηση του τοπικού περιβάλλοντος προγραμματισμού στο αρχείο καταγραφής εργασιών του GitLab:

!!! Разработка сервиса локально, в составе Kubernetes !!!

* Настройка окружения
* * Должен быть доступ до кластера через VPN
* * На локальном ПК установлен kubectl ( https://kubernetes.io/docs/tasks/tools/install-kubectl/ )
* * Получить config-файл для kubectl (скопировать в ~/.kube/config)
* * На локальном ПК установлен telepresence ( https://www.telepresence.io/reference/install )
* * Должен быть установлен Docker
* * Необходим доступ уровня reporter или выше к репозиторию https://gitlab.site.com/group/app
* * Необходимо залогинится в registry с логином/паролем от GitLab (делается один раз):

#########################################################################
docker login registry.site.com
#########################################################################

* Запуск окружения

#########################################################################
telepresence --namespace {{ .Values.global.env }} --swap-deployment {{ .Chart.Name  }}:backend --mount=/tmp/app --docker-run -v `pwd`:/app -v /tmp/app/var/run/secrets:/var/run/secrets -ti registry.site.com/group/app/backend:v8
#########################################################################

Δεν θα σταθούμε λεπτομερώς στα βήματα που περιγράφονται σε αυτήν την οδηγία... με εξαίρεση το τελευταίο. Τι συμβαίνει κατά την κυκλοφορία του Telepresence;

Εργασία με την Telepresence

Κατά την εκκίνηση (χρησιμοποιώντας την τελευταία εντολή που καθορίζεται στις παραπάνω οδηγίες), ορίζουμε:

  • Χώρος ονομάτων στον οποίο εκτελείται η microservice.
  • ονόματα της ανάπτυξης και του κοντέινερ που θέλουμε να διεισδύσουμε.

Τα υπόλοιπα ορίσματα είναι προαιρετικά. Εάν η υπηρεσία μας αλληλεπιδρά με και για το Kubernetes API Δημιουργήθηκε λογαριασμός υπηρεσίας, πρέπει να προσαρτήσουμε πιστοποιητικά/tokens στην επιφάνεια εργασίας μας. Για να το κάνετε αυτό, χρησιμοποιήστε την επιλογή --mount=true--mount=/dst_path), το οποίο θα προσαρτήσει τη ρίζα (/) από το κοντέινερ Kubernetes στην επιφάνεια εργασίας μας. Μετά από αυτό, μπορούμε (ανάλογα με το λειτουργικό σύστημα και τον τρόπο εκκίνησης της εφαρμογής) να χρησιμοποιήσουμε τα «κλειδιά» από το σύμπλεγμα.

Αρχικά, ας δούμε την πιο καθολική επιλογή για την εκτέλεση μιας εφαρμογής - σε ένα κοντέινερ Docker. Για να το κάνουμε αυτό θα χρησιμοποιήσουμε το κλειδί --docker-run και προσαρτήστε τον κατάλογο με τον κωδικό στο κοντέινερ: -v `pwd`:/app

Λάβετε υπόψη ότι αυτό προϋποθέτει εκτέλεση από τον κατάλογο του έργου. Ο κωδικός της εφαρμογής θα τοποθετηθεί στον κατάλογο /app σε ένα δοχείο.

Επόμενο: -v /tmp/app/var/run/secrets:/var/run/secrets — για να προσαρτήσετε τον κατάλογο με το πιστοποιητικό/τοκεν σε ένα κοντέινερ.

Αυτή η επιλογή ακολουθείται τελικά από την εικόνα στην οποία θα εκτελείται η εφαρμογή. NB: Κατά τη δημιουργία μιας εικόνας, πρέπει να καθορίσετε CMD ή ENTRYPOINT!

Τι ακριβώς θα συμβεί στη συνέχεια;

  • Στο Kubernetes, για την καθορισμένη Ανάπτυξη, ο αριθμός των αντιγράφων θα αλλάξει σε 0. Αντ' αυτού, θα ξεκινήσει μια νέα Ανάπτυξη - με ένα υποκατάστατο κοντέινερ backend.
  • 2 κοντέινερ θα ξεκινήσουν στην επιφάνεια εργασίας: το πρώτο με Telepresence (θα ζητά μεσολάβηση από/προς Kubernetes), το δεύτερο με την εφαρμογή που αναπτύσσεται.
  • Εάν πραγματοποιήσουμε εκτέλεση στο κοντέινερ με την εφαρμογή, τότε όλες οι μεταβλητές ENV που μεταφέρονται από την Helm κατά την ανάπτυξη θα είναι διαθέσιμες σε εμάς και όλες οι υπηρεσίες θα είναι επίσης διαθέσιμες. Το μόνο που μένει είναι να επεξεργαστείτε τον κώδικα στο αγαπημένο σας IDE και να απολαύσετε το αποτέλεσμα.
  • Στο τέλος της εργασίας, απλά πρέπει να κλείσετε το τερματικό στο οποίο εκτελείται το Telepresence (τερματίστε τη συνεδρία με Ctrl+C) - Τα κοντέινερ Docker θα σταματήσουν στην επιφάνεια εργασίας και στο Kubernetes όλα θα επιστρέψουν στην αρχική τους κατάσταση. Το μόνο που μένει είναι να δεσμευτείτε, να εκδώσετε το MR και να το μεταφέρετε σε αναθεώρηση/συγχώνευση/… (ανάλογα με τις ροές εργασιών σας).

Εάν δεν θέλουμε να τρέξουμε την εφαρμογή σε ένα κοντέινερ Docker - για παράδειγμα, δεν αναπτύσσουμε σε PHP, αλλά στο Go και εξακολουθούμε να την χτίζουμε τοπικά - η εκκίνηση του Telepresence θα είναι ακόμα πιο απλή:

telepresence --namespace {{ .Values.global.env }} --swap-deployment {{ .Chart.Name  }}:backend --mount=true

Εάν η εφαρμογή αποκτήσει πρόσβαση στο Kubernetes API, θα χρειαστεί να προσαρτήσετε τον κατάλογο κλειδιών (https://www.telepresence.io/howto/volumes). Υπάρχει ένα βοηθητικό πρόγραμμα για Linux ρίζα:

proot -b $TELEPRESENCE_ROOT/var/run/secrets/:/var/run/secrets bash

Μετά την εκκίνηση του Telepresence χωρίς την επιλογή --docker-run όλες οι μεταβλητές περιβάλλοντος θα είναι διαθέσιμες στο τρέχον τερματικό, επομένως η εφαρμογή πρέπει να εκκινηθεί σε αυτό.

NB: Όταν χρησιμοποιείτε, για παράδειγμα, PHP, πρέπει να θυμάστε να απενεργοποιήσετε διάφορους επιταχυντές op_cache, apc και άλλους επιταχυντές για ανάπτυξη - διαφορετικά η επεξεργασία του κώδικα δεν θα οδηγήσει στο επιθυμητό αποτέλεσμα.

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

Η τοπική ανάπτυξη με το Kubernetes είναι ένα πρόβλημα του οποίου η λύση αυξάνεται ανάλογα με την εξάπλωση αυτής της πλατφόρμας. Λαμβάνοντας σχετικά αιτήματα από προγραμματιστές (από πελάτες μας), αρχίσαμε να τα λύνουμε με τα πρώτα διαθέσιμα μέσα, τα οποία όμως δεν αποδείχτηκαν σε βάθος χρόνου. Ευτυχώς, αυτό έχει γίνει προφανές όχι μόνο τώρα και όχι μόνο σε εμάς, επομένως έχουν ήδη εμφανιστεί στον κόσμο πιο κατάλληλα μέσα και το Telepresence είναι το πιο διάσημο από αυτά (παρεμπιπτόντως, υπάρχει επίσης σκαλωσιά από την Google). Η εμπειρία μας από τη χρήση του δεν είναι ακόμα τόσο μεγάλη, αλλά μας δίνει ήδη λόγους να το προτείνουμε στους «συναδέλφους μας στο κατάστημα» - δοκιμάστε το!

PS

Άλλο από τη σειρά K8s tips & tricks:

Πηγή: www.habr.com

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