Как все члены наших проектных команд вдруг стали немножко DevOps’ами
Привет, Хабр! Мы недавно с коллегами читали статью компании Flant о динамических окружениях в GitLab и хотели бы поделиться с вами мыслями о том, почему мы эту, казалось бы, очень долгожданную и классную фичу не используем. Не потому что она плохая, а потому что организационно мы хотели получить решение, которое было бы доступно для использования всеми членами проектных команд, а не только DevOps-инженерами.
В этом посте мы рассказываем, почему нам не подошли средства GitLab, что мы хотели получить взамен и к какому альтернативному решению пришли. Если вам тоже хочется попробовать применить это решения для организации процессов в своих проектах, мы подготовили небольшой туториал, который поможет вам начать.

Введение
Самое основное отличие того, что мы хотели получить, от того, что нам дают CI системы, заключается в том, кто является основным пользователем динамических окружений. На нашем опыте это менеджеры, тестировщики, разработчики и стейкхолдеры проекта. Обратите внимание что это не DevOps инженеры, которые являются единоличными держателями ключей от настроек в CI/CD системах и, как следствие, Gitlab. Было бы здорово, чтобы тестировщики могли себе создать отдельное тестовое окружение, или руководитель проекта мог перенастроить стейджинг без необходимости обсуждать порядок задач в бэклоге у DevOps, правда?
Как это сделать? Нужен некий self-service, т.е. автоматизированный процесс, позволяющий юзерам взаимодействовать с серверами/кластером. В какой-то момент мы все перестали задумываться о том, как сбросить пароль на вебсайте. А ведь это простейший пример self-service портала для пользователей! Только представьте, что иначе вам бы пришлось писать письмо менеджеру и попросить прислать новый пароль вам заказным письмом по физической почте.

Точно так же мы можем революционизировать и то, как мы оркестрируем тестовые окружения для новых фич. Наша реализация такого подхода называется Octopod, и как пример инструмента, иллюстрирующего подход, мы будем использовать именно его.
Octopod является инструментом универсальным и не привязанным к какому-то конкретному способу управления пакетами в Kubernetes. Тем не менее, он главным образом призван значительно упростить развертывание именно Helm-чартов, как стандарт де-факто в мире Kubernetes. В Typeable мы используем Helm, поэтому стандартная поставка Octopod начиная с версии 1.4 уже включает все необходимое для работы с этой утилитой.
Основные отличия от GitLab
Самое, пожалуй, главное это то, что мы начали работать с review-окружениями раньше, чем в GitLab появился интерфейс для работы с динамическими окружениями. Но есть и ряд других причин, в том числе и наше идеологическое отличие в подходе к реализации и использованию review-окружений. Но, давайте обо всем по порядку.
- 
Мы не храним конфигурацию окружения в коде. Почему? Мы намеренно хотим отвязать окружение от кода и на это у нас есть несколько причин. - Не все сотрудники имеют доступ к коду. Наши процессы выстроены таким образом, что аналитики, тестировщики, менеджеры проектов и другие члены команды, которые не пишут код, доступ в репозиторий обычно имеют только на чтение, а то и не имеют его вовсе. Такой подход позволяет нам лучше управлять кодом и иметь меньше рисков и потенциальных проблем. Но им нужна возможность самостоятельно создавать review-окружения, не привлекая DevOps-инженера или разработчика. 
- В GitLab для управления динамическим окружением нужно сначала создать, а затем при необходимости модифицировать файл .gitlab-ci.yml. Таким образом, в каждой ветке кода будет свой такой файл с необходимыми настройками окружения. Есть риск того, что настройки “утекут” в основную ветку, и новые окружения будут иметь неверные параметры. Это нужно как-то решать, и gitflow от этого становится только сложнее за счёт потенциального увеличения количества конфликтов и, как следствие, мерджей или ребейзов. 
- Нам часто приходится вносить изменения в конфигурацию review-окружения. В Octopod легко изменять параметры, переменные окружения, а главное – переключаться между различными endpoint в сервисах, с которыми мы интегрированы. У нас очень много интеграций с внешними системами и не всегда можно протестировать функциональность приложения при подключении к тестовому API. Зачастую требуется взаимодействие с production API. 
 Таким образом, настройки review-окружения хранятся в Octopod и управляются через Web-интерфейс или CLI Octopod’а (octo CLI) и полностью изолированы от кода.
 
