Tipy a triky Kubernetes: o miestnom rozvoji a Telepresence

Tipy a triky Kubernetes: o miestnom rozvoji a Telepresence

Čoraz častejšie sa nás pýtajú na vývoj mikroslužieb v Kubernetes. Vývojári, najmä interpretovaných jazykov, chcú rýchlo opraviť kód vo svojom obľúbenom IDE a vidieť výsledok bez čakania na zostavenie/nasadenie – jednoduchým stlačením F5. A keď už išlo o monolitickú aplikáciu, stačilo lokálne nainštalovať databázu a webový server (v Dockeri, VirtualBoxe...) a hneď si užívať vývoj. S rezaním monolitov na mikroslužby a príchodom Kubernetes, s objavením sa závislostí na sebe, všetko bolo to trochu ťažšie. Čím viac týchto mikroslužieb, tým viac problémov. Aby ste si opäť užili vývoj, musíte pozdvihnúť viac ako jeden alebo dva kontajnery Docker a niekedy aj viac ako tucet... Vo všeobecnosti to všetko môže zabrať pomerne veľa času, pretože je tiež potrebné udržiavať aktuálnosť .

V rôznych časoch sme skúšali rôzne riešenia problému. A začnem s nahromadenými riešeniami alebo jednoducho „barlami“.

1. Barle

Väčšina IDE má schopnosť upravovať kód priamo na serveri pomocou FTP/SFTP. Táto cesta je veľmi zrejmá a hneď sme sa ju rozhodli využiť. Jeho podstata sa scvrkáva na nasledovné:

  1. V module vývojových prostredí (dev/review) sa spustí ďalší kontajner s prístupom SSH a preposielaním verejného kľúča SSH vývojára, ktorý aplikáciu zaviaže/nasadí.
  2. V počiatočnom štádiu (v kontajneri prepare-app) preneste kód na emptyDirmať prístup ku kódu z aplikačných kontajnerov a SSH servera.

Tipy a triky Kubernetes: o miestnom rozvoji a Telepresence

Pre lepšie pochopenie technickej implementácie takejto schémy poskytnem fragmenty príslušných konfigurácií YAML v Kubernetes.

Konfigurácie

1.1. hodnoty.yaml

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

Tu vasya.pupkin je hodnota premennej ${GITLAB_USER_LOGIN}.

1.2. nasadenie.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. tajomstvo.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ý dotyk

Potom už zostáva len preniesť požadované premenné 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ár, ktorý spustil nasadenie, sa môže pripojiť podľa názvu služby (ako bezpečne udeliť prístup do klastra, už sme povedali) z pracovnej plochy cez SFTP a upravte kód bez čakania na jeho doručenie do klastra.

Toto je úplne funkčné riešenie, ale z hľadiska implementácie má zjavné nevýhody:

  • potreba spresniť Helmovu tabuľku, čo sťažuje jej čítanie v budúcnosti;
  • môže používať iba osoba, ktorá službu nasadila;
  • musíte si pamätať, že ho potom musíte synchronizovať s lokálnym adresárom s kódom a odovzdať ho Gitu.

2. Teleprítomnosť

Projekt Teleprezencia je známy už pomerne dlho, ale my sme, ako sa hovorí, „nedostali sme to vážne vyskúšať v praxi“. Dopyt však urobil svoje a teraz sa radi podelíme o naše skúsenosti, ktoré môžu byť užitočné pre čitateľov nášho blogu – najmä preto, že na hube zatiaľ neboli žiadne iné materiály o Telepresence.

Skrátka sa ukázalo, že všetko nie je také strašidelné. Všetky akcie, ktoré vyžadujú vykonanie zo strany vývojára, sme umiestnili do textového súboru Helm chart s názvom NOTES.txt. Po nasadení služby do Kubernetes teda vývojár vidí pokyny na spustenie miestneho prostredia pre vývojárov v protokole ú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 sa podrobne zaoberať krokmi popísanými v tomto návode... s výnimkou posledného. Čo sa stane počas spustenia Telepresence?

Práca s Telepresence

