Mga tip at trick ng Kubernetes: tungkol sa lokal na pag-unlad at Telepresence

Mga tip at trick ng Kubernetes: tungkol sa lokal na pag-unlad at Telepresence

Lalo kaming tinatanong tungkol sa pagbuo ng mga microservice sa Kubernetes. Nais ng mga developer, lalo na sa mga na-interpret na wika, na mabilis na iwasto ang code sa kanilang paboritong IDE at makita ang resulta nang hindi naghihintay ng build/deployment - sa pamamagitan lamang ng pagpindot sa F5. At pagdating sa isang monolitikong aplikasyon, sapat na ang lokal na pag-install ng database at isang web server (sa Docker, VirtualBox...), at pagkatapos ay agad na tamasahin ang pag-unlad. Sa pagputol ng mga monolith sa mga microservice at pagdating ng Kubernetes, na may hitsura ng mga dependency sa isa't isa, lahat medyo nahirapan. Kung mas marami sa mga microservice na ito, mas maraming problema. Upang masiyahan muli sa pag-unlad, kailangan mong magtaas ng higit sa isa o dalawang container ng Docker, at kung minsan ay higit pa sa isang dosena... Sa pangkalahatan, ang lahat ng ito ay maaaring tumagal ng maraming oras, dahil kailangan din itong panatilihing napapanahon. .

Sa iba't ibang pagkakataon sinubukan namin ang iba't ibang solusyon sa problema. At magsisimula ako sa mga naipon na workaround o simpleng "mga saklay".

1. Mga saklay

Karamihan sa mga IDE ay may kakayahang mag-edit ng code nang direkta sa server gamit ang FTP/SFTP. Ang landas na ito ay napakalinaw at agad naming napagpasyahan na gamitin ito. Ang kakanyahan nito ay bumababa sa mga sumusunod:

  1. Sa pod ng mga development environment (dev/review), may inilunsad na karagdagang container na may access sa SSH at pagpapasa ng pampublikong SSH key ng developer na magko-commit/magde-deploy ng application.
  2. Sa yugto ng init (sa loob ng lalagyan prepare-app) ilipat ang code sa emptyDirupang magkaroon ng access sa code mula sa mga lalagyan ng application at sa SSH server.

Mga tip at trick ng Kubernetes: tungkol sa lokal na pag-unlad at Telepresence

Para mas maunawaan ang teknikal na pagpapatupad ng naturang scheme, magbibigay ako ng mga fragment ng mga kasangkot na configuration ng YAML sa Kubernetes.

Mga Configuration

1.1. values.yaml

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

Dito vasya.pupkin ay ang halaga ng variable ${GITLAB_USER_LOGIN}.

1.2. deployment.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. sikreto.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 }}

Huling ugnay

Pagkatapos nito ang natitira na lang ay ang paglipat kinakailangang mga variable ng 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: ang developer na naglunsad ng deployment ay maaaring kumonekta sa pamamagitan ng pangalan ng serbisyo (kung paano secure na magbigay ng access sa cluster, sinabi na namin) mula sa iyong desktop sa pamamagitan ng SFTP at i-edit ang code nang hindi naghihintay na maihatid ito sa cluster.

Ito ay isang ganap na gumaganang solusyon, ngunit mula sa isang punto ng pagpapatupad na ito ay may malinaw na mga kawalan:

  • ang pangangailangang pinuhin ang Helm chart, na nagpapahirap sa pagbabasa sa hinaharap;
  • maaari lamang gamitin ng taong nag-deploy ng serbisyo;
  • kailangan mong tandaan na pagkatapos ay i-synchronize ito sa lokal na direktoryo gamit ang code at i-commit ito sa Git.

2. Telepresence

Proyekto telepresence ay kilala sa mahabang panahon, ngunit kami, tulad ng sinasabi nila, "ay hindi nakarating sa seryosong pagsubok nito sa pagsasanay." Gayunpaman, nagawa na ng demand ang trabaho nito at ngayon ay masaya kaming ibahagi ang aming karanasan, na maaaring maging kapaki-pakinabang sa mga mambabasa ng aming blog - lalo na't wala pang ibang materyales tungkol sa Telepresence sa hub.

Sa madaling salita, ang lahat ay naging hindi nakakatakot. Inilagay namin ang lahat ng pagkilos na nangangailangan ng pagpapatupad sa bahagi ng developer sa isang Helm chart na text file na tinatawag NOTES.txt. Kaya, pagkatapos i-deploy ang serbisyo sa Kubernetes, nakikita ng developer ang mga tagubilin para sa paglulunsad ng local dev environment sa GitLab job log:

!!! Π Π°Π·Ρ€Π°Π±ΠΎΡ‚ΠΊΠ° сСрвиса локально, Π² составС 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
#########################################################################

Hindi namin tatalakayin nang detalyado ang mga hakbang na inilarawan sa pagtuturo na ito... maliban sa huli. Ano ang mangyayari sa paglulunsad ng Telepresence?

Nagtatrabaho sa Telepresence

