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

С чего мы начали

На сегодня фирма 1С выпускает более 30 прикладных решений самых разных «калибров», от ПО для индивидуальных предпринимателей до ERP-систем для больших предприятий и холдингов. И все эти решения мы тестируем.

Для тестирования наших решений мы используем парк виртуальных машин в облаке OpenStack. Для тестирования мы используем в основном наш механизм автоматизированного тестирования, но изначально перед запуском тестов виртуалки для тестирования мы настраивали вручную. В ходе работы мы сталкивались с рядом проблем.

Первая проблема - это оперативное развёртывание нескольких виртуальных машин. Раньше на ручную настройку одной виртуальной машины у нас уходило от 3 до 4 часов. В настройку входит создание и конфигурирование виртуальной машины, подключение машины к внутреннему домену, установка всех необходимых утилит, хранилищ, сертификатов, платформы 1С:Предприятие нужной версии, нужного прикладного решения.

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

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

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

Третья проблема – мониторинг нагрузки и расследование инцидентов. Когда возникали сбои, мы не могли быстро понять, на чьей стороне ошибка – в облаке OpenStack или в нашей платформе. Метрики собирались вручную, администраторы облака тратили часы на анализ логов, а мы теряли время в ожидании ответа.

Все эти проблемы – медленное развёртывание, разрозненные конфигурации, отсутствие прозрачного мониторинга – и подтолкнули нас к поиску решения.

Как мы работаем с OpenStack

Перейдём к тому, как мы работаем с OpenStack, основой нашей тестовой инфраструктуры.  Первое, что нужно заметить: администрированием и поддержкой оборудования занимается отдельная команда.

Мы как разработчики-тестировщики не лезем в железо, это задача администраторов облака. Они обеспечивают стабильность инфраструктуры, а нам предоставляют инструменты для работы. Один из таких инструментов – OpenStack CLI (консольный клиент для работы с OpenStack API), который позволяет автоматизировать развёртывание виртуальных машин.

Как мы используем OpenStack? Всё начинается с того, что администратор выдаёт нам ресурсы – вычислительные мощности, сети, диски. Дальше мы сами разворачиваем и поддерживаем виртуальные машины. Это нужно для всех видов тестирования – функционального, нагрузочного, интеграционного.
Теперь давайте разберём, как мы ускорили развёртывание в OpenStack и сделали его автоматическим.  Вот как мы используем OpenStack CLI.

Наша цель – автоматически разворачивать виртуальные машины из командной строки. Но прежде чем запустить процесс мы проводим несколько проверок. Это как контрольный список, чеклист перед стартом. Что же мы проверяем?

Во-первых, существование виртуальных машин, чтобы не создавать дубликаты. Доступную квоту – хватает ли ресурсов в облаке под наши задачи. Права на проект – есть ли у нас доступ к нужным частям инфраструктуры. Проверяем имена виртуальных машин на соответствие шаблонам, чтобы всё было по стандарту и не было никаких случайных названий. Если все проверки пройдены – мы собираем всё необходимое для развёртывания:

  • Получаем SSH-ключ (необходимый для безопасного доступа к машинам)

  • Базовый образ операционной системы (в нашем случае это Ubuntu)

  • Тип инстанса (flavor) – это конфигурация машины (сколько CPU, памяти, дисков)

И с этими данными мы запускаем развёртывание пачки виртуальных машин. После создания виртуальные машины автоматически прописываются в DNS и сразу получают имена, по которым мы можем к ним обращаться. После запуска виртуальных машин нет необходимости в дополнительных ручных настройках.

Как Ansible помогает нам управлять виртуальными машинами

Использование Ansible - это следующий шаг нашей автоматизации. Всё начинается с базового образа Ubuntu. Мы выбрали его как стандарт для наших машин – он лёгкий, универсальный и хорошо поддерживается. На Ubuntu мы ставим VNC, чтобы можно было посмотреть, что происходит в процессе тестирования в интерфейсе.

Далее – установка Ansible. Мы ставим библиотеки Python 3 для скриптов интеграции, и клиент OpenStack CLI, чтобы Ansible мог общаться с облаком OpenStack напрямую. Все наши PlayBook-и (скрипты-сценарии в формате YAML с описанием требуемых состояний управляемой системы) мы храним в GitLab. Это даёт нам версионирование, контроль изменений и удобный доступ к сценариям для всей команды. PlayBook-и – это, по сути, инструкции для Ansible: что установить, как настроить и какие сервисы запустить. А ещё у нас inventory-файлы обновляются автоматически.

 inventory-файлы определяют:

  • хосты (серверы, ВМ, сетевые устройства), которыми управляет Ansible;

  • логические группы хостов;

  • переменные подключения (логины, ключи SSH и т. д.);

  • настройки конфигурации для хостов и групп.

