Consells i trucs de Kubernetes: sobre desenvolupament local i telepresència

Consells i trucs de Kubernetes: sobre desenvolupament local i telepresència

Cada cop se'ns pregunta més sobre el desenvolupament de microserveis a Kubernetes. Els desenvolupadors, especialment els idiomes interpretats, volen corregir ràpidament el codi del seu IDE favorit i veure el resultat sense esperar a la compilació/desplegament, simplement prement F5. I quan es tractava d'una aplicació monolítica, n'hi havia prou amb instal·lar localment una base de dades i un servidor web (a Docker, VirtualBox...), i després gaudir de seguida del desenvolupament. Amb el tall de monòlits en microserveis i l'arribada de Kubernetes, amb l'aparició de dependències entre si, tot es va fer una mica més difícil. Com més microserveis d'aquests, més problemes. Per tornar a gaudir del desenvolupament, cal aixecar més d'un o dos contenidors Docker, i de vegades fins i tot més d'una dotzena... En general, tot això pot trigar força temps, ja que també cal mantenir-lo actualitzat. .

En diferents moments vam provar diferents solucions al problema. I començaré amb les solucions alternatives acumulades o simplement "mulletes".

1. Muletas

La majoria dels IDE tenen la capacitat d'editar codi directament al servidor mitjançant FTP/SFTP. Aquest camí és molt evident i de seguida vam decidir utilitzar-lo. La seva essència es resumeix en el següent:

  1. Al grup d'entorns de desenvolupament (desenvolupament/revisió), es llança un contenidor addicional amb accés SSH i reenviant la clau SSH pública del desenvolupador que confirmarà/desplegarà l'aplicació.
  2. En l'etapa inicial (dins del contenidor prepare-app) transfereix el codi a emptyDirper tenir accés al codi des dels contenidors de l'aplicació i del servidor SSH.

Consells i trucs de Kubernetes: sobre desenvolupament local i telepresència

Per entendre millor la implementació tècnica d'aquest esquema, proporcionaré fragments de les configuracions YAML implicades a Kubernetes.

Configuracions

1.1. valors.yaml

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

Aquí vasya.pupkin és el valor de la variable ${GITLAB_USER_LOGIN}.

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

Tacte final

Després d'això, només queda transferir variables necessàries 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: el desenvolupador que va llançar el desplegament es pot connectar pel nom del servei (com concedir accés al clúster de manera segura, ja ho vam dir) des del vostre escriptori mitjançant SFTP i editeu el codi sense esperar que s'entregui al clúster.

Aquesta és una solució completament funcional, però des del punt de vista de la implementació té desavantatges evidents:

  • la necessitat de perfeccionar el gràfic Helm, que dificulta la lectura en el futur;
  • només pot ser utilitzat per la persona que ha desplegat el servei;
  • Cal recordar que després sincronitzar-lo amb el directori local amb el codi i enviar-lo a Git.

2. Telepresència

Projecte Telepresència es coneix des de fa molt de temps, però nosaltres, com diuen, "no vam arribar a provar-ho seriosament a la pràctica". Tanmateix, la demanda ha fet la seva feina i ara estem encantats de compartir la nostra experiència, que pot ser útil als lectors del nostre bloc, sobretot perquè encara no hi ha cap altre material sobre Telepresència al hub.

En resum, tot va resultar que no feia tanta por. Hem col·locat totes les accions que requereixen l'execució per part del desenvolupador en un fitxer de text de gràfic Helm anomenat NOTES.txt. Així, després de desplegar el servei a Kubernetes, el desenvolupador veu instruccions per llançar l'entorn de desenvolupament local al registre de treballs de 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
#########################################################################

No ens detenem en detall en els passos descrits en aquesta instrucció... amb l'excepció de l'últim. Què passa durant el llançament de Telepresència?

Treballant amb Telepresència

