Что такое окружение в тестировании
Что такое тестовое окружение в тестировании
Многие начинающие тестировщики задают вопрос, что такое тестовое окружение в тестировании.
Давайте ответим на этот вопрос.
Окружение (environment) — это среда, место, машина, на которой находится приложение, сайт. Например, хостинг — это место, где хранится сайт, хостинг — это окружение, где может располагаться сайт.
Тестовое окружение (test environment) — это то место, где тестировщик тестирует сайт, приложение, программу.
В процессе разработки, как правило, существует несколько тестовых окружений.
Зачем нужно иметь несколько тестовых окружений? Дело в том, что большие системы могут быть развернуты не на одной машине, не на одном окружении, а на нескольких, это уже называют кластером. А разработчик пишет код не на нескольких машинах, а на одной, поэтому выделяют ещё другой тип тестового окружения — локальное окружение.
Локальное окружение — это всего одна машина, на которой разрабатывают, тестируют приложение.
Боевое окружение — это уже реальная сеть машин, совокупность нескольких окружение, это уже нетестовое окружение, а самое настоящее окружение, где работают пользователи приложения.
Чтобы не тестировать на боевом окружении, но при этом нужно проверить работу сразу на нескольких машинах, создают тестовое окружение из нескольких машин.
Таким образом, можно тестировать приложение как на локальном тестовом окружении, так и на окружении с несколькими машинами, чтобы не влиять на работу реального приложения, которое используют реальные пользователи.
Теперь Вы знаете, что тестовое окружение в тестировании.
Если хотите поговорить на темы, связанные с тестовыми окружениями, пишите в комментариях.
Окружения развёртывания программного обеспечения
Только что опубликовал в русской википедии перевод статьи Deployment environment.
Публикую этот перевод здесь также. Замечания и комментарии приветствуются.
В развёртывании программного обеспечения, окружение или ярус является компьютерной системой в которой компьютерная программа или компонент программного обеспечения развёртывается и выполняется. В простом случае, такое развёртывание и немедленное выполнение программы на той же машине, может выполнятся в единственном окружении, однако при промышленной разработке используется разделение на development окружение (‘окружение разрабочика’) (где делаются исходные изменения) и production окружение (которое используют конечные пользователи); часто с промежуточными этапами (‘stages’) посередине. Этот структурированный процесс управления релизами может иметь фазы deployment (rollout, ‘развёртывание’, ‘выкатка’), testing (‘тестирование’), и rollback (‘откат’) в случае проблем.
Окружения могут существенно отличаться в размерах: deployment окружение это обычно рабочая станция отдельного разработчика, в то время как production окружение может быть сетью множества географически разнесённых машин в случае с дата-центров, или виртуальными машинами в случае с облачными решениями. Код, данные и конфигурация могут быть развёрнуты паралельно, и нет необходимости связи с соответствующим ярусом — например, pre-production код может подсоединяться к production БД.
Архитектуры
Архитектуры развёртывания существенно разнятся, но в целом, ярусы начинаются с develpment (DEV) и заканчиваются production (PROD). Распространённой 4-х ярусной архитектурой является каскад ярусов deployment, testing, model, production (DEV, TEST, MODL, PROD) c деплоем софта на каждом ярусе по очереди. Другое распространённое окружение это Quality Control (QC), для приёмочного тестирования; песочница или экспериментальное окружение (EXP), для экспериментов не предназначенных для передачи в продакшен; и Disaster Recovery (‘аварийное восстановление’), для предоставления возможности немедленного отката в случае проблемы с продакшеном. Другой распространённой архитектурой является deployment, testing, acceptance and production (DTAP).
Такая разбивка в частности подходит для серверных программ, когда сервера работают в удаленных дата-центрах; для кода который работает на конечных устройствах пользователя, например приложений (apps) или клиентов, последний ярус обозначают как окружение пользователя (USER) или локальное окружение (LOCAL).
Точные определения и границы между окружениями варьируется — test может рассматриваться как часть dev, приёмка может рассматриваться как часть test, часть stage, или быть отдельной и так далее. Основные ярусы обрабатываются в определённом порядке, с новыми релизами при развёртывании (rolled out или pushed) на каждом. Ярусы experimental и recovery, если представлены, являются внешними к этому процессу — experimental релизы являются конечными, в то время как recovery являются обычно старыми или дублирующими версиями production, развёрнутыми после production. В случае проблем, в последнем случае можно сделать roll back к старому релизу, и большинство просто выкатывают старый релиз таким же способом как новый. Последний шаг, деплой в production («pushing to prod») самый чувствительный, т.к. здесь любые проблемы напрямую влияют на пользователя. По этой причине это часто управляется по разному, но как минимум мониторится более тщательно, и в некоторых случаях имеется фаза отката или простого переключения. Лучше всего избегать названия вроде Quality Assurance (QA); QA не означает тестирование софта. Тестирование важно, но это отличается от QA.
Иногда развёртывание выполняется вне обычного процесса, главным образом для предоставления срочных или небольших изменений, без необходимости полного релиза. Это может быть один патч, большой service pack или небольшой hotfix.
Окружения могут быть очень разных размеров: разработка обычно идёт на индивидуальных машинах разработчиков (хотя это могут быть тысячи разработчиков), в то время как продакшеном могут быть тысячи географически распределённых машин; тестирование и QC может быть маленьгим и большим, зависеть от предоставленных ресурсов, а staging может варьироваться от единичной машины (подобно canary) до точных дубликатов продакшена.
Окружения
Local
Development/Thunk
Сервер разработки выступающий как песочница где разработчик может выполнить unit-тестирование
Integration
Основа для построения CI, или для тестирования сайд-эффектов разработчиком
Testing/Test/QC/Internal Acceptance
Окружение в котором выполняется тестирование интерфейса. Команда контроля качества проверяет что новый код не будет иметь влияния на существующую функциональность системы после деплоя нового кода в тестовое окружение.
Staging/Stage/Model/Pre-production/External-Client Acceptance/Demo
Production/Live
Серверы конечных пользователей/клиентов
Окружение разработчика
Окружение разработчика (dev) является окружением в котором софт разрабатывается, это часто просто компьютер разработчика. Это отличается от конечной целевой среды некоторыми вещами — цель может не быть стационарным компьютером (это может быть смартфон, встроенная система, самоуправляемый транспорт датацентра и т.д.), и даже если это стационарный компьютер, окружение разработчика будет включать инструменты разработчика например компилятор, IDE, различные или дополнительные версии библиотек и вспомогательного софта, и т.д., что не представлено в пользовательском окружении.
В контексте управления ревизиями, особенно при участии множества разработчиков, проводятся более тонкие различия: разработчик имеет рабочую копию исходного текста на своей машине, и изменения вносятся в репозиторий, будучи закомиченными либо в «стволе», либо в ветке, в зависимости от методологии разработки. Окружение на отдельной рабочей станции, на которой изменения отработаны и опробованы, может называться локальным окружением или песочницей. Сборка копии исходного кода репозитория в чистом окружении является отдельным этапом интеграции (интеграция разрозненных изменений), и это окружение может называться интеграционным окружением или окружением разработчика; при непрерывной интеграции это делается часто, так же часто, как и для каждой ревизии. Понятие уровня исходного кода звучащее как «фиксация (коммит) изменения в репозитории» с последующей сборкой «ствола» или ветки — соответствует переходу от локального (индивидуального окружения разработчика) к интеграции (чистой сборке); плохой релиз на этом этапе означает, что изменение сломало сборку, а откат релиза соответствует либо откату всех сделанных изменений, либо отмене только ломающего изменения, если это возможно.
Тестовое окружение
Цель тестового окружения состоит в том, чтобы позволить людям, проводящим тестирование, пропускать новый и измененный код либо через автоматизированные проверки, либо через неавтоматизированные методы. После того, как разработчик пропускает новый код и конфигурации через модульное тестирование в среде разработки, код переносится в одну или несколько тестовых сред. После неудачи теста тестовая среда может удалить ошибочный код из тестовых платформ, связаться с ответственным разработчиком и предоставить детальные журналы тестирования и результаты. Если все тесты пройдут, тестовая среда или фреймворк непрерывной интеграции, контролирующий тесты, может автоматически перенести код в следующую среду развертывания.
Различные типы тестирования предполагают различные типы тестовых сред, некоторые или все из которых могут быть виртуализированы для обеспечения быстрого параллельного тестирования. Например, автоматизированные тесты пользовательского интерфейса могут выполняться на нескольких виртуальных операционных системах и дисплеях (реальных или виртуальных). Для проведения тестов производительности может потребоваться нормализованная базовая конфигурация аппаратного обеспечения, чтобы результаты тестов производительности можно было сравнивать с течением времени. Тестирование на доступность или устойчивость может основываться на симуляторах отказов в виртуальных аппаратных средствах и виртуальных сетях.
Тесты могут быть последовательными (один за другим) или параллельными (для некоторых или всех сразу), в зависимости от сложности тестовой среды. Важной целью agile и других высокопроизводительных практик разработки программного обеспечения является сокращение времени от разработки или предоставления программного обеспечения до его поставки в продакшен. Высокоавтоматизированные и распараллеленные тестовые среды вносят важный вклад в быструю разработку программного обеспечения.
Staging
Stage или stage-окружение — это среда для тестирования, которая в точности похожа на продакшен-окружение. Она стремится как можно точнее отразить реальное продакшен-окружение и может подключаться к другим продакшен-сервисам и данным, таким как базы данных. Например, серверы будут работать на удаленных машинах, а не локально (как на рабочей станции разработчика во время разработки, или на одной тестовой машине во время тестирования), чтобы проверить влияние сети на систему.
Основное назначение stage-окружения заключается в тестировании всех сценариев установки/конфигурации/перемещения скриптов и процедур, прежде чем они будут применены в продакшен-окружении. Это гарантирует, что все существенные и незначительные обновления продакшен-окружения будут завершены качественно, без ошибок и в минимальные сроки.
Другим важным использованием stage-окружения является тестирование производительности, в частности нагрузочное тестирование, так как это часто чувствительно для окружения.
Stage-окружение также используется некоторыми организациями для предварительного просмотра новых функций и их отбора заказчиками или для утверждения интеграции с работающими версиями внешних зависимостей.
Продакшен-окружение
Продакшен-окружение также известно как live (в частности в применении к серверам) так как это окружение, с которым непосредственно взаимодействуют пользователи.
Развертывание в производственной среде является наиболее чувствительным шагом; это может осуществляться путем непосредственного развертывания нового кода (перезаписывания старого кода, так что только одна копия представлена в один момент времени), или путем развертывания изменения конфигурации. Это может принимать различные формы: параллельное развертывание новой версии кода и переключение на неё с изменением конфигурации; развертывание новой версии кода рядом со старым с соответствующим «флагом нового функционала», и последующее переключение на новую версию с изменением конфигурации, которая выполнит переключение этого «флага»; или развертывание отдельных серверов (один выполняет старый код, другой — новый) с перенаправлением трафика со старого на новый с изменением конфигурации на уровне маршрутизации трафика. Всё это, в свою очередь, может быть применено одновременно или выборочно, и на разных этапах.
Развертывание новой версии обычно требует перезапуска, если только нет возможности горячего переключения, и поэтому требует либо прерывания обслуживания (обычно это пользовательское ПО, когда приложения должны быть перезагружены), либо дублирования — постепенного перезапуска экземпляров «за спиной» у балансировщика нагрузки, либо заблаговременного запуска новых серверов с последующим простым перенаправлением трафика на новые сервера.
При выкатке нового релиза в продакшен, вместо немедленного развертывания для всех экземпляров или пользователей, его можно сначала развернуть на одном экземпляре или для части пользователей, а затем уже либо развернуть для всех экземпляров, либо поэтапно по фазам, чтобы оперативно отлавливать возникающие проблемы. Это похоже на staging, за исключением того, что делается в продакшене, и по аналогии с добычей угля называется canary release. Это добавляет сложности если несколько релизов запускаются одновременно, и, поэтому их обычно стараются делать быстро, чтобы избежать проблем совместимости.
Как сделать тестовое окружение максимально похожим на боевое
С другой стороны продакшен, где еще больше серверов и где цена ошибки намного выше.
Старое тестовое окружение имело ряд особенностей:
Все эти пункты приводили к различным багам, самый неприятный из которых был почти часовой простой сайта из-за неправильного конфига nginx.
Что хотелось от нового окружения:
Начало пути
Идея использовать конфигурацию с продакшена в тестовом окружении появилась довольно давно (года 3 назад), но были другие более важные задачи, и мы не брались за реализацию этой идеи.
А взялись мы за нее случайно, решив попробовать новое технологическое веяние в виде docker’a в момент, когда вышла версия 0.8.
Чтобы понять, что такого особенного в нашем тестовом окружении, надо немножко представлять из чего состоит продакшен hh.ru.
Продакшен hh.ru предстваляет собой парк серверов, на которых запущены отдельные части сайта — приложения, каждое из которых отвечает за свою функцию. Приложения общаются между собой посредством http.
Идея была воссоздать такую же структуру, заменив парк серверов на lxc-контейнеры. А чтобы всем этим хозяйством было удобно управлять, использовать надстройку под названием docker.
Не совсем docker-way
Мы не пошли по истинному docker-way, когда в одном контейнере запущен один сервис. Задача была сделать тестовые стенды похожими на инфраструктуру продакшена и службы эксплуатации.
Служба эксплуатации использует ansible для деплоя приложений и конфигурирования серверов. Порядок выкладки и шаблоны конфигов для каждого сервиса описан в yaml файле, в терминологии ansible — playbook. Было решено использовать те же самые плейбуки и в тестовом окружении. Гибкость тут в возможности заменять значения и иметь полностью свой, тестовый, набор значений переменных.
В итоге у нас образовалось несколько docker images — базовый образ в виде ubuntu с init & ssh, с тестовой базой данных, с cassandra, с deb-репозиторием и maven-репозиторием, которые доступны во внутреннем docker registry. Из этих образов мы создаем необходимое нам количество контейнеров. Затем ansible раскатывает нужные плейбуки, на указанные в inventory (список групп серверов, с которыми будет работать ansible) контейнеры-хосты.
Все запущенные контейнеры находятся в одной (внутренней для каждой машины-хоста) сети, и каждый контейнер имеет постоянный IP адрес и DNS-имя — и тут тоже не docker-way. Для полного воссоздания инфраструктуры продакшена некоторые контейнеры имеют даже IP-адреса боевых серверов.
Заходить на контейнеры можно по ssh прямо с машины-хоста. Внутри у контейнера то же расположение файлов, что и на продакшен серверах, те же версии приложений и зависимостей.
Для удобного поиска ошибок на хост-машине агрегируются директории с логами с каждого контейнера с помощью механизма символических ссылок. Каждый запрос на продакшене имеет уникальный номер, и теперь эта же система доступна в тестовом окружении, что позволяет, имея id запроса, найти его упоминание в логах всех сервисов.
Саму хост-машину под контейнеры мы создаем и настраиваем из нашей системы управления тестовыми стендами при помощи vmbuilder & ansible. Новым машинам потребовалось больше оперативной памяти из-за дополнительных сервисов, которых раньше не было в тестовом окружении.
Для облегчения работы было написано множество скриптов (python, shell) — для запуска плейбуков (чтобы тестировщики не запоминали различные теги и параметры запуска ansible), для работы с контейнерами, для создания с нуля всего окружения и его обновления, обновления и восстановления тестовых баз и т.п.
Сборка сервисов из кода для тестирования у нас также автоматизирована, и в новом окружении используется точно та же программа сборки, что и при выпуске релизов на продакшен. Сборка производится в специальном контейнере, где установлены все необходимые build dependencies.
Какие проблемы были и как мы их решали
IP адреса контейнеров и их постоянный список.
Докер по-умолчанию выдает IP-адреса из подсети в случайном порядке и контейнер может получить любой адрес. Чтобы как-то завязываться в DNS зоне мы решили прокидывать каждому контейнеру свой уникальный, закрепленный за ним адрес, указанный в конфиг-файле.
Параллельный запуск ansible.
Служба эксплуатации никогда не сталкивается с задачей создать продакшен с чистого листа, поэтому они никогда не запускают все ansible-плейбуки разом. Мы попробовали, и последовательный запуск плейбуков для разворачивания всех сервисов занял примерно 3 часа. Такое время полностью нас не устроило при развертывании тестового окружения. Было решено запускать плейбуки в параллели. И тут нас опять ждала засада: если запустить все в параллели, то некоторые сервисы не стартуют из-за того, что они пытаются установить соединение с другими сервисами, которые еще не успели стартовать.
Обозначив примерную карту этих зависимостей, мы выделили группы сервисов и запускаем плейбуки в параллели внутри этих групп.
Задачи, которые отсутствуют в процессе выпуска приложений службой эксплуатации.
Служба эксплуатации занимается развертыванием уже собранных приложений в deb-пакетах, тестировщику, как и разработчику, приходится собирать приложения из исходного кода, при сборке есть другие зависимости относительно тех, что необходимы при установке. Для решения задачи сборки добавили еще один контейнер, в который ставим все необходимые зависимости. Отдельный скрипт собирает пакет внутри этого контейнера из исходников нужного в данный момент приложения. Затем пакет заливается в локальный репозиторий и раскатывается на те контейнеры, где он необходим.
Проблемы с возросшими требованиями по железу.
В виду большего количества сервисов (балансировщики) и других настроек приложений относительно старого тестового окружения, для новых стендов потребовалось больше оперативной памяти.
Проблемы с таймаутами.
На продакшене каждый сервис стоит на своем сервере, достаточно мощном. В тестовом окружении сервисы в контейнерах делят общие ресурсы. Установленные таймауты в продакшене оказались неработающими в тестовом окружении. Они были вынесены в переменные ansible и изменены для тестового окружения.
Проблемы с ретраями и алиасы для контейнеров.
Некоторые ошибки, происходящие в сервисах, обходятся на продакшене с помощью повторных запросов на другую копию сервиса (ретраи). В старом окружении ретраи вообще не использовались. В новом окружении, хотя мы и подняли по одному контейнеру с сервисом, были сделаны dns-алиасы для некоторых сервисов, чтобы работали ретраи. Ретраи делают систему чуть более стабильной.
pgbouncer и количество соединений.
В старом тестовом окружении все сервисы ходили прямо в postgres, в продакшене перед каждым постгресом стоит pgbouncer, менеджер соединений к базе. Если менеджера нет, то каждое соединение к базе — это отдельный процесс postgres, отъедающий дополнительный объем памяти. После установки pgbouncer количество процессов postgres сократилось с 300 до 35 на работающем тестовом стенде.
Мониторинг сервисов.
Для удобства использования и запуска автотестов был сделан легкий мониторинг, который с задержкой меньше минуты показывает состояние сервисов внутри контейнеров. Сделали на основе haproxy, который делает http check по сервисам из конфига. Конфигурационный файл для haproxy генерируется автоматически на основе ansible inventory и данных по адресам и портам из ansible playbooks. Мониторинг имеет user-friendly view для людей и json-view для автотестов, которые проверяют состояние стенда перед запуском.
Было еще множество других проблем: с контейнерами, с ansible, с нашими приложениями, с их настройками и т.п. Мы решили большинство из них и продолжаем решать то, что осталось.
Как всем этим пользоваться для тестирования?
Каждый тестовый стенд имеет свое dns-имя в сети. Раньше, чтобы получить доступ к тестовому стенду, тестировщик вводил hh.ru.standname и получал копию сайта hh.ru. Это было достаточно просто, но не позволяло тестировать многие вещи и вносило сложности в тестирование мобильных приложений.
Теперь, благодаря использованию продакшен конфигов для nginx, которые не очень хотят принимать на вход URI, заканчивающиеся на standname, тестировщик прописывает у себя в браузере прокси (на каждой хост-машине поднят squid) и открывает в браузере hh.ru или любой другой сайт из нашего пула (career.ru, jobs.tut.by, etc) и любой из доменов третьего уровня, например, nn.hh.ru.
Использование прокси позволяет без проблем тестировать мобильные приложения, просто включив прокси в настройках wifi.
Если тестировщик или разработчик захотел получить доступ к сервису и его порту напрямую снаружи, то делается проброс портов при помощи haproxy — например, для дебага или других целей.
Profit
В данный момент мы все еще находимся в процессе перехода на новое окружение и реализуем всевозможные пожелания, которые появились в процессе работы. Уже перевели ручное тестирование на новые стенды и основной релизный стенд. В ближайших планах — перевести на новое окружение инфрастуктуру автотестирования.
На текущий момент уже имеем profit в следующих случаях:
В следующих планах полная автоматизация создания стендов под каждый релиз и исключение человека из процесса сборки и автотестирования релизов.
Docker: Окружение для тестирования
Последние пять лет принесли в нашу жизнь огромное количество технологий, с помощью которых можно быстро создавать изолированные окружения для разработки и тестирования. Но не смотря на это, организовать стабильное окружение для тестирования — далеко не самая простая задача. А если нужно тестировать сетевые взаимодействия компонентов и анализировать предельный уровень нагрузки на них, то задача становится еще сложнее. Добавив возможность быстрого развертывания окружения и гибкой настройки отдельных компонентов, мы сможем получить небольшой интересный проект.
В этой статье мы подробно расскажем о создании окружения на базе Docker контейнеров для тестирования нашего клиент-серверного приложения. При этом, если смотреть глобально, то данная статья будет хорошей иллюстрацией использования Docker и его ближайшей экосистемы.
Постановка задачи
Архитектура окружения для тестирования
Распределенную сетевую среду мы построили при помощи Docker контейнеров, изолирующих в себе наши и внешние сервисы, и docker-machine, которая позволяет организовать изолированное пространство для тестирования. В результате архитектура тестового окружения выглядит так:
Для визуализации окружения мы используем Weave Scope, так как это очень удобный и наглядный сервис для мониторинга Docker контейнеров.
С данным подходом удобно тестировать взаимодействие SOA компонентов, например, небольшие клиент-серверные приложения, подобные нашему.
Реализация базового окружения
Далее подробно рассмотрим каждый шаг создания тестового окружения на базе Docker контейнеров, с использованием docker-compose и docker-machine.
Начнем с docker-machine, которая позволит нам безболезненно выделить тестовое виртуальное окружение. При этом нам будет очень удобно работать с этим окружением напрямую с хост-системы.
Итак, создаем тестовую машину:
Эта команда создает VirtualBox VM с установленными внутри нее CoreOS и Docker, готовым к работе (Если вы используете Windows или MacOS, то рекомендуется установить Docker Toolbox, в котором уже все заложено. А если вы используете Linux, то необходимо поставить docker, docker-machine, docker-compose и VirtualBox самостоятельно). Мы рекомендуем ознакомиться со всеми возможностями docker-machine, это довольно мощный инструмент для управления окружениями.
Как видно из вывода этой команды, docker-machine создает все необходимое для работы с виртуальной машиной. После создания, виртуальная машина запущена и готова к работе. Давайте проверим:
Прекрасно, виртуальная машина запущена. Надо активировать доступ к ней в нашей текущей сессии. Вернемся на предыдущий шаг и внимательно посмотрим на последнюю строку:
Это autosetup для нашей сессии. Выполнив эту команду мы увидим следующее:
Это просто набор переменных окружения, который сообщит вашему локальному docker-клиенту где искать сервер. В последней строке расположена подсказка. Выполним эту команду и посмотрим на вывод команды ls :
В столбце ACTIVE наша активная машина помечена звездочкой. Обратите внимание, машина активна в рамках только текущей сессии. Мы можем открыть еще одно окно терминала и активировать там другую машину. Это может быть удобно для тестирования, например, оркестрации при помощи Swarm. Но это тема для отдельной статьи :).
Далее проверим наш docker-сервер:
Акцентируем внимание на OS/Arch, там всегда будет linux/amd64, так как docker-сервер работает в VM, нужно не забывать об этом. Немного отвлечемся и заглянем внутрь VM:
Да, это boot2docker, но интересно не это. Посмотрим на смонтированные разделы:
В данном случае мы используем MacOS и, соответственно, внутрь машины смонтирована директория /Users (аналог /home в linux). Это позволяет нам прозрачно работать с файлами на host-системе в рамках docker, то есть спокойно подключать и отключать volumes, не заботясь о прослойке в виде VM. Это действительно очень удобно. По идее, нам можно забыть про эту VM, она нужна только для того, чтобы docker работал в “родной” среде. При этом использование docker-клиента будет абсолютно прозрачным.
Итак, базовое окружение построено, далее будем запускать Docker контейнеры.
Настройка и запуск контейнеров
В этом файле все стандартно. Первым запускаем elasticsearch, как основное хранилище, затем три экземпляра с nginx, которые будут выступать поставщиками нагрузки. Далее запускаем наши сервер-приложения. Обратите внимание, все последующие контейнеры линкуются с предыдущими. В рамках нашей docker-сети, это позволит обращаться к контейнерам по имени. Чуть ниже, когда мы будем разбирать запуск нашего сервиса в “dual mode”, мы еще вернемся к этому моменту и рассмотрим его чуть подробнее. Также с первым контейнером, в котором находится экземпляр сервер-приложения, залинкованы агенты. Это означает, что все три агента будут пересылать логи именно этому серверу.
Наше приложение спроектировано таким образом, что для добавлении новой ноды в кластер, агенту или серверу достаточно сообщить об одном существующем узле кластера и он получит полную информацию о всей системе. В конфигурационных файлах для каждого экземпляра сервера мы укажем наш первый узел и агенты автоматически получат всю информацию о текущем состоянии системы. По прошествии некоторого времени после запуска всех узлов системы, мы просто выключим этот экземпляр. В нашем случае кластер переносит это безболезненно, вся информация о системе уже распространена между всеми участниками.
И еще один момент: обратите внимание на логику монтирования volumes. На контейнерах с nginx мы указываем именованный volume, который будет доступен в docker-сети, а на контейнерах с агентами мы просто подключаем его, указав имя сервиса. Таким образом, у нас получится shared volume между потребителями и поставщиками нагрузки.
Итак, запускаем наше окружение:
Проверяем, что все запустилось нормально:
Отлично, окружение поднялось, работает и все порты проброшены. В теории мы можем стартовать тестирование, но нам нужно доделать некоторые моменты.
Присвоение имен контейнерам
Генератор нагрузки крайне прост:
Стартовый скрипт тоже не сложный:
Вся хитрость будет заключаться в конфигурационном файле supervisord и запуске Docker-контейнера.
Рассмотрим конфигурационный файл:
Помимо нашей переменной, которую мы явно указали при старте контейнера, мы видим еще и все переменные, относящиеся к залинкованному контейнеру, а именно: IP-адрес, все открытые порты и все переменные, которые были явно установлены при сборке образа elasticsearch при помощи директивы ENV. Все переменные имеют префикс с именем экспортирующего контейнера и название, указывающее на их суть. Например, ELASTIC_PORT_9300_TCP_ADDR обозначает, что в переменной хранится значение, указывающее на контейнер с именем elastic и его ip-адрес, на котором открыт порт 9300. Если поднимать отдельный discovery-сервис для поставленных задач не резонно, то это отличный способ получить IP-адрес и данные залинкованных контейнеров. При этом остается возможность использовать их в своих приложениях, которые запущены в Docker контейнерах.
Управление контейнерами и система мониторинга
Итак, мы построили окружение для тестирования отвечающее всем нашим изначальным запросам. Осталась пара нюансов. Во-первых, установим Weave Scope (скриншоты которого были в начале статьи). При помощи Weave Scope можно визуализировать среду, в которой мы работаем. Помимо отображения связей и информации о контейнерах, мы можем выполнить attach к любому контейнеру или запустить полноценный терминал с sh прямо в браузере. Это незаменимые функции при отладке и тестировании. Итак, с хост-машины выполняем следующие действия, в рамках нашей активной сессии:
После выполнения этих команд, перейдя по адресу VM_IP:4040 мы попадаем в интерфейс управления контейнерами, представленный на картинке ниже:
Отлично, почти все готово. Для полного счастья нам не хватает системы мониторинга. Воспользуемся cAdvisor от Google:
Теперь по адресу VM_IP:8080 у нас есть система мониторинга ресурсов в реальном времени. Мы можем отслеживать и анализировать основные метрики нашего окружения, такие как:



