Abstract: как заставить себя изучить любую из существующих систем конфигураций и перестать редактировать файлы на сервере руками.


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


Введение для отшельников, которые не слышали что такое configuration management systems


Уже многие годы (по айтишным меркам — три поколения как) существуют программы, которые позволяют автоматизировать процесс конфигурации серверов. Все эти программы сложные, они вторгаются в святую святых администраторов и заставляют их делать "всё не так, как раньше". Их изучение и интернализация (признание, что "так надо и так правильно") — абсолютный must have в карьере любого системного администратора.


Главная боль любой системы управления конфигурациями


Главная боль состоит в том, что система управления конфигурациями ломает привычную автоматику пальцев. Раньше вы могли поднять веб-сервер за 2 минуты почти не глядя на экран. Теперь вам предлагают потратить на абсолютно те же самые действия минут 15-20 (если вы хорошо знаете систему управления конфигурациями) или даже несколько дней (!!!!!), если вы её изучаете.


Это преступление против личной эффективности. Уменьшить её в десять (0xA) раз — и это они называют прогрессом?


Вне зависимости от всех остальных аргументов, эта мысль будет преследовать вас всё время. Даже спустя годы. Вы не просто нажимаете больше кнопок для того, чтобы сделать то же самое, но и вынуждены делать это медленнее, вы вынуждены ждать компьютер (никогда раньше вам не надо было ждать десятки секунд пока редактор "отредактирует" файл и перезапустит веб-сервер). Хуже, в момент, когда вы пишите примитивную конструкцию в конфиге, вы будете вынуждены бороться с лишними пробелами в DSL'е (специальном птичьем языке программирования, который надо выучить); думать о всякой невероятно сложной посторонней фигне; делать специальные услуги роботам. Отладка будет хуже и отвратительнее — вместо нормального сообщения об ошибке из-за опечатки в конфиге вы будете получать невнятную oversharing простыню вывода на два экрана, чтение которой занимает больше времени, чем "пойти и сделать вручную".


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


Ну как, я "продал" вам эту технологию? Готовы отбиваться всеми силами от попыток внедрить её на рабочем месте?


Перед тем, как мы продолжим говорить про системы управления конфигурациями, я хочу показать на очень иллюстративный пример из психологии зефирный эксперимент. Для тех, кому лениво читать Википедию, пересказ: детям дают зефирку, и говорят, что если они её не съедят за 15 минут, то им дадут вторую (и обе можно будет съесть). Чем старше ребёнок, тем больше вероятность, что он продержится 15 минут. Малыши не могут себя сдержать и съедают зефирку сразу, хотя потом становится обидно. Этот эксперимент проверяет механизм "отложенного удовольствия".


Именно это и предлагают системы управления конфигурациями. Вы тратите пол-часа на операцию, которую вы можете руками сделать за 3 минуты, а потом эту операцию можно выполнять снова и снова (когда нужно) без затраты трёх минут. И главное, без вовлечения головы. Чаще всего эту процедуру делегируют CI-серверу (jenkins, buildbot, etc), и тогда это открывает дверь для первого шажка к волшебной двери по имени CI/CD.


Staging


А этот шажок называется 'staging'. Копия вашего продакшена, которая ничем не занимается. На которой вы можете посмотреть ответ на вопрос "что будет, если я поменяю версию сервера?" и другие смешные эксперименты, не сломав ваш продакшен.


Безусловно, staging можно сделать и без систем управления конфигурациями. Но кто будет следить за тем, что staging похож на продакшен? Более того, кто будет следить, что после вашего смешного эксперимента стейджинг всё ещё похож на продакшен? Если вы делаете смешной эксперимент на результате предыдущего смешного эксперимента, то возможно, результат будет отличаться от того, что получится потом на продакшене.


Этот вопрос "кто будет следить?" на самом деле с подковыкркой. Если у вас не гигантский раздутый штат в котором у вас может быть пара человек, которые следят за staging'ом, то ответ на него "никто". Никто не следит. Что же делать?


Ответ: "до основанья мы разрушим," и пересоздадим с нуля. Если в этом процессе от человека требуется больше минуты времени, то, разумеется, никто этого делать не будет. Слишком уныло снова и снова делать то же самое ради исправления "смешного эксперимента".
Обычная мысль "Да чего его переподнимать, я сейчас всё назад верну руками, так быстрее". На выходе — смешной эксперимент и результат его исправления, вместо "копии продакшена".


А вот если есть робот, который "пойдёт и всё сделает сам", вот тогда да, никакой проблемы. Пошёл и сделал.


Размножение staging'ов


Если переподнять стейджинг так просто, то почему бы его не поднять в ещё одном экземпляре? Он может быть попроще, в нём не будет какой-то из важных сложных тяжёлых компонент, но нужный кусок, над которым вы работаете прямо сейчас — почему бы и нет?


А ещё он может быть на localhost'е, в виртуалке или контейнере. Что даёт вам практически нулевую латенси при работе (приятно), поддержку оффлайнового режима (полезно). Это потребует чуть-чуть работы с системой управления конфигурациями, но куда меньше, чем может показаться. А дальше — тык-тык и у вас свежий кусок копии продакшена (или даже чего-то специфичного для вашего фичебранча из гита).


Рефакторинг


После того, как у вас есть написанный процесс превращения нескольких серверов в продакшен и вы можете повторять его снова и снова (малыми усилиями), вы вольны начинать менять кусочки этого процесса (на более удобный/правильный/модный процесс) и смотреть что получилось.