Sa pagsisimula (gamit ang huling utos na tinukoy sa mga tagubilin sa itaas), itinakda namin:

  • namespace kung saan tumatakbo ang microservice;
  • mga pangalan ng deployment at container na gusto naming ipasok.

Ang natitirang mga argumento ay opsyonal. Kung nakikipag-ugnayan ang aming serbisyo sa at para sa Kubernetes API Nagawa ang ServiceAccount, kailangan naming mag-mount ng mga certificate/token sa aming desktop. Upang gawin ito, gamitin ang opsyon --mount=true (O --mount=/dst_path), na i-mount ang root (/) mula sa container ng Kubernetes papunta sa aming desktop. Pagkatapos nito, maaari naming (depende sa OS at kung paano inilunsad ang application) gamitin ang "mga susi" mula sa kumpol.

Una, tingnan natin ang pinaka-unibersal na opsyon para sa pagpapatakbo ng isang application - sa isang lalagyan ng Docker. Upang gawin ito gagamitin namin ang susi --docker-run at i-mount ang direktoryo na may code sa lalagyan: -v `pwd`:/app

Pakitandaan na ito ay ipinapalagay na tumatakbo mula sa direktoryo ng proyekto. Ang application code ay mai-mount sa direktoryo /app sa isang lalagyan.

Susunod: -v /tmp/app/var/run/secrets:/var/run/secrets β€” upang i-mount ang direktoryo na may certificate/token sa isang lalagyan.

Ang pagpipiliang ito ay sa wakas ay sinusundan ng imahe kung saan tatakbo ang application. NB: Kapag bumubuo ng isang imahe, dapat mong tukuyin CMD o ENTRYPOINT!

Ano nga ba ang susunod na mangyayari?

  • Sa Kubernetes, para sa tinukoy na Deployment, ang bilang ng mga replika ay gagawing 0. Sa halip, isang bagong Deployment ang ilulunsad - na may kapalit na lalagyan backend.
  • 2 container ang ilulunsad sa desktop: ang una ay may Telepresence (ito ay mag-proxy ng mga kahilingan mula/sa Kubernetes), ang pangalawa sa application na binuo.
  • Kung ipapatupad namin ang container na may application, magiging available sa amin ang lahat ng variable ng ENV na inilipat ng Helm sa panahon ng deployment, at magiging available din ang lahat ng serbisyo. Ang natitira na lang ay i-edit ang code sa iyong paboritong IDE at tamasahin ang resulta.
  • Sa pagtatapos ng trabaho, kailangan mo lamang isara ang terminal kung saan tumatakbo ang Telepresence (tapusin ang session gamit ang Ctrl+C) - Hihinto ang mga lalagyan ng Docker sa desktop, at sa Kubernetes lahat ay babalik sa paunang estado nito. Ang natitira na lang ay i-commit, i-issue ang MR at ilipat ito para suriin/pagsamahin/… (depende sa iyong mga workflow).

Kung hindi namin gustong patakbuhin ang application sa isang Docker container - halimbawa, hindi kami nagde-develop sa PHP, ngunit sa Go, at ginagawa pa rin ito nang lokal - ang paglulunsad ng Telepresence ay magiging mas simple:

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

Kung maa-access ng application ang Kubernetes API, kakailanganin mong i-mount ang direktoryo ng mga key (https://www.telepresence.io/howto/volumes). Mayroong isang utility para sa Linux ugat:

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

Matapos ilunsad ang Telepresence nang walang opsyon --docker-run lahat ng mga variable ng kapaligiran ay magiging available sa kasalukuyang terminal, kaya dapat na ilunsad ang application dito.

NB: Kapag gumagamit, halimbawa, PHP, dapat mong tandaan na huwag paganahin ang iba't ibang op_cache, apc at iba pang mga accelerator para sa pag-unlad - kung hindi, ang pag-edit ng code ay hindi hahantong sa nais na resulta.

Mga resulta ng

Ang lokal na pag-unlad kasama ang Kubernetes ay isang problema na ang solusyon ay lumalaki sa proporsyon sa pagkalat ng platform na ito. Pagtanggap ng mga nauugnay na kahilingan mula sa mga developer (mula sa aming mga kliyente), sinimulan naming lutasin ang mga ito gamit ang unang magagamit na paraan, na, gayunpaman, ay hindi napatunayan ang kanilang mga sarili sa mahabang panahon. Sa kabutihang palad, ito ay naging malinaw hindi lamang ngayon at hindi lamang sa amin, kaya mas angkop na paraan ang lumitaw na sa mundo, at ang Telepresence ay ang pinakasikat sa kanila (sa pamamagitan ng paraan, mayroon ding skaffold mula sa Google). Ang aming karanasan sa paggamit nito ay hindi pa napakahusay, ngunit nagbibigay na ito sa amin ng dahilan upang irekomenda ito sa aming "mga kasamahan sa tindahan" - subukan ito!

PS

Iba pa mula sa serye ng mga tip at trick ng K8:

Pinagmulan: www.habr.com

Magdagdag ng komento