Tipy a triky Kubernetes: o místním rozvoji a Telepresence

Tipy a triky Kubernetes: o místním rozvoji a Telepresence

Stále častěji jsme dotazováni na vývoj mikroslužeb v Kubernetes. Vývojáři, zejména interpretovaných jazyků, chtějí rychle opravit kód ve svém oblíbeném IDE a vidět výsledek bez čekání na sestavení/nasazení – pouhým stisknutím F5. A pokud šlo o monolitickou aplikaci, stačilo lokálně nainstalovat databázi a webový server (v Dockeru, VirtualBoxu...), a hned si užívat vývoje. S řezáním monolitů do mikroslužeb a příchodem Kubernetes, s výskytem závislostí na sobě, všechno bylo to trochu složitější. Čím více těchto mikroslužeb, tím více problémů. Abyste si opět užili vývoj, musíte získat více než jeden nebo dva kontejnery Docker a někdy i více než tucet... Obecně to vše může zabrat poměrně hodně času, protože je také potřeba udržovat aktuální .

V různých dobách jsme zkoušeli různá řešení problému. A začnu s nahromaděnými řešeními nebo jednoduše „berličkami“.

1. Berle

Většina IDE má schopnost upravovat kód přímo na serveru pomocí FTP/SFTP. Tato cesta je velmi zřejmá a hned jsme se rozhodli ji využít. Jeho podstata se scvrkává na následující:

  1. V modulu vývojových prostředí (dev/review) je spuštěn další kontejner s přístupem SSH a předáváním veřejného klíče SSH vývojáře, který aplikaci potvrdí/nasadí.
  2. V počáteční fázi (v kontejneru prepare-app) přeneste kód na emptyDirmít přístup ke kódu z aplikačních kontejnerů a SSH serveru.

Tipy a triky Kubernetes: o místním rozvoji a Telepresence

Pro lepší pochopení technické implementace takového schématu poskytnu fragmenty zapojených konfigurací YAML v Kubernetes.

Konfigurace

1.1. hodnoty.yaml

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

Zde vasya.pupkin je hodnota proměnné ${GITLAB_USER_LOGIN}.

1.2. nasazení.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. tajemství.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 }}

Konečný dotek

Poté už zbývá jen přenést požadované proměnné 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: vývojář, který spustil nasazení, se může připojit podle názvu služby (jak bezpečně udělit přístup ke clusteru, už jsme řekli) z vašeho počítače přes SFTP a upravte kód, aniž byste čekali na jeho doručení do clusteru.

Toto je zcela funkční řešení, ale z hlediska implementace má zjevné nevýhody:

  • potřeba zpřesnit Helmův diagram, což znesnadňuje čtení v budoucnu;
  • může být používán pouze osobou, která službu nasadila;
  • musíte si pamatovat, že jej pak musíte synchronizovat s místním adresářem s kódem a odevzdat jej Git.

2. Telepřítomnost

projekt Teleprezence je známá už poměrně dlouho, ale my, jak se říká, „nedostali jsme se k tomu, abychom to vážně vyzkoušeli v praxi“. Poptávka však udělala své a my se nyní rádi podělíme o naše zkušenosti, které se mohou čtenářům našeho blogu hodit – tím spíše, že na hubu zatím nebyly žádné další materiály o Telepresence.

Stručně řečeno, všechno se ukázalo být ne tak děsivé. Všechny akce, které vyžadují provedení ze strany vývojáře, jsme umístili do textového souboru Helm chart s názvem NOTES.txt. Po nasazení služby do Kubernetes tedy vývojář vidí pokyny pro spuštění místního vývojového prostředí v protokolu úloh 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
#########################################################################

Nebudeme se podrobně zabývat kroky popsanými v tomto návodu... s výjimkou toho posledního. Co se stane během spuštění Telepresence?

Práce s Telepresence

Při spuštění (pomocí posledního příkazu uvedeného ve výše uvedených pokynech) nastavíme:

  • jmenný prostor, ve kterém mikroslužba běží;
  • názvy nasazení a kontejneru, do kterého chceme proniknout.

Zbývající argumenty jsou volitelné. Pokud naše služba spolupracuje s rozhraním Kubernetes API a pro něj Servisní účet byl vytvořen, potřebujeme připojit certifikáty/tokeny na naši plochu. Chcete-li to provést, použijte možnost --mount=true (nebo --mount=/dst_path), který připojí kořen (/) z kontejneru Kubernetes na naši plochu. Poté můžeme (v závislosti na OS a způsobu spuštění aplikace) používat „klíče“ z clusteru.

Nejprve se podíváme na nejuniverzálnější možnost spuštění aplikace – v kontejneru Docker. K tomu použijeme klíč --docker-run a připojte adresář s kódem do kontejneru: -v `pwd`:/app

Upozorňujeme, že to předpokládá spuštění z adresáře projektu. Kód aplikace bude připojen do adresáře /app v kontejneru.

Další: -v /tmp/app/var/run/secrets:/var/run/secrets — pro připojení adresáře s certifikátem/tokenem do kontejneru.

Po této volbě nakonec následuje obrázek, ve kterém aplikace poběží. NB: Při vytváření obrázku musíte zadat CMD nebo ENTRYPOINT!

Co přesně se bude dít dál?

  • V Kubernetes se pro zadané Deployment změní počet replik na 0. Místo toho bude spuštěno nové Deployment - s náhradním kontejnerem backend.
  • Na ploše se spustí 2 kontejnery: první s Telepresence (bude proxy požadavky z/do Kubernetes), druhý s vyvíjenou aplikací.
  • Pokud execujeme do kontejneru s aplikací, pak nám budou dostupné všechny ENV proměnné přenesené Helmem během nasazení a také všechny služby. Nezbývá než upravit kód ve vašem oblíbeném IDE a užít si výsledek.
  • Na konci práce stačí zavřít terminál, ve kterém běží Telepresence (ukončit relaci Ctrl+C) – Docker kontejnery se na ploše zastaví a v Kubernetes se vše vrátí do výchozího stavu. Zbývá pouze potvrdit, vydat MR a přenést jej do revize/sloučení/… (v závislosti na vašich pracovních postupech).

Pokud nechceme spouštět aplikaci v kontejneru Docker – například nevyvíjíme v PHP, ale v Go, a přesto ji budujeme lokálně – spuštění Telepresence bude ještě jednodušší:

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

Pokud aplikace přistupuje k Kubernetes API, budete muset připojit adresář klíčů (https://www.telepresence.io/howto/volumes). Existuje utilita pro Linux vykořenit:

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

Po spuštění Telepresence bez možnosti --docker-run všechny proměnné prostředí budou dostupné v aktuálním terminálu, takže aplikaci je nutné spustit v něm.

NB: Při použití např. PHP musíte pamatovat na to, abyste pro vývoj zakázali různé op_cache, apc a další akcelerátory – jinak úprava kódu nepovede k požadovanému výsledku.

Výsledky

Lokální vývoj s Kubernetes je problém, jehož řešení roste úměrně s rozšířením této platformy. Po obdržení relevantních požadavků od vývojářů (od našich klientů) jsme je začali řešit prvními dostupnými prostředky, které se však dlouhodobě neosvědčily. To se naštěstí ukázalo nejen nyní a nejen u nás, takže se ve světě již objevily vhodnější prostředky a Telepresence je z nich nejznámější (mimochodem existuje i skaffold od Googlu). Naše zkušenosti s jeho používáním ještě nejsou tak skvělé, ale již nyní nám dává důvod doporučit jej našim „kolegům v obchodě“ – vyzkoušejte!

PS

Další ze série tipů a triků K8s:

Zdroj: www.habr.com

Přidat komentář