
Wir werden zunehmend nach der Entwicklung von Mikrodiensten in Kubernetes gefragt. Entwickler, insbesondere interpretierte Sprachen, möchten den Code in ihrer bevorzugten IDE schnell korrigieren, ohne darauf warten zu müssen, dass der Build / die Bereitstellung das Ergebnis anzeigt - indem sie einfach F5 drücken. Und wenn es um die monolithische Anwendung ging, reichte es aus, die Datenbank und den Webserver (in Docker, VirtualBox ...) lokal zu erhöhen. Danach - genießen Sie sofort die Entwicklung. Mit dem Sägen von Monolithen in Mikrodienste und dem Aufkommen von Kubernetes, mit dem Aufkommen von Abhängigkeiten voneinander, wurden die Dinge
etwas komplizierter . Je mehr dieser Mikrodienste, desto mehr Probleme. Um die Entwicklung wieder genießen zu können, müssen Sie mehr als ein oder zwei Docker-Container und manchmal sogar mehr als ein Dutzend anheben. Im Allgemeinen kann dies viel Zeit in Anspruch nehmen, da es auch auf dem neuesten Stand gehalten werden muss.
Zu verschiedenen Zeiten haben wir verschiedene Lösungen für das Problem versucht. Und ich beginne mit den akkumulierten Problemumgehungen oder einfach „Krücken“.
1. Krücken
Die meisten IDEs können Code mithilfe von FTP / SFTP direkt auf dem Server bearbeiten. Dieser Weg ist sehr offensichtlich und wir haben uns sofort entschieden, ihn zu verwenden. Sein Wesen ist wie folgt:
- Im Pod für Entwicklungsumgebungen (dev / review) wird ein zusätzlicher Container mit Zugriff über SSH gestartet und der öffentliche SSH-Schlüssel des Entwicklers weitergeleitet, der die Anwendung festschreibt / bereitstellt.
- In der Init-Phase (innerhalb des
emptyDir
prepare-app
Containers) übertragen wir den Code an emptyDir
um von den Containern mit der Anwendung und dem SSH-Server aus auf den Code zugreifen zu können.