Как только машина появляется в OpenStack и прописывается в DNS, Ansible сразу узнает их адреса и добавляет в список управления. Не требуется никаких ручных правок. Вот как это всё организовано:

У нас есть чёткая структура проектов, отдельные папки для PlayBook-ов, ролей, переменных. Это помогает поддерживать порядок и быстро находить нужное. К примеру, если нужно обновить конфигурацию для тестов, просто правится один файл в GitLab, и все изменения применятся автоматически.

Внутри Ansible Playbooks

Теперь давайте заглянем внутрь наших Ansible Playbook-ов.

Посмотрим, что делает наш главный PlayBook и как мы поддерживаем машины в порядке.

Первое - это PlayBook автоконфигурации. Сразу после развёртывания машины мы инициализируем второй диск (т.е. подготавливаем дополнительное хранилище для данных), монтируем сетевые шары через systemd (это сетевые ресурсы, которые подключаются автоматически при старте), устанавливаем Docker, а затем с помощью rsync переносим его данные на второй диск. Так мы разгружаем основной раздел.

Далее идёт настройка окружения. В итоге мы получаем образ по умолчанию, поднимаем сеть и образ с Virtual Network Computing (VNC) для удаленного доступа к машине. Ставим вспомогательные образы cAdvisor (Container Advisor) (для мониторинга контейнеров) и Portainer Agent для управления Docker-ом. Устанавливаем GitLab Runner, регистрируем его в GitLab, обновляем файл config.toml,  и перезапускаем службу.

Теперь машина готова к выполнению задач CI/CD. И наконец ставим Prometheus Exporter для сбора метрик нагрузки  в реальном времени.

Кроме того, PlayBook обновляет группы, хосты и другие настройки, чтобы всё соответствовало текущему состоянию проекта. Это решает проблему «разрозненных» конфигураций виртуалок.

Но автоматизация - это не только создание виртуальных машин. Мы также следим за чистотой и актуальностью машины.

Во-первых,  мы чистим Docker; убираем неиспользуемые образы и контейнеры, обновляем конфигурационные файлы, чтобы все машины всегда были одной версии настроек, очищаем кэш (то есть освобождаем место и ускоряем работу), перезагружаем незанятые GitLab Runner-ы. Т.е. есть если Runner простаивает, мы перезапускаем его, чтобы он был готов к новым задачам.

GitLab

Перейдём к задачам, которые выполняет GitLab в нашей инфраструктуре. Во-первых, в GitLab мы храним PlayBook Ansible и Python3-скрипты. Все файлы находятся под версионным контролем, файлы доступны всей нашей команде, и они всегда в актуальном состоянии. Во-вторых, мы собираем образы Docker прямо в GitLab.

Для проектов на Python3 и библиотеками у нас есть сервисы оповещений и рассылок отчётов, и всё это у нас работает в контейнерах.

Теперь главное: запуск развёртывания новых виртуальных машин. Это работает в два этапа.

Первый этап – работа с OpenStack CLI. Мы отправляем команду для создания виртуальной машины (те самые проверки квот, имён, прав, о которых мы писали выше).

Второй этап – развертывание конфигурации через Ansible. PlayBook-и берутся из GitLab и применяются к машинам; машины после этого сразу готовы к работе.

После развёртывания мы автоматически обслуживаем машины. Машины подключаются как Runner GitLab CI и сразу начинают выполнять задачи пайплайнов. Мы подключаем их к мониторингу в Prometheus; теперь метрики собираются автоматически. Далее мы создаём дашборд в Grafana, чтобы увидеть нагрузку, состояние машин, и быстро реагировать на проблемы. Далее на этих машинах мы прогоняем тесты – функциональные, нагрузочные и интеграционные.

Разберём, как мы поднимаем машину в GitLab, шаг за шагом. Это процесс, который связывает Ansible и CI/CD в единое целое. Всё начинается с автонастройки виртуальных машин средствами Ansible.

Мы передаём в PlayBook ключевые данные:

  • Список машин; на его основе автоматически создаётся файл inventory.ini, который является списком всех инстансов, с которыми будет работать Ansible.

  • Список сетевых ресурсов (шар), которые мы подключаем через systemd. А ещё они добавляются в файл config.toml GitLab Runner-а,  чтобы GitLab CI знал, где брать данные для задач. config.toml — это конфигурационный файл GitLab Runner, который используется для настройки его поведения. Он использует формат TOML.

Далее идёт назначение ролей машинам. Тут у нас два сценария:

  • Для новых виртуальных машин мы вручную назначаем теги и проекты. Это делается один раз, чтобы задать назначение машины.

  • Для пересозданных машин всё проще – им автоматически назначаются прошлые теги и проекты. То есть если машина уже была в пуле, и мы её пересоздали – она сохраняет свою роль. Это экономит время и исключает ошибки.

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

Prometheus: сбор метрик