Pri spustení (pomocou posledného príkazu uvedeného v pokynoch vyššie) nastavíme:

  • menný priestor, v ktorom je spustená mikroslužba;
  • názvy nasadení a kontajnera, do ktorého chceme preniknúť.

Zvyšné argumenty sú voliteľné. Ak naša služba interaguje s rozhraním Kubernetes API a preň Servisný účet bol vytvorený, musíme na našu plochu pripojiť certifikáty/tokeny. Ak to chcete urobiť, použite možnosť --mount=true (Alebo --mount=/dst_path), ktorý pripojí root (/) z kontajnera Kubernetes na našu plochu. Potom môžeme (v závislosti od operačného systému a spôsobu spustenia aplikácie) použiť „kľúče“ z klastra.

Najprv sa pozrime na najuniverzálnejšiu možnosť spustenia aplikácie – v kontajneri Docker. Na to použijeme kľúč --docker-run a pripojte adresár s kódom do kontajnera: -v `pwd`:/app

Upozorňujeme, že to predpokladá spustenie z adresára projektu. Kód aplikácie bude pripojený do adresára /app v nádobe.

Ďalšie: -v /tmp/app/var/run/secrets:/var/run/secrets — na pripojenie adresára s certifikátom/tokenom do kontajnera.

Po tejto voľbe nakoniec nasleduje obrázok, v ktorom aplikácia pobeží. NB: Pri vytváraní obrázka musíte zadať CMD alebo ENTRYPOINT!

Čo presne bude nasledovať?

  • V Kubernetes sa pre zadané nasadenie zmení počet replík na 0. Namiesto toho sa spustí nové nasadenie – s náhradným kontajnerom backend.
  • Na ploche sa spustia 2 kontajnery: prvý s Telepresence (bude proxy požiadavky z/do Kubernetes), druhý s vyvíjanou aplikáciou.
  • Ak spustíme do kontajnera s aplikáciou, tak nám budú dostupné všetky ENV premenné prenášané Helmom počas nasadenia a budú dostupné aj všetky služby. Zostáva len upraviť kód vo vašom obľúbenom IDE a vychutnať si výsledok.
  • Na konci práce stačí zavrieť terminál, v ktorom beží Telepresence (reláciu ukončiť pomocou Ctrl+C) – Docker kontajnery sa zastavia na ploche a v Kubernetes sa všetko vráti do pôvodného stavu. Zostáva len zaviazať sa, vydať MR a preniesť ho do kontroly/zlúčenia/... (v závislosti od vašich pracovných postupov).

Ak nechceme spúšťať aplikáciu v kontajneri Docker – napríklad nevyvíjame v PHP, ale v Go, a napriek tomu ju vytvárame lokálne – spustenie Telepresence bude ešte jednoduchšie:

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

Ak aplikácia pristupuje k Kubernetes API, budete musieť pripojiť adresár kľúčov (https://www.telepresence.io/howto/volumes). Existuje utilita pre Linux koreň:

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

Po spustení Telepresence bez možnosti --docker-run všetky premenné prostredia budú dostupné v aktuálnom termináli, takže aplikáciu treba spustiť v ňom.

NB: Keď používate napríklad PHP, musíte pamätať na to, aby ste zakázali rôzne op_cache, apc a iné akcelerátory pre vývoj - inak úprava kódu nevedie k požadovanému výsledku.

Výsledky

Lokálny vývoj s Kubernetes je problém, ktorého riešenie rastie úmerne s rozširovaním tejto platformy. Po prijatí relevantných požiadaviek od developerov (od našich klientov) sme ich začali riešiť prvými dostupnými prostriedkami, ktoré sa však dlhodobo neosvedčili. Našťastie sa to ukázalo nielen teraz a nielen u nás, a tak sa už vo svete objavili vhodnejšie prostriedky a z nich je najznámejšia Telepresence (mimochodom, existuje aj skaffold od spoločnosti Google). Naše skúsenosti s jeho používaním ešte nie sú také skvelé, ale už teraz nám dáva dôvod odporučiť ho našim „kolegom v obchode“ – vyskúšajte!

PS

Ďalšie zo série tipov a trikov K8s:

Zdroj: hab.com

Pridať komentár