Zum besseren Verständnis der technischen Implementierung eines solchen Schemas werde ich Fragmente der beteiligten YAML-Konfigurationen in Kubernetes geben.
Konfigurationen
1.1. values.yaml
ssh_pub_key: vasya.pupkin: <ssh public key in base64>
Hier ist
vasya.pupkin
der Wert der Variablen
${GITLAB_USER_LOGIN}
.
1.2. deploy.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. secret.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 }}
Letzte Berührung
Danach müssen nur noch die
erforderlichen Variablen an gitlab-ci.yml übergeben werden :
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: Der Entwickler, der die Bereitstellung gestartet hat, kann über den Namen des Dienstes (
wir haben Ihnen bereits erklärt, wie
Sie sicher auf den Cluster zugreifen können) von Ihrem Desktop aus über SFTP eine Verbindung herstellen und den Code bearbeiten, ohne darauf zu warten, dass er an den Cluster übermittelt wird.
Dies ist eine vollständig funktionierende Lösung, die jedoch unter dem Gesichtspunkt der Implementierung offensichtliche Nachteile aufweist:
- die Notwendigkeit, das Helm-Diagramm zu verfeinern, was das Lesen weiter erschwert;
- Nur wer den Dienst bereitgestellt hat, kann ihn verwenden.
- Sie müssen daran denken, es mit dem lokalen Verzeichnis mit dem Code zu synchronisieren und in Git festzuschreiben.
2. Telepräsenz
Das
Telepresence- Projekt ist seit geraumer Zeit bekannt, aber es in der Praxis ernsthaft mit uns zu versuchen, wie sie sagen, "hat unsere Hände nicht erreicht". Die Nachfrage hat jedoch ihren Job gemacht und jetzt freuen wir uns, Erfahrungen auszutauschen, die für die Leser unseres Blogs nützlich sein können - zumal es im Hub noch keine anderen Materialien zu Telepresence gab.
Kurz gesagt, es war nicht so beängstigend. Alle Aktionen, die vom Entwickler ausgeführt werden müssen, haben wir in die Textdatei des Helm-Diagramms mit dem Namen
NOTES.txt
. Daher sieht der Entwickler nach der Bereitstellung des Dienstes in Kubernetes die Anweisung zum Starten der lokalen Entwicklungsumgebung im GitLab-Jobprotokoll:
!!! , 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 #########################################################################
Wir werden uns nicht mit den in diesem Handbuch beschriebenen Schritten befassen ... mit Ausnahme der letzten. Was passiert beim Start von Telepresence?
Arbeiten Sie mit Telepresence
Beim Start (mit dem letzten in den obigen Anweisungen angegebenen Befehl) setzen wir:
- Namespace (Namespace), in dem der Microservice gestartet wird;
- die Namen der Bereitstellung und des Containers, in den wir eindringen möchten.
Die restlichen Argumente sind optional. Wenn unser Service mit der Kubernetes-API interagiert und
ein ServiceAccount dafür erstellt wird, müssen wir die Zertifikate / Token auf unserem Desktop bereitstellen. Verwenden Sie dazu die Option
--mount=true
(oder
--mount=/dst_path
), mit der das Stammverzeichnis (/) aus dem Container in Kubernetes auf unserem Desktop
--mount=/dst_path
wird. Danach können wir (abhängig vom Betriebssystem und der Art und Weise, wie die Anwendung gestartet wird) die „Schlüssel“ aus dem Cluster verwenden.
Betrachten Sie zunächst die vielseitigste Option zum Starten von Anwendungen - im Docker-Container. Verwenden Sie dazu den Schalter
--docker-run
und
--docker-run
das Verzeichnis mit dem Code im Container ein:
-v `pwd`:/app
Bitte beachten Sie, dass dies bedeutet, dass Sie mit dem Projekt im Verzeichnis beginnen. Der Anwendungscode wird im Verzeichnis
/app
im Container bereitgestellt.
Weiter:
-v /tmp/app/var/run/secrets:/var/run/secrets
- um das Verzeichnis mit dem Zertifikat / Token in den Container zu mounten.
Auf diese Option folgt schließlich das Image, in dem die Anwendung gestartet wird.
NB : Wenn Sie ein Bild
ENTRYPOINT
, müssen Sie
CMD
oder
ENTRYPOINT
angeben!
Was wird eigentlich als nächstes passieren?
- In Kubernetes wird für die angegebene Bereitstellung die Anzahl der Replikate auf 0 geändert. Stattdessen wird eine neue Bereitstellung gestartet - mit dem ersetzten
backend
Container. - Auf dem Desktop werden 2 Container gestartet: der erste - mit Telepresence (Proxy-Anfragen von / an Kubernetes), der zweite - mit der zu entwickelnden Anwendung.
- Wenn exec'nitsya im Container mit der Anwendung enthalten ist, haben wir Zugriff auf alle ENV-Variablen, die Helm während der Bereitstellung übergeben hat, sowie auf alle verfügbaren Dienste. Sie müssen lediglich den Code in Ihrer bevorzugten IDE bearbeiten und das Ergebnis genießen.
- Am Ende der Arbeit reicht es aus, einfach das Terminal zu schließen, auf dem Telepresence ausgeführt wird (Sitzung mit Strg + C beenden), Docker-Container auf dem Desktop anzuhalten und alles in seinem ursprünglichen Zustand in Kubernetes wiederherzustellen. Sie müssen lediglich einen Commit durchführen, den MR ausstellen und ihn zur Überprüfung / Zusammenführung / ... übergeben (abhängig von Ihren Workflows).
Wenn wir die Anwendung nicht im Docker-Container ausführen möchten - beispielsweise entwickeln wir sie nicht in PHP, sondern in Go und sammeln sie dennoch lokal -, ist das Starten von Telepresence noch einfacher:
telepresence --namespace {{ .Values.global.env }} --swap-deployment {{ .Chart.Name }}:backend --mount=true
Wenn die Anwendung auf die Kubernetes-API zugreift, müssen Sie das
Verzeichnis mit den Schlüsseln bereitstellen. Für Linux gibt es ein
Proot- Dienstprogramm:
proot -b $TELEPRESENCE_ROOT/var/run/secrets/:/var/run/secrets bash
Nach dem Starten von Telepresence ohne die Option
--docker-run
sind alle Umgebungsvariablen im aktuellen Terminal verfügbar, sodass Sie die Anwendung darin starten müssen.
NB : Wenn Sie beispielsweise PHP verwenden, müssen Sie daran denken, verschiedene op_cache-, apc- und andere Beschleuniger für die Entwicklung zu deaktivieren. Andernfalls führt das Bearbeiten des Codes nicht zum gewünschten Ergebnis.
Zusammenfassung
Die lokale Entwicklung mit Kubernetes ist ein Problem, dessen Lösungsbedarf proportional zur Verbreitung dieser Plattform wächst. Nachdem wir relevante Anfragen von den Entwicklern (von unseren Kunden) erhalten hatten, begannen wir, diese mit den ersten verfügbaren Mitteln zu lösen, die sich jedoch auf lange Sicht nicht bewährt hatten. Glücklicherweise ist dies nicht nur jetzt und nicht nur für uns offensichtlich geworden, daher sind bereits geeignetere Mittel auf der Welt erschienen, und Telepresence ist das bekannteste von ihnen (es gibt übrigens immer noch ein
Gerüst von Google). Unsere Erfahrung mit seiner Verwendung ist nicht so großartig, aber es gibt bereits Grund, "Kollegen" zu empfehlen - probieren Sie es aus!
PS
Andere aus dem K8s Tipps & Tricks-Zyklus: