Kubernetes tips & tricks: over lokale ontwikkeling en Telepresence

Kubernetes tips & tricks: over lokale ontwikkeling en Telepresence

We krijgen steeds vaker vragen over het ontwikkelen van microservices in Kubernetes. Ontwikkelaars, vooral van geïnterpreteerde talen, willen snel code in hun favoriete IDE corrigeren en het resultaat zien zonder te wachten op build/implementatie - door simpelweg op F5 te drukken. En als het om een ​​monolithische applicatie ging, volstond het om lokaal een database en een webserver te installeren (in Docker, VirtualBox...), en dan meteen te genieten van de ontwikkeling. Met het opsplitsen van monolieten in microservices en de komst van Kubernetes, met de schijn van afhankelijkheid van elkaar, is alles het werd iets moeilijker. Hoe meer van deze microservices, hoe meer problemen. Om weer van de ontwikkeling te kunnen genieten, moet je meer dan een of twee Docker-containers grootbrengen, en soms zelfs meer dan een dozijn... Over het algemeen kan dit allemaal behoorlijk wat tijd in beslag nemen, omdat het ook up-to-date moet worden gehouden .

Op verschillende momenten probeerden we verschillende oplossingen voor het probleem. En ik zal beginnen met de verzamelde oplossingen of simpelweg ‘krukken’.

1. Krukken

De meeste IDE's hebben de mogelijkheid om code rechtstreeks op de server te bewerken met behulp van FTP/SFTP. Dit pad ligt heel voor de hand en we hebben meteen besloten om het te gebruiken. De essentie komt neer op het volgende:

  1. In de pod van ontwikkelomgevingen (dev/review) wordt een extra container gelanceerd met SSH-toegang en die de publieke SSH-sleutel doorstuurt van de ontwikkelaar die de applicatie gaat committen/implementeren.
  2. In de init-fase (in de container prepare-app) breng de code over naar emptyDirom toegang te krijgen tot de code vanuit de applicatiecontainers en de SSH-server.

Kubernetes tips & tricks: over lokale ontwikkeling en Telepresence

Om de technische implementatie van een dergelijk schema beter te begrijpen, zal ik fragmenten van de betrokken YAML-configuraties in Kubernetes leveren.

Configuraties

1.1. waarden.yaml

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

Hier vasya.pupkin is de waarde van de variabele ${GITLAB_USER_LOGIN}.

1.2. implementatie.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. geheim.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 }}

Laatste greep

Daarna rest alleen nog de overdracht vereiste gitlab-ci.yml variabelen:

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: de ontwikkelaar die de implementatie heeft gelanceerd, kan verbinding maken via de servicenaam (hoe u veilig toegang kunt verlenen tot het cluster, we hebben het al verteld) vanaf uw bureaublad via SFTP en bewerk de code zonder te wachten tot deze bij het cluster wordt afgeleverd.

Dit is een volledig werkende oplossing, maar vanuit implementatieoogpunt heeft het duidelijke nadelen:

  • de noodzaak om de Helm-grafiek te verfijnen, waardoor deze in de toekomst moeilijk leesbaar wordt;
  • kan alleen worden gebruikt door degene die de dienst heeft ingezet;
  • je moet onthouden om het vervolgens te synchroniseren met de lokale map met de code en het vast te leggen in Git.

2. Teleaanwezigheid

Project telepresence is al heel lang bekend, maar wij, zoals ze zeggen, “zijn er niet in geslaagd het serieus in de praktijk te proberen.” De vraag heeft echter zijn werk gedaan en nu delen we graag onze ervaringen, die nuttig kunnen zijn voor de lezers van onze blog - vooral omdat er nog geen ander materiaal over Telepresence op de hub is verschenen.

Kortom, alles bleek niet zo eng te zijn. We hebben alle acties die uitvoering van de kant van de ontwikkelaar vereisen, geplaatst in een Helm-diagramtekstbestand genaamd NOTES.txt. Dus na het implementeren van de service in Kubernetes ziet de ontwikkelaar instructies voor het starten van de lokale ontwikkelomgeving in het GitLab-takenlogboek:

!!! Разработка сервиса локально, в составе 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
#########################################################################

We zullen niet in detail ingaan op de stappen die in deze instructie worden beschreven... met uitzondering van de laatste. Wat gebeurt er tijdens de lancering van Telepresence?

Werken met Telepresence

