Sfaturi și trucuri Kubernetes: despre dezvoltarea locală și teleprezență

Sfaturi și trucuri Kubernetes: despre dezvoltarea locală și teleprezență

Suntem din ce în ce mai întrebați despre dezvoltarea microserviciilor în Kubernetes. Dezvoltatorii, în special ai limbilor interpretate, doresc să corecteze rapid codul în IDE-ul lor preferat și să vadă rezultatul fără a aștepta construirea/implementarea - prin simpla apăsare a F5. Și când a fost vorba de o aplicație monolitică, a fost suficient să instalezi local o bază de date și un server web (în Docker, VirtualBox...), și apoi să te bucuri imediat de dezvoltare. Odată cu tăierea monoliților în microservicii și sosirea Kubernetes, odată cu apariția dependențelor unul de celălalt, totul a devenit un pic mai greu. Cu cât aceste microservicii sunt mai multe, cu atât mai multe probleme. Pentru a vă bucura din nou de dezvoltare, trebuie să ridicați mai mult de unul sau două containere Docker și, uneori, chiar și mai mult de o duzină... În general, toate acestea pot dura destul de mult timp, deoarece trebuie de asemenea să fie actualizate. .

În momente diferite am încercat soluții diferite la problemă. Și voi începe cu soluțiile acumulate sau pur și simplu cu „cârje”.

1. Cârje

Majoritatea IDE-urilor au capacitatea de a edita codul direct pe server folosind FTP/SFTP. Această cale este foarte evidentă și am decis imediat să o folosim. Esența sa se rezumă la următoarele:

  1. În podul mediilor de dezvoltare (dezvoltare/revizuire), un container suplimentar este lansat cu acces SSH și redirecționează cheia SSH publică a dezvoltatorului care va confirma/implementa aplicația.
  2. În stadiul inițial (în interiorul containerului prepare-app) transferați codul către emptyDirpentru a avea acces la codul din containerele aplicației și serverul SSH.

Sfaturi și trucuri Kubernetes: despre dezvoltarea locală și teleprezență

Pentru a înțelege mai bine implementarea tehnică a unei astfel de scheme, voi furniza fragmente din configurațiile YAML implicate în Kubernetes.

Configurații

1.1. valori.yaml

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

Aici vasya.pupkin este valoarea variabilei ${GITLAB_USER_LOGIN}.

1.2. implementare.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 }}

Efectul final

După aceea, tot ce rămâne este transferul variabilele necesare 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: dezvoltatorul care a lansat implementarea se poate conecta după numele serviciului (cum să acordați acces în siguranță la cluster, am povestit deja) de pe desktop prin SFTP și editați codul fără a aștepta ca acesta să fie livrat în cluster.

Aceasta este o soluție complet funcțională, dar din punct de vedere al implementării are dezavantaje evidente:

  • necesitatea de a rafina graficul Helm, ceea ce face dificil de citit pe viitor;
  • poate fi folosit numai de persoana care a implementat serviciul;
  • trebuie să vă amintiți să îl sincronizați apoi cu directorul local cu codul și să îl trimiteți în Git.

2. Teleprezența

Proiect Telepresenta este cunoscut de destul de mult timp, dar noi, după cum se spune, „nu am apucat să încercăm serios în practică”. Cu toate acestea, cererea și-a făcut treaba și acum suntem bucuroși să împărtășim experiența noastră, care poate fi utilă cititorilor blogului nostru - mai ales că nu au existat încă alte materiale despre Teleprezență pe hub.

Pe scurt, totul s-a dovedit a nu fi atât de înfricoșător. Am plasat toate acțiunile care necesită execuție din partea dezvoltatorului într-un fișier text al diagramei Helm numit NOTES.txt. Astfel, după implementarea serviciului pe Kubernetes, dezvoltatorul vede instrucțiuni pentru lansarea mediului de dezvoltare local în jurnalul de joburi 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
#########################################################################

Nu ne vom opri în detaliu asupra pașilor descriși în această instrucțiune... cu excepția ultimului. Ce se întâmplă în timpul lansării Teleprezenței?

Lucrul cu Teleprezența