Это требует второй части системы управления конфигурациями — валидации серверов. Об этом мы поговорим чуть позже, но пока сфокусируйтесь на простой идее: вы можете попробовать поменять что-то в процессе конфигурации сервера и посмотреть что получится. За бесплатно. (От себя: когда я не уверен, я иногда запускаю 2-3 версии в параллель на разных стейджингах чтобы выбрать лучший).


code review


Рефакторинг и хранение инструкций для системы управления конфигурациями в гите делает возможным проводить code review (если у вас больше одного человека в команде). code review это круто! Во-первых он дисциплинирует не оставлять кривизны. Во-вторых вы учитесь у друг друга как делать лучше. В третьих это увеличивает взаимное знание о проекте и происходящих в нём изменениях. Развивая линию ci/cd, с некоторыми усилиями можно даже видеть результаты прогона предлагаемых изменений на временной инсталляции — и робот может завернуть pull request просто потому, что он "всё ломает" — no human involved.


Тесты


Если у нас есть набор инструкций для системы управления конфигурацией, то мы можем проверить результат. Для этого есть масса интересных решений: testinfra, goss, inspec, serverspec, etc. Фактически, эти тесты позволяют проверить результат применения вашей конфигурации. Например, "на 80ом порту слушают", "в мониторинге появилось 180 чеков", "пользователь Х может залогиниться на сервер" и т.д. Когда у вас появляются такие тесты, то вы можете уже сколько угодно играться с процессом — если тесты проходят, то вы всё сделали правильно. Благодаря этому, вы можете пробовать новое (дерзкое) и не бояться неожиданного (например, "ой, я же не подумал, что включение SSL сломает весь мониторинг").


Job security


Системы управления конфигурациями напрямую угрожают рабочим местам низкоквалифицированных системных администраторов. Если раньше нам нужно было 20 администраторов, каждый из которых мог управлять 20 серверами, то теперь команда из трёх (чуть-чуть более квалифицированных администраторов) прекрасно может справляться с 400 серверами. На самом деле один тоже может справляться, но 2-3 дают большую компетенцию команде, меньший бас-фактор (концентрацию знаний у единственного человека) и улучшают атмосферу в коллективе благодаря взаимной ответственности за качество работы. И с job security всё просто. Либо вы в списке этих трёх администраторов, либо нет.


На самом деле я чуть-чуть лукавлю и реальность обычно выглядит так: вместо 60 серверов у трёх администраторов у них на руках оказывается 400 (1000? 2000?) серверов, и варианта "нанять ещё 17 администраторов" просто не стоит по бюджетным причинам. Но это особенности растущего рынка и дефицита квалифицированных кадров, а общий аргумент всё равно остаётся: системы управления конфигурациями повышают эффективность труда, и на рынке оказываются более востребованы люди с более высокой эффективностью труда.


Ещё одна программа, которая требует внимания


При всей позитивности необходимости вышесказанного, любая система управления конфигурациями — всего лишь программа. Это означает, что будут баги. В том числе обидные требующие делать неудобно и некрасиво лишь бы обойти баг. Это означает, что очевидные архитектурные фичи не будут реализованы просто потому, что у программистов иное видение направления движения проекта. Это означает, что вместо части документации будет "Документация" (которая находится в каталоге src). Как любая другая программа, она будет требовать внимания к своему внутреннему миру, уделения себе времени, компетенции (и ещё времени на обучение).


И ещё раз о смене парадигмы


Всё это (включая баги и глубокий внутренний мир) — потребует адаптации мышления под модель, которая диктуется системой управления конфигурации. Управление конфигурациями — крайне инвазивная сущность, которая хочет быть главной во всём, и многие рабочие процессы придётся подстраивать под требования этой программы. Будет множество граничных моментов, когда станет хуже (раньше можно было сделать лучше и проще), будет множество раз, когда будет ощущение выполнения нелепого ритуала вместо нормальной работы.


Но вместе с этим будет и ещё одно ощущение — что стало меньше кнопкодавства и стало больше думания. Вместо "пойти и поменять" будет момент размышления "а правильно ли менять так?", "А почему его вообще надо менять?", будет больше рассуждений об архитектуре (почему на сервере А мы меняем одно значение а на сервере Б другое? Можем ли мы найти что-то общее между этими изменениями и описать это общее как новую сущность?)


Онтология, или 2nd hard problem


Онтологические проблемы будут в полный рост. Размышления над "общим для разных изменений" будут постоянно приводить к появлению новых вещей, а новые вещи требуют имён. Придумывать же имена, как известно, это вторая сложная проблема в IT (первая — инвалидация кеша), и она сложна потому, что придуманное название определяет свойства и ожидания от объекта. И вам придётся каждый раз мучительно придумывать имена. Каждая ошибка — кусок кривизны в архитектуре. Если раньше изменения были "потому что надо поменять", то теперь изменения будут, потому что "так нужно для реализации свойств сепульки". Я старался избегать анекдотических примеров (из жизни), но всё-таки приведу. У меня в одном проекте ушло три недели на то, чтобы придумать имя "системная конфигурация" (для описания той части изменений, которые затрагивают настройки серверов и требуют использования ansible, как противоположность "программной конфигурации", для описания той части, которая не требует вмешательства ансибла). Идея оказалась разумной и помогла разделить невозможно переплетённый комок зависимостей "надо поменять на сервере А но только после того, как пользователь поменяет в интерфейсе Б, но если пользователь поменяет В, то нам А трогать не надо, а если пользователь поменяет Е, то поменяется В и Б, так что нам надо как-то одновременно поменять и конфигурацию сервера, и ту часть, которая ансиблом не конфигурируется". Уф… Давно забытый ужас. Который надо было прочувствовать, продумать и найти имя для отдельной сущности внутри него.


