Оркестр перфоманса

Едва ли будет неверным сказать, что лучшие из людей
обретают радость через страдание.
Людвиг ван Бетховен

9khtxxwiwqsesccfpb5n2sbrnwo.jpeg

Я Сергей, работаю в Яндекс.Деньгах в команде по исследованию производительности. Хочу поведать вам начало истории о нашем пути к использованию оркестровки — как мы выбирали инструменты и что при этом учитывали. Всё события из статьи происходят в реальном времени, поэтому вы, дорогие читатели, следите за развитием ситуации практически в прямом эфире.


Зачем нам дирижёр в команде?

Кто же такой дирижёр? От фр. diriger — управлять, направлять, руководить — в мире музыки — это человек, руководитель разучивания и исполнения ансамблевой музыки. В нашем случае это место занимают системы оркестрации и автоматизации.

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

Как правило, команда обладает некоторым набором мощностей — назовем их серверами, на которых они реализуют свои проекты.

Подход к получению и эксплуатации этих серверов разнообразен. Несколько примеров:


  • Команда делает запрос, к примеру в группу эксплуатации, на предоставление им ресурсов с определенными параметрами.
  • Группа эксплуатации предоставляет им необходимое количество — cloud или bare metal («голое железо») — и обязуются поддерживать их в должном состоянии согласно SLA. Настройка также производится силами группы эксплуатации.
  • Команда получает только ресурсы cloud или bare metal от группы эксплуатации, настройку она производит своими силами.
  • Команда сама «закупает» ресурсы и поддерживает/настраивает их полностью самостоятельно.

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

Для себя мы выделили их в два основных типа:


  • танковая группа,
  • сервисная группа.

Танковая группа состоит из хостов с Яндекс.Танком.

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

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


Почему дирижёр нужен, даже если оркестр сам умеет играть?

Для начала мы освоили Ansible и стали «наливать» наши серверы bare metal, чтобы быть в меньшей степени зависимыми от системных администраторов — здесь выигрывают все, мы получаем новые навыки и избавляем администраторов от части работы, которой у них и без нас всегда хватает. Мы стремимся к развитию вне своей специальности и автономности команды, насколько это возможно.

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

Сейчас наливка хостов состоит из трёх ролей Ansible:


  • первая роль устанавливает OS,
  • вторая прокатывает базовые настройки для хоста, LDAP-авторизацию, к примеру,
  • и третья устанавливает в docker-контейнере Яндекс.Танк и сопутствующие зависимости.

Перейдем к сервисам, которые мы используем внутри команды.

Для своих задач мы в равной степени используем Kotlin и Python, а ещё чуть-чуть Golang. Чтобы унифицировать разработку и развертывание наших сервисов, мы решили упаковывать их в docker-контейнеры. Это даёт свободу выбора языка программирования и одновременно регулирует единый формат поставки своего приложения.

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

Согласно документации по ipv6 на официальном сайте Docker, ipv6 включается добавлением параметров в daemon.json:

{
  "ipv6": true,
  "fixed-cidr-v6": "2001:db8:1::/64"
}

При этом провайдер должен выдать подсеть ipv6, которую вы пропишете в fixed-cidr-v6.
Однако мы выбрали другой вариант — ipv6 NAT, и вот почему:


  • Сейчас docker нельзя использовать только с ipv6.
  • Наличие в каждом контейнере глобально маршрутизируемого адреса означает, что все порты (даже неопубликованные) становятся доступны всем, если не выполняется дополнительная фильтрация.
  • userland proxy для опубликования портов, iptables только для ipv4.

ipv6 NAT — это docker-контейнер, который сам управляет правилами в ip6tables и редактирует их при добавлении нового контейнера.

Чтобы это решение корректно заработало, необходимо было сделать еще ряд манипуляций. Обязательно инициализировать ip6table_nat в системе. Наличие установленного в системе модуля не гарантирует, что при запуске модуль будет загружен в ядро. Мы столкнулись с этим, когда получили вот такую ошибку при запуске контейнера с NAT на свежем хосте:

