Съвети и трикове на Kubernetes: относно местното развитие и телеприсъствието

Съвети и трикове на Kubernetes: относно местното развитие и телеприсъствието

Все по-често ни питат за разработването на микроуслуги в Kubernetes. Разработчиците, особено на интерпретирани езици, искат бързо да коригират кода в любимата си IDE и да видят резултата, без да чакат компилация/разгръщане - просто като натиснат F5. А когато става дума за монолитно приложение, достатъчно е да инсталирате локално база данни и уеб сървър (в Docker, VirtualBox...), след което веднага да се насладите на разработката. С разрязването на монолитите в микроуслуги и пристигането на Kubernetes, с появата на зависимости една от друга, всичко стана малко по-трудно. Колкото повече от тези микроуслуги, толкова повече проблеми. За да се насладите на разработката отново, трябва да създадете повече от един или два Docker контейнера, а понякога дори повече от дузина... Като цяло всичко това може да отнеме доста време, тъй като също трябва да се поддържа актуално .

По различно време опитвахме различни решения на проблема. И ще започна с натрупаните решения или просто „патерици“.

1. Патерици

Повечето IDE имат способността да редактират код директно на сървъра, използвайки FTP/SFTP. Този път е много очевиден и веднага решихме да го използваме. Същността му се свежда до следното:

  1. В групата на среди за разработка (dev/review) се стартира допълнителен контейнер с SSH достъп и препращане на публичния SSH ключ на разработчика, който ще ангажира/разгърне приложението.
  2. В началния етап (в контейнера prepare-app) прехвърлете кода на emptyDirда имате достъп до кода от контейнерите на приложението и SSH сървъра.

Съвети и трикове на Kubernetes: относно местното развитие и телеприсъствието

За да разбера по-добре техническото изпълнение на такава схема, ще предоставя фрагменти от включените YAML конфигурации в Kubernetes.

Конфигурации

1.1. стойности.yaml

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

Тук vasya.pupkin е стойността на променливата ${GITLAB_USER_LOGIN}.

1.2. разгръщане.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. тайна.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 }}

Последно докосване

След това остава само прехвърлянето изисквани променливи 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

Готово: разработчикът, който е стартирал внедряването, може да се свърже по име на услуга (как сигурно да се предостави достъп до клъстера, вече казахме) от вашия работен плот чрез SFTP и редактирайте кода, без да чакате да бъде доставен на клъстера.

Това е напълно работещо решение, но от гледна точка на изпълнение има очевидни недостатъци:

  • необходимостта от прецизиране на диаграмата на Хелм, което затруднява четенето й в бъдеще;
  • може да се използва само от лицето, което е внедрило услугата;
  • трябва да запомните след това да го синхронизирате с локалната директория с кода и да го ангажирате към Git.

2. Телеприсъствие

Проект Телеприсъствие е известен от доста време, но ние, както се казва, „не успяхме да го изпробваме сериозно на практика“. Търсенето обаче свърши своята работа и сега се радваме да споделим нашия опит, който може да бъде полезен за читателите на нашия блог - особено след като все още няма други материали за Telepresence в центъра.

Накратко, всичко се оказа не толкова страшно. Поставихме всички действия, които изискват изпълнение от страна на разработчика, в текстов файл с диаграма Helm, наречен NOTES.txt. По този начин, след внедряване на услугата в Kubernetes, разработчикът вижда инструкции за стартиране на локалната среда за разработка в регистъра на заданията на 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
#########################################################################

Няма да се спираме подробно на стъпките, описани в тази инструкция... с изключение на последната. Какво се случва по време на стартирането на Telepresence?

Работа с телеприсъствие

При стартиране (използвайки последната команда, посочена в инструкциите по-горе), задаваме:

  • пространство от имена, в което се изпълнява микроуслугата;
  • имената на разполагането и контейнера, в които искаме да проникнем.

Останалите аргументи не са задължителни. Ако нашата услуга взаимодейства с и за Kubernetes API ServiceAccount създаден, трябва да монтираме сертификати/токени на нашия работен плот. За да направите това, използвайте опцията --mount=true (Or --mount=/dst_path), който ще монтира root (/) от контейнера на Kubernetes към нашия работен плот. След това можем (в зависимост от операционната система и как се стартира приложението) да използваме „ключовете“ от клъстера.

Първо, нека разгледаме най-универсалния вариант за стартиране на приложение – в Docker контейнер. За да направим това, ще използваме ключа --docker-run и монтирайте директорията с кода в контейнера: -v `pwd`:/app

Моля, обърнете внимание, че това предполага стартиране от директорията на проекта. Кодът на приложението ще бъде монтиран в директорията /app в контейнер.

Следваща: -v /tmp/app/var/run/secrets:/var/run/secrets — за монтиране на директорията със сертификата/токена в контейнер.

Тази опция накрая е последвана от изображението, в което ще работи приложението. NB: Когато създавате изображение, трябва да посочите CMD или ENTRYPOINT!

Какво точно ще се случи след това?

  • В Kubernetes, за посоченото внедряване, броят на репликите ще бъде променен на 0. Вместо това ще бъде стартирано ново внедряване - със заместващ контейнер backend.
  • 2 контейнера ще се стартират на работния плот: първият с Telepresence (ще прокси заявки от/към Kubernetes), вторият с приложението, което се разработва.
  • Ако изпълним в контейнера с приложението, тогава всички ENV променливи, прехвърлени от Helm по време на внедряването, ще бъдат достъпни за нас и всички услуги също ще бъдат достъпни. Всичко, което остава, е да редактирате кода в любимата си IDE и да се насладите на резултата.
  • В края на работата трябва само да затворите терминала, в който работи Telepresence (прекратете сесията с Ctrl+C) - Docker контейнерите ще спрат на работния плот, а в Kubernetes всичко ще се върне в първоначалното си състояние. Всичко, което остава, е да се ангажирате, да издадете MR и да го прехвърлите към преглед/сливане/… (в зависимост от вашите работни процеси).

Ако не искаме да стартираме приложението в контейнер на Docker - например, разработваме не в PHP, а в Go, и все още го изграждаме локално - стартирането на Telepresence ще бъде още по-лесно:

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

Ако приложението има достъп до API на Kubernetes, ще трябва да монтирате директорията с ключове (https://www.telepresence.io/howto/volumes). Има помощна програма за Linux корен:

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

След стартиране на Telepresence без опцията --docker-run всички променливи на средата ще бъдат налични в текущия терминал, така че приложението трябва да се стартира в него.

NB: Когато използвате например PHP, не забравяйте да деактивирате различни op_cache, apc и други ускорители за разработка - в противен случай редактирането на кода няма да доведе до желания резултат.

Резултати от

Локалното развитие с Kubernetes е проблем, чието решение нараства пропорционално с разпространението на тази платформа. Получавайки съответните заявки от разработчици (от наши клиенти), ние започнахме да ги решаваме с първите налични средства, които обаче не се доказаха в дългосрочен план. За щастие, това стана очевидно не само сега и не само за нас, така че в света вече се появиха по-подходящи средства, а Telepresence е най-известният от тях (между другото, има и скеле от Google). Нашият опит с използването му все още не е толкова голям, но вече ни дава основание да го препоръчаме на нашите „колеги в магазина“ - опитайте!

PS

Други от серията съвети и трикове на K8s:

Източник: www.habr.com

Добавяне на нов коментар