Переезд с фронтира в бэк-офис


Поскольку кнопки для смены конфига на сервере жмутся всё меньше, а раздумий об абстрактном всё больше, то жизнь постепенно переползает с ssh user@server на git commit.
Это означает, что вслед за системой управления конфигурациями приходит многое из жизни программистов. Структура кода (кода!!), тесты, выразительность и понятность, code review, готовность и устойчивость кода (кода!!) к неожиданным изменениям ТЗ, само ТЗ начинает так или иначе появляться. Появляются issue, которые не "чинить сейчас", а "придумать как устранить", появляется техдолг (сейчас нафигачили, надо переписать), появляется бэклог, появляются well-known bugs. Пример: .., да, да, мы знаем, что сейчас наша конфигурация неправильно настраивает опции кеширования для дисков, но для внесения изменений нам надо сначала переписать кусок, отвечающий за классификацию блочнных устройств. Это при том, что нормальный админ уже давно бы сделал hdparm -W 0 /dev/sda на 400 серверах в цикле. Возможно, к 300 серверу он бы понял, что sda иногда — это виртуальный cd-rom и надо на каждом сервере проверять кому атрибут выставляется..., но это уже другая история.


Жизнь админа становится всё меньше похожа на жизнь админа. Профессия разделяется на тех, кто пишет конфигурацию и тех, кто её сопровождает (т.е. остаётся на фронтире, наедине с сервером). Таких иногда называют SRE, и в зависимости от критичности проекта в каждый момент времени, это может быть как очень крутая и важная профессия, так и "апгрейженный саппорт".


С чего начать?


Если я вас чуть-чуть мотивировал, но вы не знаете, с чего начать, то начните с поиска системы управления конфигурациями, которая вам по душе. Это Ansible, cfengine, Chef, Juju, Pupplet, SaltStack, Quattor, etc. Вероятнее всего, список не полон. Ни одно из этих решений не является хорошим (на мой взгляд), но это лучшее, из того, что у нас есть. Выбор такой системы частично нужно основывать на известных языках программирования (это моё IMHO), ощущении от синтаксиса и жизнеспособности проекта.


После выбора ПО, не стоит бросаться с головой. Читать умные книги по такой системе надо, играться тоже можно до любого уровня сложности, но внедрять стоит очень ограниченно, не теряя контроля над ситуацией. Это означает, что начинать надо с простой автоматизации длительных действий (перепишите свой любимый скрипт деплоя на языке системы управления конфигурацией), попробуйте в него записать хотя бы часть того, что делаете руками.


postscriptum


Одним из интереснейших лайфхаков с системами управления конфигурациями, я считаю лабораторное применение. Когда исследуется новое ПО, то конфигурация этого ПО силами системы управления конфигурациями позволяет "попробовать снова" (если не ясно, делает ли ПО сайд-эффекты по серверу).


Заодно, описание для робота "что делать" отлично подходит на роль эскизного проекта внедрения. Одно время я отлаживал corosync, который не хотел работать в сети с лимитом на unknown unicast/multicast. В ходе отладки мне пришлось несколько десятков раз переподнимать кластер. Когда это делалось ansible'ом, "несколько десятков раз" не стали подвигом, а пришли к чему-то уровня "перезапустить лабораторию".


