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



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


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


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


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


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


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


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

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


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


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

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


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


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


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


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


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


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


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

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


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


Небольшая ремарка про ipv6 в 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, так как нам этого хотелось.


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

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


  1. negasus
    15.03.2019 22:35

    Не, ну как так. Только уютно устроился, а пост закончился. Ставлю плюс авансом! (В чатик тоже вписался)


    1. misterkramer Автор
      16.03.2019 15:08

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