В этой статье мы рассмотрим подход, при котором разработка приложений ведется непосредственно в кластере Kubernetes, а отдельные операции сборки и деплоя оказываются не нужны. Такую возможность предоставляет сервис Okteto Cloud и одноименная Open Source-утилита от его разработчиков. Идея проекта — сэкономить много времени и сосредоточиться на программировании, не забивая голову подготовкой и настройкой окружения. 

С чего все начиналось

При разработке приложений, предназначенных для последующего деплоя в Kubernetes, главной трудностью перед началом работы является непосредственно сам кластер Kubernetes. Разработчику недостаточно просто уметь программировать — ему нужна также и сопутствующая инфраструктура. В её роли могут быть:

  • Локальный кластер, самостоятельно поднятый на машине разработчика или в доступной ему локальной сети.

  • Полноценный тестовый стенд, развернутый DevOps-инженерами компании на ее инфраструктуре и включающий в себя настроенные пайплайны непрерывной доставки (CI). 

В обоих случаях есть существенные ограничения, из-за которых начало разработки может откладываться на долгий срок. Это и отсутствие у разработчика знаний и навыков работы с Kubernetes, и отсутствие нужных мощностей рабочего железа, и длительное ожидание, пока нужное окружение будет поднято в инфраструктуре компании.

Решить эти проблемы можно по-разному, и Okteto предлагает один из таких способов. Использование этого продукта позволяет перенести разработку приложения сразу в готовое окружение, минуя стадию долгой подготовки.

Okteto можно разделить на две важных части:

  1. Система управления кластером со встроенной системой сборки:

    • Okteto Cloud — managed Kubernetes с расширенными возможностями. Позволяет в графическом режиме управлять сборочными контейнерами и настраивать все необходимое для разработки;

    • Okteto Enterprise — корпоративная версия системы управления  Okteto, предназначенная для установки в K8s-кластер вашей организации. Для этого понадобится приобрести лицензию, но есть и бесплатный вариант для небольших команд (до трех человек). Установленная на любой кластер Okteto Cloud Enterprise превращает его в полноценный Okteto Cloud на вашей инфраструктуре.

  2. Okteto CLI — Open Source-утилита командной строки для работы с кластером Kubernetes. Поддерживаются как кластеры под управлением Okteto Cloud, так и любые другие, к которым есть доступ через kubectl.

Для установки Enterprise-версии системы разработчики рекомендуют кластер со следующими минимальными характеристиками:

  • Kubernetes версии v1.19 или выше.

  • Пул из минимум 3 узлов с 4 CPU и 16 GB оперативной памяти.

  • 100 GB пространства на диске.

 Установка поддерживается на решения от популярных облачных провайдеров:

  • Amazon Elastic Kubernetes Service;

  • Azure Kubernetes Service;

  • Google Kubernetes Engine;

  • DigitalOcean Kubernetes.

Для этого предлагается Helm-чарт, включающий в себя все необходимые компоненты системы, такие как NGINX Ingress, cert-manager и другие части Okteto, необходимые для запуска Enterprise-версии. 

Отдельно стоит заметить, что авторы Okteto позволяют бесплатно ознакомиться с системой в своем облаке. После регистрации пользователь может бесплатно работать, имея ограниченные ресурсы:

  • 5 пространств имен; 

  • 10 Pod’ов;

  • 1 CPU на Pod,

  • 3 GB RAM на Pod;

  • 5 GB доступного места.

Как это работает

Принцип работы достаточно прост:

  1. В Kubernetes-кластере, где будет вестись разработка, создается отдельное пространство имен, содержащее один специальный Pod. 

  2. Внутри Pod’а поднимается контейнер со всем необходимым для запуска приложения: компиляторы, интерпретаторы и т.д.

  3. Исходный код разрабатываемого приложения будет синхронизироваться с содержимым контейнера, для чего используется Open Source-утилита Syncthing. Синхронизация работает в обе стороны и в режиме реального времени: любые изменения, внесенные в код приложения на машине пользователя или напрямую в контейнере, автоматически синхронизируются с противоположной стороной.

  4. Для управления запуском и тестированием приложения пользователю предоставляется shell-интерфейс, проброшенный внутрь контейнера. 

Из дополнительных особенностей стоит отметить возможность проброса нужных портов из контейнера на машину пользователя. Это может быть необходимо для работы, например, со встроенным в контейнер дебаггером.

Okteto поддерживает большое количество языков программирования, предлагая контейнеры, подготовленные для разработки в них приложений на соответствующем стеке. Также по всем этим языкам авторы предоставляют исчерпывающие инструкции, что позволит начать работу достаточно быстро.

Разработка в Okteto и традиционный подход CI