Ежедневное применение систем управления конфигурациями требует перестройки самых базовых инстинктов работы с серверами, но взамен очень неприятной learning curve даёт на руки не только инструмент для повышения эффективности труда, но и смену модели поведения и мышления на более эффективную. Это очень тяжёлый шаг, но шаг, который нужно обязательно сделать.

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


  1. utoplenick
    22.03.2018 17:21

    Спасибо, прочитал с удовольствием, сам использую puppet+hiera+mcollective


    1. amarao Автор
      22.03.2018 17:23

      hiera — это костыли для puppet'а, а mcollective — я не до конца понимаю его роль в этом мире.

      Сам я из лагеря ansible'истов, но с опытом chef'а.


      1. utoplenick
        22.03.2018 17:44

        Ну почему костыли) Просто способ отделить данные от логики, mcollective держу в основном для случая когда нужно форсануть применение конфигурации «здесь и сейчас»


        1. amarao Автор
          22.03.2018 18:08

          У меня нет достаточной квалификации во всех системах управления конфигурациями, но всё, что я слышал, говорит о следующем: ни одна из них не готова к крупной инфраструктуре. У всех них — детские болезни роста, благоглупости и очень неудобно.

          Я ни с паппетом ни с hiera не работал, но первый же пост на хабре (https://habrahabr.ru/post/242657/) явно говорит, что «Паппет изначально, видимо, не задумывался, как решение для больших инфраструктур, по крайней мере иерархия в него изначально заложена из рук вон плохо.». Вот такое же у меня мнение и про ансибл (причём не только и не столько в контексте количества серверов, сколько в вопросе работы с сложными структурами данных и отношениями).


  1. poxvuibr
    22.03.2018 17:58

    Это при том, что нормальный админ уже давно бы сделал hdparm -W 0 /dev/sda на 400 серверах в цикле. Возможно, к 300 серверу он бы понял, что sda иногда — это виртуальный cd-rom и надо на каждом сервере проверять кому атрибут выставляется..., но это уже другая история.

    При параллельном раскатывании конфигурации на 400 машинах было бы так же, только более эффективно? Или использование какого-нибудь ansible как-то от такого страхует? Или может быть помогает исправлять проблемы?


    1. amarao Автор
      22.03.2018 18:13

      У ансибла есть разного рода защиты от такого. Начиная с serial (количество параллельных выполнений) и заканчивая управляемым лимитом на количество отказов за раз.

      Но в статье я намекал на другое — … да, да, мы знаем, что сейчас наша конфигурация неправильно настраивает опции кеширования для дисков, но для внесения изменений нам надо сначала переписать кусок, отвечающий за классификацию блочнных устройств.

      Если задача решается обстоятельно, то проблемы «на некоторых дисках он sda, а на некоторых sdb» просто не будет. Хотя сами задачи будут выполняться медленее, качество их выполнения будет значительно выше.

      Пример с hdparm был примером ошибочного применения наколенной автоматизации в крупном масштабе. Диагностики нет, обработки ошибок нет, проверки на условия нет, есть только success path.

      Грамотный подход к задаче позволяет иметь такой рабочий процесс, в котором для выполнения такого рода задачи придётся (в силу специфики процесса) объяснить где что и по какому случаю делать. Объяснить машине и человеку (который читает код). В ходе объяснения будут всякие неловкие вопросы «а точно sda?» и т.д.


  1. datacompboy
    22.03.2018 20:25

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

    нормальная система должна позволять простые вещи делать просто. а сложные — делать управляемо сложно.
    то есть сложность должна быть типа sqrt(N) (а то и log(N)).
    а все эти системы переходят от A+N (где A = базовые знания про сервер, вопрос секунд, а N = число серверов) на Q + N/50 (где Q на несколько порядков больше чем A).
    то есть сложность остаётся зачастую близкой к линейной, причем коэффициент огромный, так что делитель позволяет выигрывать только когда компов становится действительно много.
    ну это паппет. ансибль чуть лучше, у него саблинейный уже коэффициент у N, но всё равно, сцуко, Q зашкаливает…


    1. foxmuldercp
      22.03.2018 20:52

      Я пока не понял идеологию шефа/паппате с клиентами на сервере-клиенте, мне близка идеология Ansible и по сути. вся конфигурация сервера — прописать мак на DHCP, и прописать его в конфиг ансибла, дальше я буду иметь сервер почты, днс или чего-я-там-захочу.
      Но как и у всех решений — есть их путь, и костылизм. у меня была конфигурация фаервола, где половина плейбука raw команды, потому как штатный модуль 90% задач поставленных нок инженером выполнить не мог, потому как сильно базовый


      1. amarao Автор
        22.03.2018 21:37

        Да, по поводу raw-команд. В большинстве случаев это повод написать модуль. Они там пишутся в пол-пинка, и позволяют решать много проблем в удобном контексте (в котором можно и тесты прифигачить).

        Если много shell или raw, и код планируется совпровождать долго, то писать модули — это лучше, чем shelll-нинзя-стайл.


    1. amarao Автор
      22.03.2018 21:30

      Да, вы абсолютно правы. Все существующие системы управления конфигурациями сосут по-крупному. К сожалению, это лучшее, что у нас есть, и оно лучше, чем самописное на шелле (и его аналогах) или «то же самое, руками».

      Меня, например, жутко бесит, что ансибл считает «not a programming language», что мешает (крупно мешает!) использовать паттерны нормальной разработки. В этом смысле я бы больше поддерживал chef, если бы не одно «но» — их ужасная, душераздирающая инженерная практика с вендорингом всего и вся. (chef-bundle идёт с тремя запакетированными версиями beam.smp).


      1. csdoc
        22.03.2018 23:22

        После аналогичных размышлений я сделал свою систему управления конфигурациями на Python. По принципу работы она похожа на Ansible, только вместо языка программирования, построенного на базе YAML синтаксиса используется обычный Python: Fabrix

        Это надстройка над системой автоматизации деплоймента Fabric

        Список реализованных в Fabrix функций: Reference

        Пример использования: contrib

        В каталоге create-server-partitions — скрипт на чистом Fabric для создания разделов на жестких дисках, в каталоге infrastructure-as-code — настройка сервера виртуализации KVM + ZFS и виртуальных машин.


        1. vaniacer
          23.03.2018 15:24

          Тоже пошел по этому пути) Написал свое web приложение github.com/vaniacer/up позволяющее выполнять какие-либо скрипты на кучке серверов по ssh.


  1. foxmuldercp
    22.03.2018 20:48

    Вообще да, понимаешь что с возрастом приходит лень и автоматизация и количество администрирования практически сходит на нет, и не важно — один сервер или сотни.
    Вообще те же групповые политике в MS были давно и иногда мне кажется что они стали идеей для шефа, паппета и ему подобных. Еще 10 лет назад, в эпоху 6й фри у меня было пару десятков скриптов на баше, которые делали тоже, что сейчас делает ансибл.
    А я видел и конфигурации, где в процессе обработки логов CI/CD еще и динамически меняли конфигурации тестовых площадок и продакшена.


    1. amarao Автор
      22.03.2018 21:32

      Групповые политики имели смысл в том месте, где вычислялась итоговая полиси. Интересный и дерзкий подход. Однако, он не сильно очевиден (удачи в отладке сложной групповой политики), и жёстко завязан на то, что весь софт его уважает. То есть тривиального «сделать файл» там не получится, не говоря уже про нетривиальное «создать базу с пользователями», или уж совсем космическое «выполнить rolling update».


  1. ludenus
    22.03.2018 20:59

    Ansible, cfengine, Chef, Juju, Pupplet, SaltStack, Quattor… Ни одно из этих решений не является хорошим

    Подробностей бы — где какие грабли лежат? Особенно любопытно Ansible vs Salt.


    1. amarao Автор
      22.03.2018 21:35

      Я не эксперт в salt, про боль в ансибле надо писать много. Ключевое — он не задуман как язык программирования. Глобальные переменные, неясный scope для хэндлеров (например, комбинация include_role и import_role оставляет очень сложное впечатление), невозможность использовать переменную в левой и правой части выражения одновременно, невозможность без выкрутас «добавить значение в словарь/список», путаница с делегацией фактов при делегации задачи из роли, etc.

      Плюсы ансибла — низкий порог вхождения, нулевой футпринт на целевой ноде, совместимость с сетевым оборудованием (можно пойти и сконфигурировать), интересные трюки с делегацией, питон (это субъективное, ибо chef/puppet — это ruby).


    1. kt97679
      22.03.2018 21:36

      На всякий случай вот мои впечатления от солта: habrahabr.ru/post/315012/#comment_9905944


      1. amarao Автор
        22.03.2018 21:38

        Спасибо. То есть у них хуже, чем у ansible.


        1. kt97679
          22.03.2018 22:39

          Пожалуйста делайте поправку на то, что мой комментарий 2-х летней давности. Мы как заморозили версию так и используем ее. Возможно в последующих версиях что-то улучшилось, но как минимум мои просьбы исправить race conditions так и остались не адресованными.


          1. sevikl
            23.03.2018 11:40

            и даже при всём этом salt всё еще лучше чем puppet. когда я несколько раз поймал повисание агента puppet на применении конфига с диким отжором cpu, без всякого сожаления снес это поделие вместе с руби-помойкой и тысячей зависимостей и переполз на salt, благо задач не так много и получилось довольно безболезненно.


            1. utoplenick
              23.03.2018 12:47

              За 6 лет использования ни разу ле ловил ничего подобного, да и зависимостей явно меньше тысячи)


            1. kt97679
              23.03.2018 18:32

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

              К сожалению практически все configuration management systems сегодня требуют достаточно тяжелых зависимостей на клиенте. Для меня идеальная cms должна обходиться стандартными binutils на клиенте и работать через ssh, т.е. никаких дополнительных демонов. Из известных мне решений этим условиям удовлетворяет capistrano и cdist. Я посмотрел примеры конфигураций для cdist и как-то не впечатлитлся. Capistrano выгдлядит более привлекательно, но пока что не было шансов попробовать.


              1. amarao Автор
                23.03.2018 18:57

                Ну, собственно, ansible требует python на хосте, но может сам поставить даже и питон (вот кусок моего кода для бутстрапа контейнера):


                - raw: test -x /usr/bin/python || apt-get update && apt-get -y install python

                Он в буквальном смысле получает систему (в которой даже ssh нет) и выдаёт мне на выход рабочую машину ("рабочая" часть идёт ниже, после bootstrap'а).


                1. kt97679
                  23.03.2018 20:37
                  +1

                  Я считаю, что питон на клиенте для configuration management не нужен. Все можно сделать штатными командами из binutils. Кроме того без завязки на питон мы можем конфигурировать оборудование, где крутится embedded OS с минимумом возможностей.

                  Про нет ssh не понял. ansible ведь работает через ssh, или я что-то упускаю?


                  1. amarao Автор
                    23.03.2018 21:18

                    Ансибл работает через кучу транспортов, и ssh — только один из них. Если есть возможность запускать код или команды (хоть как-то), то можно иметь к этому connection. Так, например, работает конфигурация сетевого оборудования.

                    Насчёт «без питона» — многие вещи на generic OS делаются лучше с питоном. На shell'е очень тяжело работать с структурами данных — простейшая хеш-таблица (словарь) — и уже проблемы. Распарсить json — целое приключение и т.д.


                    1. kt97679
                      23.03.2018 21:51

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

                      Мне кажется, что в процессе конфигурирования клиента не надо парсить json и выполнять другой сложный код. Это вполне можно сделать на управляющем сервере. В моем представлении идеальная scm должна сделать ровно 2 ssh запроса в процессе конфигурирования клиента. Сперва собрать необходимые данные о клиенте, потом обработать их на управляющем сервере, собрать скрипт для конфигурирования клиента и 2-м ssh запросом выполнить этот скрипт.


                      1. amarao Автор
                        24.03.2018 01:00

                        Это не совсем возможно. Часть модулей требует использования API, которые лучше использовать в виде API, а не CLI. Пример — libvirt. Да, можно дёргать virsh, а потом парсить вывод, но это глупость, потому что libvirt для того и создавался, чтобы не надо было парсить вывод.

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

                        Принимать решения надо после каждой операции, причём некоторые решения могут требовать результата с нескольких серверов (т.е. решение нельзя делегировать). Использование bash'а выглядит большим аттавизмом, потому что в bash'е очень плохая типизация, а многие API подразумевают типизацию данных. Интерфейсы с СУБД, corosync, openstack и т.д. — все они лучше в виде языка программирования, а не шеллового пайплайна.


                        1. kt97679
                          24.03.2018 20:24

                          Если эти API доступны по сети взаимодействовать с ними опять же может управляющий сервер. Если они доступны по сети только с локального хоста или через локальный unix socket можно решить проблему через проброс портов. Если логика конфигурации может меняться по ходу выполнения сценария можно выполнять команды по очереди и отслеживать на управляющем сервере результат. Возможно я упускаю какие-то детали и есть что-то, что с использованием выше перечисленных подходов сделать нельзя. Тем не менее думаю, что питон на клиенте как минимум можно сделать опциональным, а не обязательным. Потому как для простейших случаев, когда надо установить пакеты, изменить конфигурационные файлы и перезапустить сервисы питон не нужен. Все ИМХО :).


                          1. amarao Автор
                            24.03.2018 23:18

                            Вы не понимаете проблемы. У вас плейбука, которая выглядит так:

                            1) сделать_сложно
                            2) если в сделать_сложно есть «мастер», сделать действие2 на хосте «другой».
                            3) перезапустить сервис, если в сделать_сложно были изменения

                            При этом «перезапустить сервис» может выполняться не более чем на 8 серверах из 17 одновременно.

                            Для выполнения второго этапа нам нужно взаимодействие с мастер-нодой (сервером). Так что «просто прислать большой баш» не катит, нужно взаимодействие между центральным сервером и конфигурируемыми серверами много раз. Более того, ответ на шаге 1 влияет на шаг 2, так что он нам нужен в структурированном виде. Код возврата, stdin, stdout, статус changed или failed (код возврата и failed это не одно и то же, т.к. мы можем иметь ненулевой код возврата и всё равно success), возможно, нам нужна ещё какая-то информация (условно, модуль stat для файла, который позволяет делать условия stat.exists, stat.isdirectory и т.д.).

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


                            1. kt97679
                              24.03.2018 23:57

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


                              1. amarao Автор
                                25.03.2018 10:00

                                А теперь осталось понять, почему для этого надо использовать баш вместо более развитого языка программирования. Сам баш ничего не умеет — там нет сетевого ввода-вывода, файловые операции мягко говоря, странные. Использование же всяких coreutils делает процесс во-первых «не на баше», а во-вторых приводит к огромному числу форков, за которыми надо следить. Можно не следить — но тогда это success-only programming, с «ошибки — это не наша проблема» подходом.


                                1. kt97679
                                  25.03.2018 18:48

                                  Так я же написал, давайте сделаем питон опциональным. Для простейших сценариев типа установить пакет/изменить конфиг/перезапустить сервис он не нужен. К слову, можно вас попросить развернуть пример, который вы привели выше в кратком виде? Там где сделать_сложно итд?


  1. g0dlike
    22.03.2018 22:03
    +1

    Спасибо за статью, но мир немножко изменился.
    Сейчас пайплайн выглядит приблизительно так:
    1) Генерим конфиги, обвязку, устанавливаем пакеты и т.д. скажем на том же сервере CI (можно даже без SCM, внезапно) в виде слоя контейнера.
    2) Запускаем получившийся контейнер где-нибуть.
    Решились проблемы:
    1) Staging — внезапно, это те же контейнеры и те же серверы, просто используется другой датасет(даже прод в рид онли можно)
    2) Рефакторинг — мы вообще ничего не меняем на собственно серверах — нечего рефакторить. Рефакторинг же контейнера очень прост.
    3) Code Review — отревьють несчастный конфиг контейнера куда проще, чем тыщу взаимосвязанных *буков.
    4) Большой инфраструктуры — нам больше не нужно настратвать 100500 серверов, нам теперь нужно просто на них передать 1 мегабайт контейнерного слоя — что, согласитесь, несколько другого уровня задача.
    5) Неодинаковости серверов. Нам в общем случае плевать, где запускать контейнер, был бы процессор, память, диск(не обязательно), сеть.
    Ну и так далее.
    Конечно же, взамен появились другие проблемы, которые, тем не менее, легко автоматизируются и не требуют участие человека — «где же, черт побери, запустился этот контейнер?», «куда же записались данные?», «Как тебя попроще мониторить?»


    1. powerman
      22.03.2018 22:23

      Для своих сервисов — да. Ансибл ещё полезен, но уже не так критичен, когда всё в контейнерах. Особенно когда задача "раскатать сервис на N серверов" решается встроенными средствами docker swarm, ECS и т.п.


      Но сервера и инфраструктура не состоят из одних кастомных сервисов, ещё нужно настраивать как сами сервера (сетевые интерфейсы, файрвол, тюнить ядро, обновлять ОС, etc.) так и стандартные сервисы, которые в теории тоже можно запихать в контейнеры, но на практике они ещё обычно не там (dns, dhcp, smtp, cron, ssh, openvpn, мониторинг самого сервера, etc.).


      1. g0dlike
        22.03.2018 22:36

        Ну почему же.
        В облаках все настраивается абсолютно похожим образом — www.packer.io
        Если же вы переросли облака и доросли до своего железа, придется настроить что-то вроде www.ubuntu.com/server/maas


        1. selivanov_pavel
          23.03.2018 04:49
          +2

          Как этот maas избавит от необходимости, например, настраивать bcache для работы связки "несколько SSD + большая полка с дисками", или настраивать параметры ядра на балансере, потому что сколько haproxy/nginx в контейнер не запаковывай, без настроек ядра максимальной производительности из них не выжмешь? Контейнеры это ещё не всё


  1. periskop
    23.03.2018 10:58

    Хорошая статья, спасибо!


    А кто что может сказать насчет Rundeck-а? Может ли он быть заменой (именно заменой) Ansible?


    1. amarao Автор
      23.03.2018 13:28

      Выглядит как open core, а open core — очень плохая модель разработки (с точки зрения применимости).

      У меня есть большой пунктик насчёт несвободных инструментов, так что я бы сказал, что «очень плохо». Возможно, кто-то опишет его лучше, но в условиях достаточного ассортимента opensource, я бы не стал смотреть на продукты с закрытой моделью.


  1. ExH
    23.03.2018 11:07

    Спасибо за статью, а вот ещё про «не готовность к большим инфраструктурам».
    Сейчас вообще нет способа настроить биос автоматически.
    Поэтому надо или заказывать себе особые биосы у производителя или настраивать руками все 100500 серверов.


    1. amarao Автор
      23.03.2018 13:30

      Есть. Dell, idrac, у которого есть API и CLI. Одна из суперфич servers.com состоит в том, что у нас полностью управление биосами серверов автоматизировано. У нас даже есть специальные роботы, которые в бэкграудне серверам биосы обновляют. И у каждого выдаваемого сервера (роботами!) настройки биоса выставлены в оптимальные.

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


      1. ExH
        23.03.2018 13:37

        Интересно.
        Жаль что в наших супермикрах такого нет.
        А как определяется «оптимальность» настроек?
        Может есть какой-то общедоступный мануал?


        1. amarao Автор
          23.03.2018 13:41

          Супермикры вообще дешевле на вход, но дороже по TCO. Про этот вопрос наше начальство недавно интервью давало, если интересно — overcast.fm/+EA6-Hp1xM (2 часа!).

          Оптимальность настроек на самом деле сводится к
          а) отсутствию ерунды (типа отключения устройств, процессоров и т.д.)
          б) выключению режима максимального энергосбережения
          в) сбросу странных настроек drac'а
          г) тому режиму загрузки, который мы предоставляем.


  1. baxxter
    23.03.2018 13:16
    +1

    Что такое staging и рефакторинг? Фронтир, бэк-офис? Я как админ среднего пошиба (в подчинении около 80 серверов) не знаком с данными терминами и не понял совершенно о чём речь. Если целью статьи является мотивация к изучению систем конфигураций и объяснение для чего они нужны, то вы не мотивировали и не научили ничему меня. Ощущение что написано для тех кто уже в теме или созрел. Можете привести какие то конкретные примеры чем мне, как администратору, данные системы помогут в работе и какие процессы помогут автоматизировать?


    1. amarao Автор
      23.03.2018 13:23
      +1

      Спасибо за замечание. Я надеюсь, про то, что такое «staging» в статье объяснено:

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


      Насчёт рефакторинга. Рефакторинг — это переписывание куска существующего (обычно, кода, но оно так же применимо и к конфигурации), таким образом, чтобы оно делало то же самое, но в более понятном и ясном виде для читающего. Обычно под это так же подгоняют всякие улучшения архитектуры и т.д. В контексте управления конфигурациями минимальный рефакторинг может состоять, например, из замены переменных external_api_ip, listen_ip, api_ip (в мониторинге) на одну переменную. Маленький шаг, делающий последующую жизнь легче.

      Насчёт бэк-офис — это «офис», подальше от серверной. К вершинам devops отношения не имеет, и является аналогией обычного бизнес-деления — фронт-офис — это ресепшен и менеджеры, разговаривающие с клиентами, бэк-офис — бухгалтерия, старший менеджмент, люди, которые не говорят с клиентами (обычно). В контексте IT — подальше от серверов и поближе к офисной жизни.

      Привести примеры автоматизации очень сложно, потому что если я приведу свои примеры, то они для вас ничего не скажут (какое вам дело до того, как у меня bgp-пиры переконфигурируются?), а привести примеры, актуальные для вас — это во-первых сложно, а во-вторых это уже чистой воды консалтинг.

      Но, всё же попробую.

      Сейчас я работаю над playbook'ой ансибла, которая будет брать бэкап, поднимать в контейнерах микрокопию продакшена и прогонять тесты (написанные вместе с программистами), которые говорят «похожи ли эти данные на продакшен». Эта плейбука будет автоматически запускаться раз в сутки и проверять, что:

      а) бэкап есть
      б) бэкап можно загрузить в базу
      в) данные в бэкапе являются ожидаемыми данными (а не чем попало)
      г) У нас есть работающая процедура восстановления СУБД в случае аварии (я меняю две переменные и вместо контейнеров оно поднимается на новых железных серверах).

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


      1. vaniacer
        23.03.2018 15:21

        Простой bash сценарий github.com/vaniacer/DDT делает все это без ансамбляansible.
        Качает дампы, для проверки разворачивает на тестовый сервер при необходимости можно добавить проверку каких-либо таблиц и отправляет результат письмом. Я использую mutt(исторически так сложилось) т.к. он умеет аттач) соотв. он должен быть установлен и настроен, но можно прикрутить любой другой почтовик.


        1. amarao Автор
          23.03.2018 15:29

          О, вот тут всё и становится интересно. А у вас тестовый сервер — это копия продакшена? Может оказаться, что из-за неправильной локали на тестовом сервер всё пройдёт, а в продакшене — сломается. Или у вас будут слегка разные версии pg_dump/pg_restore.

          Весь же вопрос в воспроизводимости. Вот на ваш тестовый сервер базу накатали 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; }

          И всё хорошо. Только вместо бэкапа пробел.


          1. vaniacer
            23.03.2018 15:55

            Это общий вариант, можно добавить необходимое кол-во select'oв для проверки.
            Размер файла пишется в лог, дамп с пробелом будет подозрительно мал)


            1. amarao Автор
              23.03.2018 16:07
              +1

              И в этом месте мы можем застрять на миллионе «можно поправить». Конечно, можно.

              Я просто показываю насколько хрупкими и неустойчивыми чаще всего оказываются скрипты на баше. Обработка ошибок на баше — это невероятно сложно, и редко кто-то такое делает. Вместо этого, все полагаются на дефолты. Что хорошо для однострочника «тут и сейчас», но совсем не годится в качестве основы для устойчивого продакшена.


              1. vaniacer
                23.03.2018 16:10

                Вы сами пишете что с мямлом тоже не все хорошо, меняем шило на мыло, нет?)


                1. amarao Автор
                  23.03.2018 16:12

                  Разница как между прохудившимся ботинком от долгой дороги, и неудобным сидением для поездки в автомобиле. Вроде бы тоже неудобства, но на другом масштабе.


      1. navion
        23.03.2018 19:54

        Сейчас я работаю над playbook'ой ансибла, которая будет брать бэкап, поднимать в контейнерах микрокопию продакшена и прогонять тесты (написанные вместе с программистами), которые говорят «похожи ли эти данные на продакшен».

        Зачем писать это руками, когда есть виртуальные лаборатории в самом софте для бекапа?


        1. amarao Автор
          23.03.2018 20:26

          Потому что нет софта, способного сбэкапить проект. Он очень кастомный и процесс бэкапа требует только конкретных таблиц, более того, миграции базы данных выполняются flyway'ем, и схему СУБД при этом бэкапить не надо.


  1. vaniacer
    23.03.2018 15:39

    Но вместе с этим будет и ещё одно ощущение — что стало меньше кнопкодавства и стало больше думания. Вместо «пойти и поменять» будет момент размышления «а правильно ли менять так?», «А почему его вообще надо менять?», будет больше рассуждений об архитектуре (почему на сервере А мы меняем одно значение а на сервере Б другое? Можем ли мы найти что-то общее между этими изменениями и описать это общее как новую сущность?)


    Я и без ансамбляansible, сам стараюсь делать именно так. Автоматизирую рутинные задачи с помощью доступных ЯП bash\python. Может дело не в технологиях?)


    1. amarao Автор
      23.03.2018 15:53
      +1

      Безусловно, можно и без специализированного инструмента. Вы берёте и пишите программу. Как только вы написали программу (для компании), у вашей компании стало чуть больше головной боли. Почему? Потому что любую программу нужно поддерживать.

      Вот, например, какое у вас покрытие кода для написанных вами программ? А как у вас с интеграционным тестированием этих программ?… Но это же сложно, мы же сисадмины, а не программисты какие-то, правда?

      Только главное свойство скрипта состоит в том, что он оперирует понятиями нижелещащего (своего) уровня. Это означает, что на скриптах нельзя строить абстракции, обобщения или иные средства снятия головной боли с человеков. Хорошая программа даёт возможность оперировать понятиями более высокого уровня, абстрагироваться от мелких нюансов реализации.

      ansible — при всех его минусах — программа (так же как и любая другая система управления конфигурациями). Потому что она смещает фокус с низкоуровневых деталей вроде «включать ли pipefail для моего башового однострочника?» в область высокоуровневых — я опрерирую вопросами «воспроизводимости инсталляции», «идемпотентности плейбуки». Ближайший вопрос, который меня интересует — не интеграция stdout'а с pgdump'а, а такая структура database-recovery.yaml, которая позволит её одинаково применять её и для железных серверов и внутри слейва jenkins'а внутри контейнера.

      Ключевой проблемой NIH (not invented here), или русский аналог «сами напишем» состоит в том, что вы напишите хуже, чем люди, пишущие продукт. Не потому что вы лично хуже программист, чем они, а потому что у вас бюджет времени на написание «движка автоматизации» явно меньше, чем несколько лет. И их «движок» пишет много людей, и ещё больше людей тестирует. Как до релиза, так и после (багфиксы).

      Вторая проблема: вот вы будете передавать компетенцию следующему человеку. Потому что у вас повышение, или вы нашли себе другую работу. Приходит человек, и ему выдают, например, 14000 строк на баше. С сопроводительной документацией, да? Компетенцию человек будет получать очень долго, а главное, очень узкоспециализировано, потому что нигде, кроме вашего проекта, она ему не пригодится.

      Ансибл (или любая другая система) даёт универсальный инструмент, для которого можно ожидать квалификации у новопришедших, для которого есть документация, книги, видео для обучения.

      Если это не убеждает, то давайте я задам вам другой вопрос: вот у вас есть bash. На нём можно сделать всё. Зачем python?

      Вот ответите на этот вопрос — ответите и на вопрос, зачем системы управления конфигурациями вместо скриптов.


      1. vaniacer
        23.03.2018 16:06
        +1

        Вы печатаете с чудовищной скоростью, зачем вам ансамбльansible?)


        1. amarao Автор
          23.03.2018 16:08

          Чтобы не заниматься низкоквалифицрованной работой. (Админ, который на сервере вручную меняет тривиальные настройки — низкоквалифицированный персонал, увы).


          1. vaniacer
            23.03.2018 16:14

            Убедили, попробую)