A l'inici (utilitzant l'última ordre especificada a les instruccions anteriors), establim:

  • espai de noms en què s'executa el microservei;
  • noms del desplegament i del contenidor que volem penetrar.

La resta d'arguments són opcionals. Si el nostre servei interactua amb i per a l'API de Kubernetes S'ha creat un compte de servei, hem de muntar certificats/tokens al nostre escriptori. Per fer-ho, utilitzeu l'opció --mount=true (O --mount=/dst_path), que muntarà l'arrel (/) del contenidor Kubernetes al nostre escriptori. Després d'això, podem (segons el sistema operatiu i com s'inicia l'aplicació) utilitzar les "claus" del clúster.

Primer, mirem l'opció més universal per executar una aplicació: en un contenidor Docker. Per fer-ho utilitzarem la clau --docker-run i munteu el directori amb el codi al contenidor: -v `pwd`:/app

Tingueu en compte que això suposa que s'executa des del directori del projecte. El codi de l'aplicació es muntarà al directori /app en un recipient.

Següent: -v /tmp/app/var/run/secrets:/var/run/secrets — per muntar el directori amb el certificat/token en un contenidor.

Aquesta opció finalment va seguida de la imatge en què s'executarà l'aplicació. NB: En crear una imatge, cal especificar CMD o ENTRYPOINT!

Què passarà exactament després?

  • A Kubernetes, per al desplegament especificat, el nombre de rèpliques es canviarà a 0. En comptes d'això, es llançarà un nou desplegament, amb un contenidor substitutiu. backend.
  • Es llançaran 2 contenidors a l'escriptori: el primer amb Telepresència (proxy de/a Kubernetes), el segon amb l'aplicació que s'està desenvolupant.
  • Si executem al contenidor amb l'aplicació, totes les variables ENV transferides per Helm durant el desplegament estaran disponibles per a nosaltres, i tots els serveis també estaran disponibles. Només queda editar el codi al teu IDE favorit i gaudir del resultat.
  • Al final del treball, només cal tancar el terminal en què s'està executant Telepresence (acabar la sessió amb Ctrl+C) - Els contenidors Docker s'aturaran a l'escriptori i a Kubernetes tot tornarà al seu estat inicial. Només queda comprometre's, emetre el MR i transferir-lo a revisar/fusionar/... (segons els teus fluxos de treball).

Si no volem executar l'aplicació en un contenidor Docker (per exemple, no desenvolupem en PHP, sinó en Go, i encara la construïm localment), llançar Telepresence serà encara més senzill:

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

Si l'aplicació accedeix a l'API de Kubernetes, haureu de muntar el directori de claus (https://www.telepresence.io/howto/volumes). Hi ha una utilitat per a Linux arrel:

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

Després de llançar Telepresència sense l'opció --docker-run totes les variables d'entorn estaran disponibles al terminal actual, de manera que l'aplicació s'ha de llançar en ell.

NB: Quan utilitzeu, per exemple, PHP, heu de recordar desactivar diversos acceleradors d'op_cache, apc i altres per al desenvolupament; en cas contrari, editar el codi no donarà el resultat desitjat.

Resultats de

El desenvolupament local amb Kubernetes és un problema la solució del qual va creixent en proporció a la difusió d'aquesta plataforma. En rebre les sol·licituds rellevants dels desenvolupadors (dels nostres clients), vam començar a resoldre-les amb els primers mitjans disponibles, que, però, no es van demostrar a llarg termini. Afortunadament, això s'ha fet evident no només ara i no només per a nosaltres, de manera que ja han aparegut mitjans més adequats al món, i la Telepresència és la més famosa (per cert, també hi ha bastidor de Google). La nostra experiència d'utilitzar-lo encara no és tan gran, però ja ens dóna motius per recomanar-lo als nostres "col·legues de la botiga": proveu-ho!

PS

Altres de la sèrie de trucs i consells K8s:

Font: www.habr.com

Afegeix comentari