- 
Переменные окружения в GitLab глобальны для проекта. Множество параметров review-окружения передается через переменные окружения. GitLab предоставляет интерфейс для указания переменных окружения (Variables) без внесения изменений в .gitlab-ci.yml, но эти переменные имеют глобальный скоуп, то есть распространяются на все динамические окружения проекта. Единственная возможность прописать переменные окружения для конкретного review-environment – это внести их в .gitlab-ci.yml в соответствующей ветке, а это противоречит пункту 1. 
 В Octopod мы решили эту проблему с помощью Application Configuration и Deployment Configuration. Octopod генерирует список параметров ключ-значение, который позволяет видеть в UI возможные настройки чарта и управлять ими. Достаточно выбрать нужный ключ и прописать значение. Также можно указывать кастомные ключи, которые отсутствуют в списке. Мы предусмотрели два вида настроек конфигурации: Application Configuration и Deployment Configuration. Application Configuration – это конфигурация (Helm values), которая передается приложению. Например, это может быть строка подключения к базе данных или переменные окружения. Deployment Configuration применяется только на этапе создания окружения. Значения ключей передаются в Helm и позволяют переопределять значения по умолчанию, влияя таким образом непосредственно на процесс развертывания. В качестве примера здесь можно привести версию чарта или URL Helm-репозитория.
 Вот как выглядит конфигурация стейджинга в Octopod: 