La pornire (folosind ultima comandă specificată în instrucțiunile de mai sus), setăm:

  • spațiu de nume în care rulează microserviciul;
  • numele implementării și containerului în care dorim să pătrundem.

Argumentele rămase sunt opționale. Dacă serviciul nostru interacționează cu și pentru API-ul Kubernetes ServiceAccount creat, trebuie să instalăm certificate/token-uri pe desktopul nostru. Pentru a face acest lucru, utilizați opțiunea --mount=true (Sau, --mount=/dst_path), care va monta rădăcina (/) din containerul Kubernetes pe desktopul nostru. După aceasta, putem (în funcție de sistemul de operare și de modul în care este lansată aplicația) să folosim „cheile” din cluster.

Mai întâi, să ne uităm la cea mai universală opțiune pentru rularea unei aplicații - într-un container Docker. Pentru a face acest lucru vom folosi cheia --docker-run și montați directorul cu codul în container: -v `pwd`:/app

Vă rugăm să rețineți că aceasta presupune rularea din directorul proiectului. Codul aplicației va fi montat în director /app într-un recipient.

Următor: -v /tmp/app/var/run/secrets:/var/run/secrets — pentru a monta directorul cu certificatul/jetonul într-un container.

Această opțiune este urmată în final de imaginea în care va rula aplicația. NB: Când construiți o imagine, trebuie să specificați CMD sau ENTRYPOINT!

Ce se va întâmpla mai exact în continuare?

  • În Kubernetes, pentru implementarea specificată, numărul de replici va fi modificat la 0. În schimb, va fi lansată o nouă implementare - cu un container înlocuitor backend.
  • Pe desktop se vor lansa 2 containere: primul cu Telepresence (va proxy cererile de la/la Kubernetes), al doilea cu aplicația în curs de dezvoltare.
  • Dacă executăm în containerul cu aplicația, atunci toate variabilele ENV transferate de Helm în timpul implementării ne vor fi disponibile și toate serviciile vor fi, de asemenea, disponibile. Tot ce rămâne este să editezi codul în IDE-ul tău preferat și să te bucuri de rezultat.
  • La sfârșitul lucrărilor, trebuie doar să închideți terminalul în care rulează Telepresence (încheiați sesiunea cu Ctrl+C) - containerele Docker se vor opri pe desktop, iar în Kubernetes totul va reveni la starea inițială. Tot ce rămâne este să te angajezi, să emiti MR și să-l transferi la revizuire/imbinare/... (în funcție de fluxurile de lucru).

Dacă nu dorim să rulăm aplicația într-un container Docker - de exemplu, dezvoltăm nu în PHP, ci în Go și totuși o construim local - lansarea Telepresence va fi și mai simplă:

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

Dacă aplicația accesează API-ul Kubernetes, va trebui să montați directorul de chei (https://www.telepresence.io/howto/volumes). Există un utilitar pentru Linux rădăcină:

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

După lansarea Telepresence fără opțiune --docker-run toate variabilele de mediu vor fi disponibile în terminalul curent, deci aplicația trebuie lansată în acesta.

NB: Când utilizați, de exemplu, PHP, trebuie să vă amintiți să dezactivați diverse op_cache, apc și alte acceleratoare pentru dezvoltare - altfel editarea codului nu va duce la rezultatul dorit.

Rezultatele

Dezvoltarea locală cu Kubernetes este o problemă a cărei soluție crește proporțional cu răspândirea acestei platforme. Primind solicitări relevante de la dezvoltatori (de la clienții noștri), am început să le rezolvăm cu primele mijloace disponibile, care însă nu s-au dovedit pe termen lung. Din fericire, acest lucru a devenit evident nu numai acum și nu numai pentru noi, așa că au apărut deja mijloace mai potrivite în lume, iar Teleprezența este cea mai faimoasă dintre ele (apropo, există și schelă de la Google). Experiența noastră de utilizare nu este încă atât de mare, dar deja ne oferă motive să-l recomandăm „colegilor din magazin” - încercați-l!

PS

Altele din seria de sfaturi și trucuri K8s:

Sursa: www.habr.com

Adauga un comentariu