Комментарии 69
Сам я из лагеря ansible'истов, но с опытом chef'а.
Я ни с паппетом ни с hiera не работал, но первый же пост на хабре (https://habrahabr.ru/post/242657/) явно говорит, что «Паппет изначально, видимо, не задумывался, как решение для больших инфраструктур, по крайней мере иерархия в него изначально заложена из рук вон плохо.». Вот такое же у меня мнение и про ансибл (причём не только и не столько в контексте количества серверов, сколько в вопросе работы с сложными структурами данных и отношениями).
Это при том, что нормальный админ уже давно бы сделал hdparm -W 0 /dev/sda на 400 серверах в цикле. Возможно, к 300 серверу он бы понял, что sda иногда — это виртуальный cd-rom и надо на каждом сервере проверять кому атрибут выставляется..., но это уже другая история.
При параллельном раскатывании конфигурации на 400 машинах было бы так же, только более эффективно? Или использование какого-нибудь ansible как-то от такого страхует? Или может быть помогает исправлять проблемы?
Но в статье я намекал на другое — … да, да, мы знаем, что сейчас наша конфигурация неправильно настраивает опции кеширования для дисков, но для внесения изменений нам надо сначала переписать кусок, отвечающий за классификацию блочнных устройств.
Если задача решается обстоятельно, то проблемы «на некоторых дисках он sda, а на некоторых sdb» просто не будет. Хотя сами задачи будут выполняться медленее, качество их выполнения будет значительно выше.
Пример с hdparm был примером ошибочного применения наколенной автоматизации в крупном масштабе. Диагностики нет, обработки ошибок нет, проверки на условия нет, есть только success path.
Грамотный подход к задаче позволяет иметь такой рабочий процесс, в котором для выполнения такого рода задачи придётся (в силу специфики процесса) объяснить где что и по какому случаю делать. Объяснить машине и человеку (который читает код). В ходе объяснения будут всякие неловкие вопросы «а точно sda?» и т.д.
не от долгого секса с ней, когда «ну наконец уже» а именно получая удовольствие от процесса и результата?
нормальная система должна позволять простые вещи делать просто. а сложные — делать управляемо сложно.
то есть сложность должна быть типа sqrt(N) (а то и log(N)).
а все эти системы переходят от A+N (где A = базовые знания про сервер, вопрос секунд, а N = число серверов) на Q + N/50 (где Q на несколько порядков больше чем A).
то есть сложность остаётся зачастую близкой к линейной, причем коэффициент огромный, так что делитель позволяет выигрывать только когда компов становится действительно много.
ну это паппет. ансибль чуть лучше, у него саблинейный уже коэффициент у N, но всё равно, сцуко, Q зашкаливает…
Я пока не понял идеологию шефа/паппате с клиентами на сервере-клиенте, мне близка идеология Ansible и по сути. вся конфигурация сервера — прописать мак на DHCP, и прописать его в конфиг ансибла, дальше я буду иметь сервер почты, днс или чего-я-там-захочу.
Но как и у всех решений — есть их путь, и костылизм. у меня была конфигурация фаервола, где половина плейбука raw команды, потому как штатный модуль 90% задач поставленных нок инженером выполнить не мог, потому как сильно базовый
Если много shell или raw, и код планируется совпровождать долго, то писать модули — это лучше, чем shelll-нинзя-стайл.
Меня, например, жутко бесит, что ансибл считает «not a programming language», что мешает (крупно мешает!) использовать паттерны нормальной разработки. В этом смысле я бы больше поддерживал chef, если бы не одно «но» — их ужасная, душераздирающая инженерная практика с вендорингом всего и вся. (chef-bundle идёт с тремя запакетированными версиями beam.smp).
Это надстройка над системой автоматизации деплоймента Fabric
Список реализованных в Fabrix функций: Reference
Пример использования: contrib
В каталоге create-server-partitions — скрипт на чистом Fabric для создания разделов на жестких дисках, в каталоге infrastructure-as-code — настройка сервера виртуализации KVM + ZFS и виртуальных машин.
Вообще да, понимаешь что с возрастом приходит лень и автоматизация и количество администрирования практически сходит на нет, и не важно — один сервер или сотни.
Вообще те же групповые политике в MS были давно и иногда мне кажется что они стали идеей для шефа, паппета и ему подобных. Еще 10 лет назад, в эпоху 6й фри у меня было пару десятков скриптов на баше, которые делали тоже, что сейчас делает ансибл.
А я видел и конфигурации, где в процессе обработки логов CI/CD еще и динамически меняли конфигурации тестовых площадок и продакшена.
Ansible, cfengine, Chef, Juju, Pupplet, SaltStack, Quattor… Ни одно из этих решений не является хорошим
Подробностей бы — где какие грабли лежат? Особенно любопытно Ansible vs Salt.
Плюсы ансибла — низкий порог вхождения, нулевой футпринт на целевой ноде, совместимость с сетевым оборудованием (можно пойти и сконфигурировать), интересные трюки с делегацией, питон (это субъективное, ибо chef/puppet — это ruby).
К сожалению практически все configuration management systems сегодня требуют достаточно тяжелых зависимостей на клиенте. Для меня идеальная cms должна обходиться стандартными binutils на клиенте и работать через ssh, т.е. никаких дополнительных демонов. Из известных мне решений этим условиям удовлетворяет capistrano и cdist. Я посмотрел примеры конфигураций для cdist и как-то не впечатлитлся. Capistrano выгдлядит более привлекательно, но пока что не было шансов попробовать.
Ну, собственно, ansible требует python на хосте, но может сам поставить даже и питон (вот кусок моего кода для бутстрапа контейнера):
- raw: test -x /usr/bin/python || apt-get update && apt-get -y install python
Он в буквальном смысле получает систему (в которой даже ssh нет) и выдаёт мне на выход рабочую машину ("рабочая" часть идёт ниже, после bootstrap'а).
Про нет ssh не понял. ansible ведь работает через ssh, или я что-то упускаю?
Насчёт «без питона» — многие вещи на generic OS делаются лучше с питоном. На shell'е очень тяжело работать с структурами данных — простейшая хеш-таблица (словарь) — и уже проблемы. Распарсить json — целое приключение и т.д.
Мне кажется, что в процессе конфигурирования клиента не надо парсить json и выполнять другой сложный код. Это вполне можно сделать на управляющем сервере. В моем представлении идеальная scm должна сделать ровно 2 ssh запроса в процессе конфигурирования клиента. Сперва собрать необходимые данные о клиенте, потом обработать их на управляющем сервере, собрать скрипт для конфигурирования клиента и 2-м ssh запросом выполнить этот скрипт.
«И выполнить этот скрипт» — не получится. Логика конфигурации может требовать разного поведения в зависимости от того, поменялось что-то или нет, были ошибки или нет.
Принимать решения надо после каждой операции, причём некоторые решения могут требовать результата с нескольких серверов (т.е. решение нельзя делегировать). Использование bash'а выглядит большим аттавизмом, потому что в bash'е очень плохая типизация, а многие API подразумевают типизацию данных. Интерфейсы с СУБД, corosync, openstack и т.д. — все они лучше в виде языка программирования, а не шеллового пайплайна.
1) сделать_сложно
2) если в сделать_сложно есть «мастер», сделать действие2 на хосте «другой».
3) перезапустить сервис, если в сделать_сложно были изменения
При этом «перезапустить сервис» может выполняться не более чем на 8 серверах из 17 одновременно.
Для выполнения второго этапа нам нужно взаимодействие с мастер-нодой (сервером). Так что «просто прислать большой баш» не катит, нужно взаимодействие между центральным сервером и конфигурируемыми серверами много раз. Более того, ответ на шаге 1 влияет на шаг 2, так что он нам нужен в структурированном виде. Код возврата, stdin, stdout, статус changed или failed (код возврата и failed это не одно и то же, т.к. мы можем иметь ненулевой код возврата и всё равно success), возможно, нам нужна ещё какая-то информация (условно, модуль stat для файла, который позволяет делать условия stat.exists, stat.isdirectory и т.д.).
Идея «заслать баш и не париться» работает только если баш никогда не ломается и мы никогда не хотим знать что там случилось. Это, мягко говоря, не очень рабочий подход.
- lxc_container:
name: '{{inventory_hostname}}'
state: started
template: download
template_options: '-d {{distro}} -r {{distro_version}} -a amd64'
register: container_data
При кажущейся тривиальности использования, внутри — куча логики, выполняющейся на хосте, и возвращающеся на управляющий хост.
Ну, собственно, ansible требует python на хосте
Посмотрел, ansible и вправду хочет питон на конфигурируемой ноде. Мне какзалось, что одним из преимуществ ansible было, что ничего, кроме ssh доступа не нужно. Скажите, ansible всегда хотел питона на клиенте, или это позднее явление?
Для своих сервисов — да. Ансибл ещё полезен, но уже не так критичен, когда всё в контейнерах. Особенно когда задача "раскатать сервис на N серверов" решается встроенными средствами docker swarm, ECS и т.п.
Но сервера и инфраструктура не состоят из одних кастомных сервисов, ещё нужно настраивать как сами сервера (сетевые интерфейсы, файрвол, тюнить ядро, обновлять ОС, etc.) так и стандартные сервисы, которые в теории тоже можно запихать в контейнеры, но на практике они ещё обычно не там (dns, dhcp, smtp, cron, ssh, openvpn, мониторинг самого сервера, etc.).
Как этот maas избавит от необходимости, например, настраивать bcache для работы связки "несколько SSD + большая полка с дисками", или настраивать параметры ядра на балансере, потому что сколько haproxy/nginx в контейнер не запаковывай, без настроек ядра максимальной производительности из них не выжмешь? Контейнеры это ещё не всё
Хорошая статья, спасибо!
А кто что может сказать насчет Rundeck-а? Может ли он быть заменой (именно заменой) Ansible?
У меня есть большой пунктик насчёт несвободных инструментов, так что я бы сказал, что «очень плохо». Возможно, кто-то опишет его лучше, но в условиях достаточного ассортимента opensource, я бы не стал смотреть на продукты с закрытой моделью.
А что именно смущает? В сравнении меня мог бы смутить только пункт Advanced Workflow Capabilities, недоступный в открытой версии.
А изначальный вопрос был про сравнения подходов у этих систем. На первый взгляд, Rundeck — просто веб-морда для запуска задач, соответственно, он попроще будет. Но не окажется ли потом, что простота выходит боком, когда упираешься в ограничения?
Сейчас вообще нет способа настроить биос автоматически.
Поэтому надо или заказывать себе особые биосы у производителя или настраивать руками все 100500 серверов.
Если бы настройка производилась руками, то нам бы потребовалось дополнительно несколько сотен человек обслуживающего персонала.
Жаль что в наших супермикрах такого нет.
А как определяется «оптимальность» настроек?
Может есть какой-то общедоступный мануал?
Оптимальность настроек на самом деле сводится к
а) отсутствию ерунды (типа отключения устройств, процессоров и т.д.)
б) выключению режима максимального энергосбережения
в) сбросу странных настроек drac'а
г) тому режиму загрузки, который мы предоставляем.
Копия вашего продакшена, которая ничем не занимается. На которой вы можете посмотреть ответ на вопрос «что будет, если я поменяю версию сервера?» и другие смешные эксперименты, не сломав ваш продакшен.
Насчёт рефакторинга. Рефакторинг — это переписывание куска существующего (обычно, кода, но оно так же применимо и к конфигурации), таким образом, чтобы оно делало то же самое, но в более понятном и ясном виде для читающего. Обычно под это так же подгоняют всякие улучшения архитектуры и т.д. В контексте управления конфигурациями минимальный рефакторинг может состоять, например, из замены переменных external_api_ip, listen_ip, api_ip (в мониторинге) на одну переменную. Маленький шаг, делающий последующую жизнь легче.
Насчёт бэк-офис — это «офис», подальше от серверной. К вершинам devops отношения не имеет, и является аналогией обычного бизнес-деления — фронт-офис — это ресепшен и менеджеры, разговаривающие с клиентами, бэк-офис — бухгалтерия, старший менеджмент, люди, которые не говорят с клиентами (обычно). В контексте IT — подальше от серверов и поближе к офисной жизни.
Привести примеры автоматизации очень сложно, потому что если я приведу свои примеры, то они для вас ничего не скажут (какое вам дело до того, как у меня bgp-пиры переконфигурируются?), а привести примеры, актуальные для вас — это во-первых сложно, а во-вторых это уже чистой воды консалтинг.
Но, всё же попробую.
Сейчас я работаю над playbook'ой ансибла, которая будет брать бэкап, поднимать в контейнерах микрокопию продакшена и прогонять тесты (написанные вместе с программистами), которые говорят «похожи ли эти данные на продакшен». Эта плейбука будет автоматически запускаться раз в сутки и проверять, что:
а) бэкап есть
б) бэкап можно загрузить в базу
в) данные в бэкапе являются ожидаемыми данными (а не чем попало)
г) У нас есть работающая процедура восстановления СУБД в случае аварии (я меняю две переменные и вместо контейнеров оно поднимается на новых железных серверах).
Это пример правильно сделанной автоматизации очень рутинной задачи «проверить, что бэкапы сделались».
Качает дампы, для проверки разворачивает на тестовый сервер при необходимости можно добавить проверку каких-либо таблиц и отправляет результат письмом. Я использую mutt(исторически так сложилось) т.к. он умеет аттач) соотв. он должен быть установлен и настроен, но можно прикрутить любой другой почтовик.
Весь же вопрос в воспроизводимости. Вот на ваш тестовый сервер базу накатали N раз, а на новый сервер она так же накатается? Если да, то ваша уверенность основывается на предположении, что «в этом месте в софте багов на этот раз точно нет» или на чём-то другом?
Весь же вопрос не в том, что с системой управления конфигураций вы можете сделать что-то, чего не можете руками (и на шелле). Можете. Тьюринг-полнота — ваш друг (и враг).
Система управления конфигурациями позволяет описать происходящее как полностью воспроизводимый процесс, no golden artefacts required. Сам «тестовый сервер» перестаёт быть The Server и становится 'a server', который поднимается одной командой. Снова и снова в той же самой конфигурации.
Кстати, я посмотрел на ваш код. Если у вас в дампе пусто, то psql скажет, что всё хорошо.
echo " "|gzip -c |gzip -d | psql -v ON_ERROR_STOP=1 -h $dbhost -U $dbuser $dbtest > /dev/null 2>> "$dbserr" \
|| { printf "${db_error[*]}"; cat "$dbserr"; continue; }
И всё хорошо. Только вместо бэкапа пробел.
Размер файла пишется в лог, дамп с пробелом будет подозрительно мал)
Я просто показываю насколько хрупкими и неустойчивыми чаще всего оказываются скрипты на баше. Обработка ошибок на баше — это невероятно сложно, и редко кто-то такое делает. Вместо этого, все полагаются на дефолты. Что хорошо для однострочника «тут и сейчас», но совсем не годится в качестве основы для устойчивого продакшена.
Сейчас я работаю над playbook'ой ансибла, которая будет брать бэкап, поднимать в контейнерах микрокопию продакшена и прогонять тесты (написанные вместе с программистами), которые говорят «похожи ли эти данные на продакшен».
Зачем писать это руками, когда есть виртуальные лаборатории в самом софте для бекапа?
Но вместе с этим будет и ещё одно ощущение — что стало меньше кнопкодавства и стало больше думания. Вместо «пойти и поменять» будет момент размышления «а правильно ли менять так?», «А почему его вообще надо менять?», будет больше рассуждений об архитектуре (почему на сервере А мы меняем одно значение а на сервере Б другое? Можем ли мы найти что-то общее между этими изменениями и описать это общее как новую сущность?)
Я и без
Вот, например, какое у вас покрытие кода для написанных вами программ? А как у вас с интеграционным тестированием этих программ?… Но это же сложно, мы же сисадмины, а не программисты какие-то, правда?
Только главное свойство скрипта состоит в том, что он оперирует понятиями нижелещащего (своего) уровня. Это означает, что на скриптах нельзя строить абстракции, обобщения или иные средства снятия головной боли с человеков. Хорошая программа даёт возможность оперировать понятиями более высокого уровня, абстрагироваться от мелких нюансов реализации.
ansible — при всех его минусах — программа (так же как и любая другая система управления конфигурациями). Потому что она смещает фокус с низкоуровневых деталей вроде «включать ли pipefail для моего башового однострочника?» в область высокоуровневых — я опрерирую вопросами «воспроизводимости инсталляции», «идемпотентности плейбуки». Ближайший вопрос, который меня интересует — не интеграция stdout'а с pgdump'а, а такая структура database-recovery.yaml, которая позволит её одинаково применять её и для железных серверов и внутри слейва jenkins'а внутри контейнера.
Ключевой проблемой NIH (not invented here), или русский аналог «сами напишем» состоит в том, что вы напишите хуже, чем люди, пишущие продукт. Не потому что вы лично хуже программист, чем они, а потому что у вас бюджет времени на написание «движка автоматизации» явно меньше, чем несколько лет. И их «движок» пишет много людей, и ещё больше людей тестирует. Как до релиза, так и после (багфиксы).
Вторая проблема: вот вы будете передавать компетенцию следующему человеку. Потому что у вас повышение, или вы нашли себе другую работу. Приходит человек, и ему выдают, например, 14000 строк на баше. С сопроводительной документацией, да? Компетенцию человек будет получать очень долго, а главное, очень узкоспециализировано, потому что нигде, кроме вашего проекта, она ему не пригодится.
Ансибл (или любая другая система) даёт универсальный инструмент, для которого можно ожидать квалификации у новопришедших, для которого есть документация, книги, видео для обучения.
Если это не убеждает, то давайте я задам вам другой вопрос: вот у вас есть bash. На нём можно сделать всё. Зачем python?
Вот ответите на этот вопрос — ответите и на вопрос, зачем системы управления конфигурациями вместо скриптов.
Принудительное введение в системы управления конфигурациями