Bij het opstarten (met behulp van de laatste opdracht gespecificeerd in de bovenstaande instructies) stellen we het volgende in:

  • naamruimte waarin de microservice draait;
  • namen van de implementatie en container die we willen binnendringen.

De overige argumenten zijn optioneel. Als onze service communiceert met en voor de Kubernetes API ServiceAccount aangemaakt, moeten we certificaten/tokens op onze desktop mounten. Gebruik hiervoor de optie --mount=true (Of --mount=/dst_path), waarmee de root (/) van de Kubernetes-container naar onze desktop wordt gemount. Hierna kunnen we (afhankelijk van het besturingssysteem en hoe de applicatie wordt gestart) de “sleutels” uit het cluster gebruiken.

Laten we eerst eens kijken naar de meest universele optie voor het uitvoeren van een applicatie: in een Docker-container. Om dit te doen, zullen we de sleutel gebruiken --docker-run en mount de map met de code in de container: -v `pwd`:/app

Houd er rekening mee dat hierbij wordt aangenomen dat het vanuit de projectmap wordt uitgevoerd. De applicatiecode wordt in de directory gemount /app in een container.

Volgende: -v /tmp/app/var/run/secrets:/var/run/secrets — om de directory met het certificaat/token in een container te mounten.

Deze optie wordt tenslotte gevolgd door de afbeelding waarin de applicatie zal draaien. NB: Wanneer u een afbeelding maakt, moet u dit opgeven CMD of ENTRYPOINT!

Wat gaat er nu precies gebeuren?

  • In Kubernetes wordt voor de opgegeven implementatie het aantal replica's gewijzigd in 0. In plaats daarvan wordt een nieuwe implementatie gelanceerd - met een vervangende container backend.
  • Er worden twee containers op de desktop gelanceerd: de eerste met Telepresence (die verzoeken van/naar Kubernetes proxy), de tweede met de applicatie die wordt ontwikkeld.
  • Als we met de applicatie de container ingaan, zijn alle ENV-variabelen die tijdens de implementatie door Helm zijn overgedragen voor ons beschikbaar en zijn alle services ook beschikbaar. Het enige dat overblijft is om de code in uw favoriete IDE te bewerken en van het resultaat te genieten.
  • Aan het einde van het werk hoeft u alleen maar de terminal te sluiten waarin Telepresence draait (de sessie beëindigen met Ctrl+C) - Docker-containers stoppen op het bureaublad en in Kubernetes keert alles terug naar de oorspronkelijke staat. Het enige dat overblijft is het vastleggen, het uitgeven van de MR en het overbrengen naar beoordeling/samenvoegen/... (afhankelijk van uw workflows).

Als we de applicatie niet in een Docker-container willen draaien - we ontwikkelen bijvoorbeeld niet in PHP, maar in Go, en bouwen deze toch lokaal - zal het lanceren van Telepresence nog eenvoudiger zijn:

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

Als de applicatie toegang heeft tot de Kubernetes API, moet u de sleutelsmap koppelen (https://www.telepresence.io/howto/volumes). Er is een hulpprogramma voor Linux wortel:

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

Na het lanceren van Telepresence zonder de optie --docker-run alle omgevingsvariabelen zullen beschikbaar zijn in de huidige terminal, dus de applicatie moet daarin worden gestart.

NB: Wanneer u bijvoorbeeld PHP gebruikt, moet u eraan denken om verschillende op_cache, apc en andere ontwikkelingsversnellers uit te schakelen - anders zal het bewerken van de code niet tot het gewenste resultaat leiden.

Resultaten van

Lokale ontwikkeling met Kubernetes is een probleem waarvan de oplossing groeit in verhouding tot de verspreiding van dit platform. Toen we relevante verzoeken van ontwikkelaars (van onze klanten) ontvingen, begonnen we deze op te lossen met de eerste beschikbare middelen, die zich echter op de lange termijn niet bewezen hebben. Gelukkig is dit niet alleen nu en niet alleen voor ons duidelijk geworden, dus er zijn al geschiktere middelen in de wereld verschenen, en Telepresence is de bekendste daarvan (er is trouwens ook schavot van Google). Onze ervaring met het gebruik ervan is nog niet zo geweldig, maar het geeft ons nu al reden om het aan onze “collega's in de winkel” aan te bevelen - probeer het!

PS

Overige uit de K8s tips & tricks serie:

Bron: www.habr.com

Voeg een reactie