2019/01/22 14:59:54 running [/sbin/ip6tables -t filter -N DOCKER --wait]: exit status 3: modprobe: can't change directory to '/lib/modules': No such file or directory
ip6tables v1.6.2: can't initialize ip6tables table `filter': Table does not exist (do you need to insmod?)

Проблема решилась после добавления в роль Ansible инициализации с помощью модуля modprobe и загрузки при старте ОС с помощью lineinfile:

- name: Add ip6table_nat module
 modprobe:
   name: ip6table_nat
   state: present
- name: Add ip6table_nat to boot
 lineinfile:
   path: /etc/modules
   line: 'ip6table_nat'

Кстати, на хабре есть хорошая статья, которая кратко и ясно описывает преимущества и недостатки того или иного метода для работы ipv6 в docker.

Но вернемся к нашему вопросу, заданному в начале:
Почему дирижёр нужен, даже если оркестр сам умеет играть?

Теперь все представляют, как играть в нашей команде:


  • процесс «наливки» серверов создан,
  • разработка и деплой сервисов унифицированы.

Появляется резонный вопрос — как эффективно и максимально автоматизировано деплоить, обновлять, контролировать наши сервисы в docker-контейнерах?

Несмотря на то, что каждый участник оркестра знает свою партию, он может сбиваться, отходить от первоначальной задумки. Здесь мы и приходим к тому, что без дирижёра наш оркестр не будет эффективно репетировать и слаженно играть. Дирижер отвечает за все параметры исполнения, за то, чтобы все было объединено единым темпом и настроением.


Как с минимальными вложениями получить хорошего дирижера?

Тема оркестрации достаточно хорошо развита на рынке. Но сначала поговорим о вспомогательных инструментах, которые могут помочь дирижёру.

Consul — система, которая предоставляет две основные функции:


  • обнаружение сервисов (service discovery),
  • распределенное хранилище ключ-значение.

В нашем оркестре Consul будет отвечать за регистрацию сервисов и хранение их конфигураций. Есть два варианта регистрации:


  • Активная — это когда сервис сам регистрирует себя используя HTTP API;
  • Пассивная — сервис необходимо прописать вручную.

Vault — это хранилище, которое стандартизирует и унифицирует безопасное хранение и работу с секретами — пароли, сертификаты.
Вот преимущества, которые мы получим, используя этот инструмент:


  • Единый центр создания и хранения секретов, управления их жизненным циклом посредством HTTP API.
  • Transit Secrets Engine — шифрования-дешифрования данных без их сохранения. Возможность для передачи данных в зашифрованном виде по незащищённым каналам связи.
  • Политики доступов, которые удобно настраивать.
  • Аудит доступа к секретам.
  • Возможность создания собственного CA (Certificate Authority) для управления самоподписанными сертификатами внутри своей инфраструктуры.

Учитывая все наши требования, на роль дирижера годились два варианта — Kubernetes и Nomad.


Kubernetes

Сколько уже написано про него статей и книг (вот такая, к примеру), рассказано докладов, что напишу коротко — это универсальный комбайн, который может практически всё. Плата за это — не всегда легкие настройка и поддержка кластера на Kubernetes.


Nomad

Инструмент от HashiCorp, компании, известной по упомянутым выше consul и vault.

Nomad показался нам достаточно простым в установке и настройке, чем Kubernetes. Один бинарный файл работает как в режиме сервера, так и клиента. При этом Nomad покрывает весь список задач, которые мы хотим, чтобы он решал: управление кластером, быстрый планировщик, поддержка multidatacenter. Плюс при использовании consul и vault мы получаем более тесную интеграцию для оркестровки наших сервисов.

Что сейчас в работе:


  • подготовили серверы для развертывания Consul,
  • в Consul будет занесена конфигурация кластера nomad, с помощью которой nomad должен быть развернут автоматически,
  • параллельно будем устанавливать vault для хранения секретов.

Вопрос в зал — стоит ли заводить дирижёра для таких задач или оркестру и без него хорошо? Расскажите в комментариях, что вы думаете по этому поводу.


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

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

© Habrahabr.ru