Есть такой тренд сейчас - работать с IT-инфраструктурой как с кодом. Хорошо цель этого метода описывается этой цитатой:

“Enable the reconstruction of the business from nothing but a source code repository, an application data backup, and bare metal resources”

-- Jesse Robins

Я полностью поддерживаю эту идею, причем именно в этой трактовке.

Если говорить про парадигму, которую нам предлагает этот метод, то вот она:

Поддерживать модульную, легко поддающуюся автоматизации инфраструктуру, и описывать эту инфраструктуру с помощью языка высокого уровня.

Это означает для нас, как сисадминов, что мы должны пользоваться всеми наработками разработчиков ПО, такими как:

  • версионирование описания инфраструктуры;
  • полноценное тестирование описания с использованием нескольких стадий (dev, QA, staging, prod);
  • внутренние стандарты "кодинга";
  • непрерывная интеграция (continuous integration).

Проблема же, на мой взгляд, заключается в том, что многие понимают "Инфраструктуру как код" в другом смысле - "Давайте писать описание нашей инфраструктуры с помощью Chef/Puppet, словно это обычный код". Причем у Chef это выражено заметно сильнее, поскольку в качестве DSL используется чистый Ruby.

Конечно, программисты, каким-либо образом ставшие ответственными за администрирование серверов с помощью Chef, с радостью начинают использовать привычный инструмент (Ruby) привычным же образом, и получается ровно то, что они привыкли делать. Вместо декларативного описания инфраструктуры, на которое можно натравить какой-нибудь инструмент для управления конфигурациями и получить настроенную инфраструктуру, на выходе получаем программу с кучей хаков, с множественным ветвлением, с выполнением кода на Shell, которая может императивно привести систему к нужному состоянию.

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

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

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

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

  • Собрать пакет Nginx с нужными модулями на build-сервере, протестировать и поместить в репозиторий;
  • Написать шаблон конфига Nginx под ваши задачи, учитывающий различия между имеющимися средами (staging/prod);
  • Написать кукбук/манифест/роль, который будет ставить пакет из вашего репозитория, заполнять шаблон переменными, которые отличаются в ваших окружениях, и класть этот шаблон на сервер.

Вот и все, не нужны тонны кода на Ruby со вставками на Shell, не нужны сотни переменных. У нас есть описание процесса сборки пакета (spec-файл или Makefile), и декларативное описание требуемого состояния системы.

И это прекрасно подходит под один из принципов Экстремального Программирования, который звучит так:

Do The Simplest Thing That Could Possibly Work

То есть, надо сделать так, чтобы наш кукбук/манифест/роль был достаточно простым для того, чтобы удовлетворять нашим сегодняшним требованиям. Конечно, увлекаться и делать что-то "в лоб", не думая, будет неверно, но и создавать псевдо-универсальных монстров точно не стоит. Во всем нужна мера.

Что самое плохое - люди, которые пишут сам Chef, и написали этот кукбук для Nginx. Написали хорошо, но написали как программисты, а не как системные администраторы. А когда сисадмины пишут кукбуки в таком стиле, на их творения вообще без слез не взглянешь.

Именно поэтому я выбрал для управления серверами Ansible, созданный Michael DeHaan, человеком, который работал в Puppet Labs, создал Func и Cobbler, а затем, имея большой опыт и видя ошибки предшественников, написал Ansible. Ansible заметно проще Chef или Puppet, и декларативный yaml-файл с описанием требуемого состояния системы ограничивает возможность выстрелить себе в ногу и наворотить лапшеобразного императивного кода.

Если эту заметку прочтут программисты, администрирующие сервера - перестаньте толковать "Инфраструктуру как код" неверно! Мы берем лучшие наработки из мира программирования, но это не традиционное программирование. Не надо переизобретать Bash-скрипты на Ruby.


Comments

comments powered by Disqus