- Ограничение по ресурсам. Review-окружений может быть много, потребляемых ими ресурсов – тоже. В конце концов, ресурсы заканчиваются и с этим нужно что-то делать. Поэтому, мы архивируем окружение, когда тикет в Jira перемещается в колонку Done (Jira, Octopod и GitHub у нас интегрированы между собой). Также, архивацию можно сделать и вручную. Архивация подразумевает подход “scale-to-zero”, когда освобождаются Pods, но все остальные ресурсы (Persistent Volumes, например) сохраняются. Это позволяет в случае необходимости разархивировать окружение и очень быстро вернуть его в рабочее состояние. Окружения в архиве старше 14 дней удаляются полностью, то есть происходит cleanup с удалением абсолютно всех ресурсов, включая PVC, сертификаты, и т.д. Автоматизацию этого процесса мы настраиваем с помощью octo CLI – утилиты командной строки Octopod, которая имеет расширенные возможности по сравнению с веб-интерфейсом. В GitLab такой подход тоже можно реализовать, но задача эта нетривиальная и требующая сложной логики в .gitlab-ci.yml. 
- Требуется четкое отслеживание состояния review-окружения. Один из недостатков Helm заключается в том, что невозможно отследить состояние окружения после того, как оно было развернуто. Helm завершил свою работу, а следить за тем, продолжает ли окружение функционировать, нужно самостоятельно. В процессе работы что-то может пойти не так, review-окружение уже не работает, но мы этого не знаем, пока оно нам не понадобится. Ребята из Flant решили эту проблему с помощью kubedog, который встроен в werf. Octopod следит за состояниями окружений несколько иначе. Все управляющие скрипты для Octopod мы пишем на Rust и используем kube-rs клиент для проверки статусов всех ReplicaSet. Проверка выполняется каждые 5 секунд, поэтому статус состояния review-окружения в Octopod всегда актуален. 
- Написание скрипта .gitlab-ci.yml может быть достаточно сложной задачей. В Octopod мы решили эту проблему за счет поставки готовых скриптов для Helm, позволяющих деплоить любой валидный Helm-чарт. Во многих случаях это полностью исключает необходимость написания каких-либо скриптов и сводит вовлечение DevOps-инженера к минимуму. В конце статьи мы перейдем к практическому упражнению и развернем инстанс Wordpress в Octopod, используя Helm-чарт от bitnami. 
- Необходимость создания комплексных взаимозависимых окружений. Если вам нужно создать окружение, которое зависит от инфраструктурных сервисов вроде PostgreSQL или Redis, то эти сервисы могут быть развернуты как отдельные review-окружения с помощью своих Helm-чартов, а параметры подключения к ним переданы через Application Overrides. Так можно использовать, например, один инстанс PostgreSQL или один сервис аутентификации для нескольких review-окружений. 
- Требуется более тесная и надежная интеграция с кластером Kubernetes. Octopod работает в том же Kubernetes кластере, в котором разворачивает все review-окружения. Проблема с доступом к кластеру и передачей Secrets решена полностью, Octopod работает через Service Account. В GitLab можно настроить бесшовную интеграцию с Kubernetes кластером, что решает проблему передачи секретов. Но если интеграция по какой-то причине не работает, то возникают сложности. 
Практика. Устанавливаем Octopod
Есть два основных пути установки Octopod:
- Для промышленного использования. Установка производится в кластер Kubernetes с помощью официального Helm-чарта. 
- Для индивидуального использования и ознакомления с основными возможностями Octopod. Установка производится локально и полностью автоматизирована. 
Мы с вами сейчас установим Octopod локально. На данный момент установка поддерживается в Linux и MacOS. Для установки в Windows требуется Windows Subsystem for Linux 2 (Docker Desktop устанавливается в Windows и интегрируется с WSL 2, остальные компоненты устанавливаются в WSL по инструкциям для Linux). Предварительно потребуется установить следующие инфраструктурные компоненты:
- Docker Desktop (https://www.docker.com/products/docker-desktop) 
- Kind (https://kind.sigs.k8s.io/docs/user/quick-start/#installation) 
- Kubectl (https://kubernetes.io/docs/tasks/tools) 
- Helm 3 (https://helm.sh/docs/intro/install) 
- (Только для Windows) WSL 2 (https://docs.microsoft.com/en-us/windows/wsl/install) 
Затем запускаем скрипт, который установит Octopod:
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/typeable/octopod/master/octopod_local_install.sh)"
Важное замечание при установке Octopod в Windows. WSL 2 может иметь проблемы с подключением к ресурсам по SSL из-за настроек антивирусного ПО с функцией файерволла (https://docs.microsoft.com/en-us/windows/wsl/troubleshooting#no-internet-access-in-wsl). Проявляется это как time out при попытке скачивания данных из репозиториев.
После того, как установка завершена, открываем браузер и в адресной строке вводим http://octopod.lvh.me и видим

Наверное, здесь стоит пояснить, что lhv.me – это простой сервис, который на любой запрос возвращает IP-адрес локального хоста 127.0.0.1. Его удобно использовать, чтобы не приходилось каждый раз вносить изменения в /etc/hosts.
Теперь нам нужно создать новый деплоймент. Octopod поставляется с уже предустановленными параметрами для Helm-чартов от bitnami, а в качестве примера используется Wordpress.
Нажмите кнопку NEW DEPLOYMENT. На экране появится окно, в котором необходимо ввести параметры окружения. В самом простом случае достаточно ввести имя. Например, wordpress. Но мы добавим еще два App override (для этого нажмите ADD AN OVERRIDE:
| KEY | VALUE | 
| wordpressUsername | admin | 
| wordpressPassword | P@ssw0rd | 
Мы добавляем эти две переменные только на время создания review-окружения, когда эти переменные будут использованы для инициализации Wordpress. Затем их можно удалить. Естественно, что имя пользователя и пароль мы здесь указываем явно и простым текстом лишь для упрощения и в демонстрационных целях на локальной версии Octopod. В реальных условиях мы используем соответствующие инструменты типа Hashicorp Vault.

Нажмите кнопку SAVE.
Через некоторое время review-окружение будет создано.

На этом создание review-окружения завершено. Теперь вы можете открыть Wordpress по ссылке, которая указана в колонке Links. Чтобы зайти в админку, добавьте в URL /admin (http://wordpress.lvh.me/admin). Введите имя пользователя и пароль, которые были указаны при создании окружения.
Если все прошло успешно, то переменные wordpressUsername и wordpressPassword можно удалить, а пароль при необходимости можно заменить в админке Wordpress.
Заключение
Мы считаем, что review-окружения могут быть полезны не только разработчикам и тестировщикам, но и другим людям с меньшими техническими скилами. Поэтому мы постарались сделать порог вхождения в Octopod минимальным, интерфейс дружелюбным и понятным, а взаимодействие с пользователем интуитивным и предсказуемым. Именно этим продиктован путь, который мы выбрали для развития Octopod и решения тех проблем, которые описаны в этой статье. Конечно, идеологически Octopod значительно отличается от GitLab Dynamic Environments и применяет другие подходы к решению схожих вопросов. Но свое главное предназначение он выполняет безотказно – DevOps инженеры теперь свободны от рутинных задач по созданию и обслуживанию review-окружений, а это много стоит.
Нам, в свою очередь, очень хотелось бы получать обратную связь от пользователей Octopod. Ждем ваших предложений, пожеланий и PRs на GitHub! Также мы готовы ответить на ваши вопросы, пожелания и замечания в комментариях.
Вам может быть интересно:
 
          