Комментарии 26
Наблюдаю рядом сверхсложные инсталляции на chef'е (106000 строк) и ansible'е (14000 строк).
Мои наблюдения: как система управления конфигурациями chef куда более продуман на уровне абстракций и переиспользования кода, а так же работы в большой команде (когда каждый видит и трогает маленький кусочек, а на выходе большой и необъятный продакшен). Однако, у него есть гигантский, неподъёмный техдолг: омерзительные worst practice по пакетированию и сопровождению самого chef. Те «deb'ки», которые предоставляет chef — это гигантские бандлы где вендорят всё (включая базы данных и реббит, в некоторых дебках beam.smp запакетирован два-три раза, потому что его тоже вендорят).
Второе возражение — руби. Кому-то это большой плюс, но меня альтернативное сознание руби совершенно не радует, так же как и не радует состояние ruby в смысле пакетирования в debian/ubuntu.
Ansible: туман в голове. С его помощью можно описывать совершенно нереально сложные сценарии и творить чудеса, но все эти чудеса держатся на самодисциплине. Ансибл не предоставляет никакой разумной policy (и это редкий случай, когда я говорю, что софт должен предоставлять полиси), а значит, все методы выстрелить в ногу оставлены пользователю as is, многие без предупреждения.
При этом ансибл написан на питоне и живёт разумно как в качестве хост-софта, так и в качестве virtualenv'а. Довольно разумная система lookup плагинов даёт возможность делать кульбиты на питоне, зато всё остальное — довольно дуболомный и простой линейный код на ямле, в котором даже include_role не вызывает особой боли (кроме ситуации, когда переопределяются handler'ы, но я могу сказать «не делайте так»).
При этом инфраструктура chef'а куда более заточена на тестирование и модульность.
При этом chef пишется товарищами с прицелом на энтерпрайз-пользователей (винды), так что примерно половина хорошего, которая могла бы быть, у них отсутствует.
По поводу поста:
DARTS выглядит и звучит крайне любопытно.
Какой у нас на хосте руби? Системный 1.8? Завернутый в магию RVM? Зашимленный в rbenv? Какой-нибудь странный самосбор в /usr/local? А на маке? А на винде?
С контролем этого хозяйства раньше были реальные проблемы. Сейчас просто притаскивает с собой все что нужно и работает. Лишние 200Мб на диске проблемой редко когда будут.
В этом смысле питон куда более разумно интегрирован, и умудряется успешно избегать вендоринга (не запрещая его в то же самое время).
В огромном коде сложно разобраться в любом в фреймворке. Зато у Ansible есть идемпотентность.
Когда как. Если специально тратить время на корректное написание и тестирование ролей, то она есть.
У модулей она обычно есть, но тоже не всегда. Это даже без учёта багов: был, например, очень неприятный момент с mount
и пробелами в name
и/или src
.
При этом ранлист в шефе состоит из рецептов кукбук, и каждая кукбука имеет свои переменные, свои тесты и позволяет использовать себя в разных местах несколько раз (например, собирая от других кукбук «заявки» на установку пакетов).
В ансибле этого нет. Всё что там есть в ролях — это plays. На их базе можно попытаться реализовать подобие кукбук и рецептов, и более того, в крупных инсталляциях это приходится делать обязательно, через include_role с специально подготовленными переменными (специфичными для роли). Но это приходится изобретать самому, и поддерживать эту полиси силами дисциплины. А в шефе это — на уровне кода.
Я как раз сейчас пишу большую простыню (на английском) про best practices для ансибла в сложных проектах. И большая часть того, что я пишу — это то, что «надо изобретать для себя самому», поскольку от ансибла нет никаких поддерживающих элементов.
Например, в больших проектах надо обязательно различать execution groups (те, которые указываются в hosts в play'ях), query groups (те, которые опрашиваются в циклах внутри всяких acl'ек и т.д. на тему разрешения доступа), и group variables groups, задача которых — предоставлять общие переменные для всех членов этой группы.
Вот если это разделение не соблюдать, будут постоянно вылазить косяки и неудобства. То мы лишнее пишем на хост (просто потому, что ему надо было дать доступ к базе данных), то мы лишний хост вписываем в acl'ы (потому что ему надо было что-то поправить), то кто-то имеет перекрытие переменных из разных групп, то кто-то не видит нужные переменные.
Вот эту штуку — тоже надо поддерживать полисей в голове, и никак не иначе.
Хорошая полиси позволяет получить хорошие практики и отрезать плохие на уровне синтакисиса или подразумеваемого workflow, а не на уровне дисциплины в команде.
Кроме того, есть вещи, которые просто невозможно описать в декларативном виде. Даже ансибловое «state=restarted» — это не декларативное, это завувалированное императивное «перезапусти, пожалуйста».
Пример выше про «state=restarted» — это раз.
И любое действие — это императивный вызов, он просто с идемпотентностью в лучшем случае: поставь если не стоит, создай если нету и т.д. На ансибле ты не описываешь конечное состояние, ты пишешь «сделай а, сделай б»
И вот декларативный пример, который, конечно же не будет работать:
# псевдо-код
- service: httpd
state: started
- package: httpd
state: installed
Как опубликуете — поделитесь ссылкой здесь, пожалуйста. Всегда интересно посмотреть на чужой опыт на том же поле граблей ,)
идемпотентности ансибла хватает на раскраску вывода в разные цвета и нотифиейшены
От них часто тоже толку не сильно много, если не делать регулярно meta: flush_handlers
, т. к. в длинных плейбуках, особенно при их активном написании рано или поздно случится радостный красненький failure, который дропнет все нотификейшны.
Вот насчёт красненького, который хэндлерам не даёт отработать — это я не думал. Спасибо, буду думать. Плохо будет, если случится.
Я последнее время от использования handler'ов вообще ушел, насколько это возможно. Иногда в сторону маркерных файлов, хотя это и раздувает плейбуки.
Хотя меня не смущает лишний раз дёрнуть systemctl daemon-reload
безусловно (с changed_when: no
). Это гораздо лучше чем рестартануть сервис со старым unit-файлом.
Самое, пожалуй, печальное из последнего — запрет на action+args с использованием собранного снаружи словаря для args. Далеко не все модули имеют разумные замены для параметров эквивалентные default(omit)
. Скажем, в том же gluster_volume
для replicas
0 оказался вполне нормальным аналого отсутствия параметра, но не всегда так везёт.
Для этого в хендлерах рестарта должно быть просто выставление файлового флага (в районе /run), а потом обычная таска должна по этому флагу рестартиться. /run чистится при старте сервера, так что оно идеально для таких задач.
странно, что каждый должен изобретать велосипед для таких базовых вещей.
А главное, я не знаю какая у них лицензия, но я точно знаю, что ими нельзя пойти и сделать что-то прикольное за 5 минут на виртуалочке в лаборатории. Лицензии, и всё такое.
За игроками следили дилеры, за дилерами менеджеры, за менеджерами бригадиры, за бригадирами старший смены, за старшим смены администратор, за администратором я, а за всеми нами следили камеры.Фильм Казино
Возможно, ошибаюсь, но насколько я понял, проблема не устранена, и при неудачном стечении обстоятельств всё может повториться. Если баг опять пройдет, пусть удлиненный, цикл ревью/тестирования и вырубит по какому-то новому триггеру баш и cfengine — сервера все так же не удастся быстро вернуть к жизни.
Подробнее можно почитать в посте «Три дня, которые потрясли нас в 2013»
TL;DR: мы готовы автоматизированно починить bash и cfengine на всём проде через ipmi.
Как не положить тысячи серверов с помощью системы централизованного управления конфигурацией на примере CFEngine