Мы подошли к финальной части нашей истории – к мониторингу. И тут на сцену выходит Prometheus. Это инструмент, который дал нам полную прозрачность работы виртуальных машин.

В начале статьи мы упоминали проблему мониторинга; когда что-то падало, мы могла далеко не сразу разобраться, на чьей стороне ошибка – облака OpenStack или приложения 1С. Раньше метрики мы собирали вручную, это был долгий процесс. Теперь после развёртывания и настройки машин через Ansible и GitLab CI мы автоматически подключаем их к Prometheus. Мы собираем метрики нагрузки CPU и использования памяти, загрузку дисков и сети (чтобы увидеть узкие места), состояния Docker-контейнеров и GitLab Runner-ов, смотрим, сколько задач выполняется и есть ли сбои. Эти данные поступают от Prometheus Exporter-ов, которые мы ставим на каждую виртуальную машину ещё на этапе автоконфигурации.  Далее все данные агрегируются в центральный сервер Prometheus. Нет никаких ручных логов, все данные собираются в реальном времени. Мы видим результаты всей автоматизации через Grafana; это наш инструмент визуализации, который превращает метрики в понятные графики.

Grafana

Первое, что мы делаем для Grafana – автоматически создаём дашборды для виртуальных машин. Как только машина развернута и подключена к Prometheus, Grafana подхватывает метрики и строит дашборд. Это не требует ручного труда, дашборд строится автоматически. Метрики мы собираем, чтобы ответить на три вопроса:

  1. Нет ли проблем с инфраструктурой облака? Если OpenStack тормозит или падает, мы видим это на графиках.

  2. Нет ли проблем на новых сборках платформы 1С:Предприятие? Если тесты начинают выполняться медленно или падают, мы сразу понимаем, что дело в коде или конфигурации.

  3. Не пора ли нам расширяться в аппаратном плане? Если загрузка виртуальных машин растёт, а машины работают на пределе своих возможностей, тогда дашборды покажут – пора добавить ресурсов.

Grafana дала нам не просто красивые картинки, а инструмент принятия решений. Мы больше не гадаем где проблема, а видим всё в реальном времени.

Portainer

Теперь расскажем о том, как мы управляем всем этим хозяйством. Тут нам помогает Portainer. Portainer — это инструмент для управления контейнерными средами, который предоставляет веб-интерфейс для управления Docker, Kubernetes, Docker Swarm, Azure ACI и другими системами оркестрации. Portainer упрощает работу с контейнерами, позволяя запускать, останавливать, масштабировать и мониторить их без необходимости использования командной строки. Этот инструмент даёт нам централизованный контроль над сущностями Docker.

С помощью Portainer мы управляем всем из одной точки. Виртуальные машины, контейнеры, сеть – всё под присмотром через удобный веб-интерфейс. Не нужно переключаться между CLI и разными серверами, открываем Portainer и видим полную картину – что запущено, где работает, какие ресурсы задействованы. Но Portainer– это не только про мониторинг. Мы запускаем сервисы с несколькими контейнерами и отладочные стеки прямо из Portainer. Например, нужно развернуть тестовый сервис 1С с подключенными Prometheus и Grafana. Для этого создаём стек, то есть набор контейнеров, связанных между собой. Создаём конфигурацию в DockerCompose, и Portainer сам всё поднимет. А если что-то пойдёт не так – тут же можно зайти в логи, отладить контейнеры или перезапустить сервис. Всё делается в пару кликов.

Как мы все это используем у себя

Мы подошли к тому, чтобы увидеть, как всё это – OpenStack, Ansible, GitLab, Prometheus и Portainer – работает у нас на практике. Покажем, как мы связали все эти инструменты в единый процесс и что получили в итоге.

Всё начинается с GitLab. Мы запускаем процесс из GitLab, и вот что происходит. OpenStack автоматически разворачивает виртуальные машины и проводит проверки CLI, про которые мы писали выше. Ansible берет их на конфигурацию, устанавливает Docker, настраивает сетевые шары, поднимает GitLab Runer-ы. В результате мы получаем настроенный Runner GitLab CI, готовый к работе. Далее – сбор метрик и их визуализация. Машины подключаются к Prometheus, данные идут в Grafana, и мы видим на дашбордах всё – нагрузку, состояния, проблемы. А ещё мы подключаем машины к Portainer, чтобы централизовано управлять контейнерами и запускать тестовые стеки.

В итоге на развёртывание и подключение пачки виртуальных машин к GitLab у нас уходит в среднем 15 минут против трёх-четырёх часов на одну машину (как раньше, при ручном конфигурировании). Мы получаем идентичное и готовое к запуску тестов окружение – быстро, без ошибок, с полной прозрачностью. Теперь тесты запускаются сразу, все конфигурации виртуалок одинаковые, и, если что-то ломается – мы видим где и почему. Так мы превратили хаос ручной работы в автоматизированную систему, что сэкономило нам массу времени и ресурсов.

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