Какое-то время назад мы сделали безагентский (Agentless) мониторинг и алармы к нему. Это аналог CloudWatch в AWS с совместимым API. Сейчас мы работаем над балансировщиками и автоматическим скейлингом. Но пока мы не предоставляем такой сервис — предлагаем нашим заказчикам сделать его самим, используя в качестве источника данных наш мониторинг и теги (AWS Resource Tagging API) как простой service discovery. Как это сделать покажем в этом посте.

Пример минимальной инфраструктуры простого веб-сервиса: DNS -> 2 балансера -> 2 backend. Данную инфраструктуру можно считать минимально необходимой для отказоустойчивой работы и для проведения обслуживания. По этой причине мы не будем «сжимать» еще сильнее эту инфраструктуру, оставляя, например, только один backend. А вот увеличивать число backend серверов и сокращать обратно до двух хотелось бы. Это и будет нашей задачей. Все примеры доступны в репозитории.

Базовая инфраструктура

Мы не будем останавливаться детально на настройке приведённой выше инфраструктуры, покажем лишь, как её создать. Мы предпочитаем разворачивать инфраструктуру с помощью Terraform. Он помогает быстро создать всё необходимое (VPC, Subnet, Security Group, VMs) и повторять эту процедуру раз за разом.

Настройка мониторинга

Запущенные выше ВМ автоматически мониторятся нашим облаком. Именно данные этого мониторинга будут являться источником информации для будущего автоскейлинга. Полагаясь на те или иные метрики мы можем увеличивать или сокращать мощности.

Мониторинг в нашем облаке позволяет настроить алармы по различным условиям на различные метрики. Это очень удобно. Нам не нужно анализировать метрики за какие-то интервалы и принимать решение — это сделает мониторинг облака. В данном примере мы будем использовать алармы на метрики CPU, но в нашем мониторинге их также можно настроить на такие метрики как: утилизация сети (скорость/pps), утилизация диска (скорость/iops).

Настройка тегов

После настройки мониторинга перед нами встаёт следующая задача — обнаружение инстансов и их имён (service discovery). Нам нужно как-то понимать, сколько у нас сейчас запущено backend инстансов, а также нужно знать их имена. В мире вне облака для этого хорошо подошел бы, например, consul и consul template для генерации конфига балансера. Но в нашем облаке есть теги. Теги помогут нам категоризировать ресурсы. Запросив информацию по определённому тегу (describe-tags), мы можем понимать, сколько инстансов у нас сейчас в пуле и какие у них id. По умолчанию уникальный id инстанса используется в качестве hostname. Благодаря внутреннему DNS работающему внутри VPC эти id/hostname резолвятся во внутренние ip инстансов.

Пример describe-tags доступен в документации Облака КРОК.

Настройка автоскейлинга

Теперь когда облако занимается мониторингом, и мы умеем работать с тегами, нам остаётся только опрашивать состояние настроенных алармов на предмет их срабатывания. Тут нам нужна сущность, которая будет заниматься периодическим опросом мониторинга и запуском задач по созданию/удалению инстансов. Здесь можно применить различные средства автоматизации. Мы будем использовать AWX. AWX — это open-source версия коммерческого Ansible Tower, продукта для централизованного управления Ansible-инфраструктурой. Основная задача — периодически запускать наши ansible playbook.

С примером деплоя AWX можно ознакомиться на странице wiki в официальном репозитории. Настройка AWX также описана в документации Ansible Tower. Чтобы сервис AWX начал запускать пользовательские playbook, его необходимо настроить, создав следующие сущности:

  • Сredentials трёх типов:
    — AWS credentials — для авторизации операций, связанных с Облаком КРОК.
    — Machine credentials — ssh ключи для доступа на вновь созданные инстансы.
    — SCM credentials — для авторизации в системе контроля версий.
  • Project — сущность, которая склонит git репозиторий с playbook.
  • Scripts — скрипт dynamic inventory для ansible.
  • Inventory — сущность, которая будет вызывать скрипт dynamic inventory перед запуском playbook.
  • Template — конфигурация конкретного вызова playbook, состоит из набора Credentials, Inventory и playbook из Project.
  • Workflow — последовательность вызовов playbooks.

Процесс автоскейлинга можно разделить на две части:

  • scale_up — создание инстанса при срабатывании хотя бы одного high аларма;
  • scale_down — терминация инстанса, если для него сработал low аларм.

В рамках scale_up части необходимо будет:

  • опросить сервис мониторинга облака о наличии high алармов в состоянии «Alarm»;
  • досрочно остановить scale_up, если все high алармы находятся в состоянии «OK»;
  • создать новый инстанс с необходимыми атрибутами (tag, subnet, security_group и т.д.);
  • создать high и low алармы для запущенного инстанса;
  • настроить наше приложение внутри нового инстанса (в нашем случае это будет просто nginx с тестовой страницей);
  • обновить конфигурацию haproxy, сделать релоад, чтобы на новый инстанс начали идти запросы.

В create-instance.yaml происходит: создание инстанса с правильными параметрами, тегирование этого инстанса и создание необходимых алармов. Также через user-data передаётся скрипт установки и настройки nginx. User-data обрабатывается сервисом cloud-init, который позволяет производить гибкую настройку инстанса во время запуска, не прибегая к использованию других средств автоматизации.

Так как в секции backend конфига haproxy определена опция option httpchk, сервис haproxy будет самостоятельно опрашивать состояния backend инстансов и балансировать траффик только между прошедшими health check.

В scale_down части необходимо:

  • проверить стейт low аларма;
  • досрочно закончить выполнение play, если отсутствуют low алармы в стейте «Alarm»;
  • терминировать все инстансы, у которых low alarm находится в стейте «Alarm»;
  • запретить терминацию последней пары инстансов, даже если их алармы находятся в стейте «Alarm»;
  • удалить из конфигурации load balancer инстансы, которые мы удалили.

Мы явно удаляем теги после удаления инстансов в связи с тем, что после удаления инстанса связанные с ним теги удаляются отложенно и доступны ещё в течение минуты.
AWX.

Настройка задач, шаблонов

Предыдущий сниппет создаст по template на каждый из используемых ansible playbook’ов. Каждый template конфигурирует запуск playbook набором определённых credentials и inventory.

Построить pipe для вызовов playbook’ов позволит workflow template. Настройка workflow для автоскейлинга представлена ниже:

В предыдущем шаблоне представлена схема workflow, т.е. последовательность выполнения template’ов. В данном workflow каждый следующий шаг (success_nodes) будет выполнен только при условии успешного выполнения предыдущего. Графическое представление workflow представленно на картинке:

В итоге был создан обобщающий workflow, который выполняет create-instace playbook и, в зависимости от статуса выполнения, destroy-instance и/или update-lb playbook’и. Объединённый workflow удобно запускать по заданному расписанию. Процесс автоскейлинга будет запускаться каждые три минуты, запуская и терминируя инстансы в зависимости от стейта алармов.

Тестирование работы

Теперь проверим работу настроенной системы. Для начала установим wrk-утилиту для http бенчмаркинга.

В течение времени скрипт мониторинга должен показать, что во время действия бенчмарка значение статистики метрики CPUUtilization увеличивается пока не дойдёт до значений 300%. Через 180 секунд после начала бенчмарка флаг StateValue должен переключиться в состояние Alarm. Раз в две минуты происходит запуск autoscaling workflow. По умолчанию, параллельное выполнение одинаковых workflow запрещено. То есть каждые две минуты задача на выполнение workflow будет добавлена в очередь и будет запущена только после завершения предыдущей. Таким образом во время работы wrk будет происходить постоянное наращивание ресурсов, пока high алармы всех backend инстансов не перейдут в состояние OK. По завершению выполнения wrk scale_down workflow терминирует все backend инстансы за исключением двух.

Также в Облаке КРОК есть возможность просмотра графиков используемого в посте мониторинга на странице инстанса на соответствующей вкладке.

Просмотр алармов доступен на странице мониторинга на вкладке алармы.

Заключение

Автоскейлинг довольно популярный сценарий, но, к сожалению, в нашем облаке его пока нет (но только пока). Однако у нас достаточно много мощного API, чтобы делать подобные и многие другие вещи, используя популярные, можно сказать почти стандартные, инструменты такие как: Terraform, ansible, aws-cli и прочие.

C оригиналом статьи можно ознакомиться на Хабре