Okteto стремится дать разработчикам возможность сосредоточиться на главном для них, не отвлекаясь на детали организации CI/CD. Для этого измененный код не требует никаких операций, а сразу же синхронизируется с контейнером в K8s-кластере, собирается в нем и оказывается готов к работе.

Авторы Okteto не без оснований называют подобный подход к разработке cloud native way. У них есть целая статья об этом, где описаны все плюсы и минусы, а также более подробно рассмотрены его принципы. 

Следование этому пути делает традиционные CI-системы ненужными в рамках процесса разработки. Промежуточные звенья, такие как коммиты в удаленные Git-репозитории, сборочные машины, хранилище контейнеров (container registry) и так далее, больше не требуются, а все их функции сведены к сохранению изменений в приложении и перезапуску удаленной сборки в сборочном контейнере.

Okteto CLI

Okteto CLI — это Open Source-утилита, написанная на языке программирования Go. Она довольно быстро развивается: релизы стабильно выходят до нескольких раз в месяц, а ее репозиторий на GitHub собрал уже более 2300 звезд. За это стоит выразить благодарность 48 разработчикам, активность которых можно наблюдать в репозитории.

Работа утилиты поддерживается во всех основных операционных системах: Linux, macOS и Windows. Скачать готовую сборку под вашу ОС можно из релизов в репозитории: просто качаем нужную версию и кладем в каталог, доступный в $PATH.

С ее помощью можно как управлять проектом, выгруженным из Okteto Cloud (например, из GitHub, как будет рассмотрено далее), так и сгенерировать новый проект, готовый к развертыванию не только в Okteto Cloud, но и любом другом кластере Kubernetes.

Да, Okteto CLI поддерживает работу с любым кластером K8s: для этого необходимо, чтобы в системе был настроен доступ к нему с использованием kubectl.

Обратите внимание! Несмотря на то, что утилиту можно использовать с любым кластером, делать это без установки на него Enterprise-версии Okteto Cloud — спорное решение. После установки система берет на себя многие вещи, начиная от container registry и заканчивая web-интерфейсом (полный список компонентов Okteto Enterprise можно посмотреть на официальном сайте). Использование же «голой» утилиты позволит просто развернуть в кластере dev-контейнер и работать с ним, но не предоставит средств для удобного управления всем процессом.

Для доступа к кластеру Okteto Cloud необходимо войти в систему под своей учетной записью. Сделать это можно прямо из утилиты — предложение пройти аутентификацию появится сразу же, как только в качестве контекста будет выбран https://cloud.okteto.com. В веб-интерфейсе системы есть подсказка, как выбрать контекст нужного кластера:

После выполнения команды утилита предложит открыть системный браузер по умолчанию и войти в Okteto Cloud.

Знакомство с Okteto Cloud

Возможности системы

Помимо сборки и запуска приложения в контейнерах Okteto Cloud предоставляет некоторые дополнительные возможности, например:

  • Автоматическое подключение SSL-шифрования к вашему приложению (доступ по HTTPS).

  • Build service — дополнительные сервисы для сборки приложения, аналог GitLab Runners.

  • Container registry.

  • Preview environments (на каждый push в репозиторий будет разворачиваться предварительный просмотр новой версии приложения).

  • Добавление Secret’ов (например, для доступа к БД).

  • Возможность поделиться пространством имен с коллегами. На указанный email придет приглашение, пройдя по которому, пользователь сможет получить доступ к вашему пространству имен и созданным в нем Pod’ам.

Ценовая политика

Всего авторы предоставляют для использования четыре тарифных плана, один из которых — бесплатный — был упомянут выше. Следующий план называется «Developer Pro», стоит 19 USD за пользователя в месяц и включает в себя чуть большие выделяемые мощности:

  • 10 пространств имен;

  • 20 Pod’ов;

  • 2 CPU на Pod,

  • 6 GB RAM на Pod;

  • 20 GB доступного места.

Ценник по двум оставшимся тарифным планам (Teams и Enterprise) доступен по запросу.

Регистрация и начало работы

Работа с Okteto подразумевает быстрый запуск вашего приложения в кластере под управлением Okteto Cloud. После регистрации в системе дается возможность выбрать в качестве источника ресурсов для развертывания приложения один из вариантов:

  • Непосредственный деплой с помощью Okteto CLI. Для работы с утилитой потребуется выгрузить из Okteto Cloud учетные данные для пространства имен в системе и работать с облаком напрямую из своего терминала. При этом развертывание приложения происходит вручную после запуска соответствующей команды.

  • GitHub-репозиторий или другой Git-репозиторий. В панели управления указывается ссылка на свой репозиторий, и после нажатия на кнопку «Launch» начнется поиск в репозитории необходимых для деплоя файлов: Helm charts, Kubernetes manifests, Okteto stacks (аналог Docker Swarm), docker-compose или Okteto manifests. Также есть возможность указать в файле okteto-pipeline.yml дополнительные параметры сборки и деплоя приложения, если это требуется.

  • Helm-каталог. Позволяет поднять заранее подготовленные инфраструктурные компоненты, необходимые для вашего приложения. Например, MongoDB, Redis, RabbitMQ, MySQL и т.д.

    Авторы обещают поддержку многих сервисов, но если все же чего-то не хватает, то можно оформить им issue в репозитории с просьбой добавить необходимое.

Практика разработки в Okteto Cloud

Для примера рассмотрим запуск и разработку в Okteto Cloud простого приложения, написанного на Go. Приложение делает лишь одно действие — при запросе на endpoint / возвращает ответ «Hello from Okteto!»:

package main
 
import (
	"fmt"
	"net/http"
)
 
func main() {
	fmt.Println("Starting hello-world server...")
	http.HandleFunc("/", helloServer)
	if err := http.ListenAndServe(":8080", nil); err != nil {
		panic(err)
	}
}
 
func helloServer(w http.ResponseWriter, r *http.Request) {
	fmt.Fprint(w, "Hello from Okteto!")
}

Чтобы все заработало, необходимо к исходному коду приложения добавить Dockerfile и файл с инструкциями для Okteto. Положим их рядом с файлом main.go в корне репозитория. Содержимое тестового проекта будет выглядеть так:

.
├── Dockerfile
├── main.go
└── okteto.yml

В Dockerfile указаны инструкции для сборки контейнера с приложением, а в файле okteto.yml — настройки для Okteto: каталог для синхронизации, пробрасываемые порты и так далее.

Dockerfile — стандартный для приложения на Go:

FROM golang:buster
COPY . /app
RUN cd /app && \
    go build main.go && \
    chmod +x main
CMD /app/main.go

Содержимое okteto.yml:


name: okteto-test
autocreate: true
image: okteto/golang:1
command: bash
securityContext:
  capabilities:
    add:
    - SYS_PTRACE
sync:
# Каталог, куда будет синхронизироваться проект.
- .:/usr/src/app
forward:
- 2345:2345
- 8080:8080 # Проброс локальных портов.
persistentVolume:
  enabled: true 

Примечание. Исходные коды этого проекта доступны в нашем репозитории examples.

Перейдем в web-интерфейс Okteto Cloud. Для начала создадим новое окружение (Dev Environment). Затем выберем в качестве источника GitHub.

Вставим ссылку на репозиторий с проектом и нажмем «Launch». Система найдет в корне проекта Dockerfile, после чего соберет и запустит в соответствии с ним контейнер:

Проверим, что все запустилось и работает, выполнив запрос на endpoint по адресу, присвоенному проекту в Okteto Cloud:

curl https://okteto-test-alexey-demyanov.cloud.okteto.net/                                                     
Hello from Okteto!

Получить адрес, по которому доступно запущенное приложение, можно так же в админ-панели Okteto Cloud. Ссылка расположена в левом верхнем углу в разделе Endpoints:

Сейчас тестовое приложение просто запущено в кластере Okteto и работает. Попробуем что-нибудь в нем изменить. Для этого запустим dev-контейнер для разработки приложения. 

Склонируем себе проект с GitHub и перейдем в его корневой каталог. Теперь  воспользуемся утилитой Okteto CLI (она должна быть предварительно установлена в системе):

okteto up

В результате выполнения команды контейнер, ранее собранный и запущенный по файлу Dockerfile из репозитория на GitHub, будет заменен на dev-контейнер, определенный в okteto.yml:

Using alexey-demyanov @ cloud.okteto.com as context
 ✓  Persistent volume successfully attached
 ✓  Files synchronized
    Context:   cloud.okteto.com
    Namespace: alexey-demyanov
    Name:      okteto-test
    Forward:   2345 -> 2345
               8080 -> 8080

Welcome to your development container. Happy coding!

alexey-demyanov:okteto-test app> ls -la
total 24
drwxrwsr-x 2 root root 4096 Apr  3 22:14 .
drwxr-xr-x 1 root root 4096 Nov  9 01:11 ..
-rw-r--r-- 1 root root  109 Apr  3 22:14 .stignore
-rw-rw-r-- 1 root root  111 Apr  3 22:07 Dockerfile
-rw-rw-r-- 1 root root  311 Apr  3 22:03 main.go
-rw------- 1 root root  240 Apr  3 20:46 okteto.yml

При этом сразу же будет предоставлен shell-интерфейс внутрь созданного контейнера: терминал находится в контейнере и готов к работе. Код проекта уже синхронизирован с контейнером и также готов к изменениям.

Модифицируем код приложения, заменив текст ответа на Hello User!:

fmt.Fprint(w, "Hello User!")

Обратите внимание, что сделать это можно как на локальной машине, так и напрямую в контейнере — код сразу же будет синхронизирован с противоположной стороной.

Запустим приложение в контейнере еще раз:

alexey-demyanov:okteto-test app> go run main.go
Starting hello-world server...

Проверим изменения:

curl https://okteto-test-alexey-demyanov.cloud.okteto.net/
Hello User! 

Поскольку Okteto пробросил указанные в конфигурационном файле порты на локальную машину, обратиться к запущенному приложению можно не только по адресу удаленного кластера, но и так, как если бы приложение было запущено локально:

curl 127.0.0.1:8080                                                     
Hello User!

Остановим разработку, нажав кнопку «Stop Development», сделаем push наших изменений в Git-репозиторий и, при необходимости, снова выкатим приложение в Okteto Cloud, как сделали в самом начале.

Как видно из примера, никаких промежуточных шагов в виде сборки контейнера, деплоя его в кластер и запуска не потребовалось. Изменения вносились прямо в код, после чего внутри контейнера происходил перезапуск приложения и сразу же был доступен результат. 

Сравнение с werf и Skaffold

Подход чем-то похож на локальную разработку с werf или разработку со Skaffold, но сборка и тестирование приложения происходят сразу в рабочем кластере, не требуя подготовки локального окружения. werf и Skaffold также могут работать с любым удаленным кластером, к которому у них есть доступ через kubectl, но они всегда будут следовать привычному процессу CI/CD, стремясь сохранять идентичность окружений и конфигурации.

Okteto предлагает мгновенную среду разработки (готовый K8s-кластер, container registry, сборщик образов) и механизм организации «песочницы», который позволяет вести разработку прямо в кластере и изменять код приложения как локально на машине разработчика, так и напрямую в контейнере компонента — изменения синхронизируются в обе стороны.

Несмотря на то, что Okteto, как и оба других решения, можно назвать оберткой над шагами доставки (элементами пайплайна), оно явно отделяет процесс разработки от доставки и не претендует на покрытие или какое-либо улучшение последнего. Таким образом, полностью доставка покрывается только в простых случаях, а в остальных необходимо использование дополнительных инструментов. 

Режим разработки в Skaffold и werf предлагает использовать идентичное окружение, конфигурацию и процесс сборки, а Okteto в свою очередь «песочницу», которая никак не ограничивает пользователя. Соответственно, конфигурация «песочницы» и CI/CD — «два мира по соседству»: их синхронизация полностью на совести пользователя, а результат, которого удалось достичь в процессе разработки, не обязательно сохранит свою работоспособность при выкате в production-окружение.

В любом случае, это довольно удобный способ разработки, и выбор инструмента в зависимости от требований к приложению всегда остается за разработчиками: упростить процесс и получить относительную свободу или сохранять идентичность конфигурации во время доставки, пожертвовав при этом немного времени на прохождение всех стадий CI/CD-пайплайна.

Выводы

Okteto — это не просто софт или ещё одно облако, а подход к разработке, позволяющий избавить разработчика от многих ресурсоемких и затратных по времени процессов. Он позволяет сосредоточиться только на непосредственной работе, минуя стадии подготовки окружения и настройки кластера. 

При этом разработчику остаются доступны все удобства с обеих сторон: и дебаггер для отладки приложения, и быстрый «локальный» запуск, и полностью сконфигурированное окружение рабочего кластера, что минимизирует появление ошибок из-за несоответствий между локальным или тестовым стендом и production-окружением.

Несомненным плюсом является возможность бесплатно протестировать предоставляемые возможности, чтобы понять, насколько такой подход к разработке вам удобен, а также бесплатно установить Okteto Enterprise на ваш кластер для небольшой команды.

P.S.

Читайте также в нашем блоге:

Комментарии (1)


  1. EvilShadow
    09.06.2022 11:53
    +2

    Следование этому пути делает традиционные CI-системы ненужными в рамках
    процесса разработки. Промежуточные звенья, такие как коммиты в удаленные
    Git-репозитории, сборочные машины, хранилище контейнеров (container
    registry) и так далее, больше не требуются

    Следующий шаг - убрать лишние сущности типа Kubernetes и Syncthing и загружать код прямо на машины. Например, по FTP. Это делает традиционные CI-системы ненужными и обеспечивает просто феноменальную скорость работы. А в веб-разработке можно пойти и дальше и встраивать исполняемый код прямо в HTML страницы. Исключительно для удобства.