Разработка и тестирование chef кукбуков с помощью инструмента Sparrowdo v2

    Здравствуйте! Об инструменте sparrowdo и его применение в разработке сценариев конфигурации chef я писал уже ранее.


    Что ж, за это время утекло много воды и я хотел снова немного раскрыть данную тему, собственно поэтому заголовок статьи содержит версию два.


    Итак — sparrowdo — система управления конфигурациями написанная на замечательном языке Perl6, активно развивающимся в последнее время. В своей лично работе я нахожу sparrowdo очень удобным и органично сосуществующим с более мощной платформой управления конфигурация — opscode chef. На нескольких конкретных примерах я покажу как я использую chef вместе со sparrowdo. Это пост не будет очень длинным, но надеюсь даст понимание о чем идет речь.


    Что мы имеем? В силу своей основной профессиональной деятельности мне приходится много писать всяческих chef кукбуков. В нашем проекте активно используется aws сервисы, поэтому создание сервера и установка на нем chef клиента — операция достаточно дешевая и нересурсоемкая, следовательно я могу запросто отлаживать chef рецепты, запуская chef клиента на удаленном сервере по ssh, вместо того что бы использовать более традиционный для таких случаев vagrant


    Хорошо, таким образом процесс разработки и отладки кукбуков сводится к тому, что разрабатывая очередную версию рецептов, я обновляю кукбук на chef сервере посредством команды knife upload и запускаю тестируемый кукбук далее на удаленном сервере посредством команды chef-client ( с заданным ран листом ). Собственно, вылавливая при этом различные ошибки и падения возникающие при деплое ( если выражаться языком документации chef — конвергенции ноды )


    При таком раскладе мне очень удобен sparrowdo — который в отличие от chef является push based инструментом управления конфигурациями или, попросту говоря, умеет выполнять свои сценарии на удаленном хосте по ssh.


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


    Sparrowdo поддерживает модульность — вы можете расширять его базовую функциональность за счет модулей написанных на языке Perl6, поэтому специально для это задачи мною был написан модуль под названием Sparrowdo::Chef::Client


    Интерфейс модуля достаточно прост — он предоставляет необходимый минимум для запуска chef клиента — а именно указание ран листа и опционально задание атрибутов


    Вот как будет выглядеть сценарий по запуску кукбука java с установкой атрибута, задающем версию устанавливаемого jdk:


    $ cat sparrowfile
    
    module_run 'Chef::Client', %(
        run-list => [
          "recipe[java]"
        ],
         attributes => %(
          java => %(  
            jdk_version => 7 
          ),
        ),
        log-level => 'info',
        force-formatter => True
    );

    В наших проектах мы используем во основном jdk версии 7, поэтому я выставляю ее через соответствующий chef атрибут, который переопределяет дефолтное значение.


    Вот как будет выглядеть отчет sparrowdo при запуске на удаленном сервере:


    $ sparrowdo --host=remote.server  --ssh_user=centos --ssh_private_key=/home/melezhik/.ssh/foo.pem
    
    running sparrow tasks on remote.server ... 
    target OS is - centos7
    enter module <Chef::Client> ... 
    push task <set up chef run list and attributes> plg <file> OK
    push task <run chef-client> plg <bash> OK
    set up task box file - /tmp/sparrowdo/task-box8938.json - OK
    get index updates from SparrowHub ... OK
    public@file is uptodate (0.0.5)
    public@bash is uptodate (0.1.4)
    running task box from /tmp/sparrow-cache/task-box8938.json ... 
    [t] set up chef run list and attributes at 2017-04-06 13:35:14
    
    set target content
    touch target
    target created
    set target mode to 644
    ok  scenario succeeded
    ok  text match /target (created|deleted)/
    ok  text has 'set target content'
    STATUS  SUCCEED
    [t] run chef-client
    @ runs bash command
    [t] run chef-client modules/bash-command/ params: envvars: at 2017-04-06 13:35:14
    
    [2017-04-06T13:35:15+00:00] INFO: Forking chef instance to converge...
    Starting Chef Client, version 12.19.36
    
    #
    # вывод опущен 
    #
    
    Chef Client finished, 7/9 resources updated in 38 seconds
    ok  scenario succeeded
    STATUS  SUCCEED

    Хорошо, это простой пример показывает как мы можем управлять настройками запускаемых сhef кукбуков, выставляя ран лист и различные атрибуты. Приведу далее еще несколько интересных случаев.


    тестирование прохождения граничных условий


    Не секрет, что большо'е количество задач по управлению конфигрурациями и автоматизации связано с запуском сетевых сервисов. Например у нас есть кукбук, который настраивает и и перезапускает сервер nginx согласно какому-то нетривиальному набору правил. Я думаю, те кто писал подобного рода рецепты часто сталкивались с тем, что их сценарии могут вести себя по-разному относительно разных состояний сервиса в начале. Вот, например я хочу посмотреть что будет, и не упадет ли мой деплой если nginx не будет запущен до выполнения chef рецепта, с помощью sparrowdo, который сам по себе так же является инструментом управления конфигурациями это сделать легко:


    $ cat sparrowfile
    
    service-stop 'nginx'
    
    module_run 'Chef::Client', %(
        run-list => [
          "recipe[nginx-app::configure]"
        ]
    );

    Согласитесь — что встраивать остановку nginx внутрь шеф рецептов, только для того, что бы протестировать поведение нашего основного кукбука, было бы не хорошо. А здесь с помощью sparrowdo мы делаем это легко и непринужденно, причем не меняя ничего в коде самого chef кукбука


    встроенные post deployment / audit тесты


    Часто требуется проверить работу шеф клиента после того, как он отработал. Есть различные варианты решения данной задачи — test-kitchen/ serverspec, goss, chef minitest-handler, inspec у всех у них есть свои плюсы и минусы. Но вот вам еще одна альтернатива — sparrowdo — основной смысл тот же — мы делаем проверки рядом, а точнее внутри sparrowdo сценария, вот одна из моих излюбленных проверок на то, что сервер tomcat запущен и "виден" в списке процессов — практика показывает, что иногда chef не отлавливает ситуации с падением перезапускаемого сервиса и нам необходимо делать это самим:


    $ cat sparrowfile
    
    service-stop 'nginx'
    
    module_run 'Chef::Client', %(
        run-list => [
          "recipe[tomcat-app::configure]"
        ]
    );
    
    task-run  'check tomcat', 'proc-validate', %(
      pid_file => '/var/run/tomcat7.pid',
      footprint => 'java'
    );
    

    необязательные зависимости


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


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


    package-install 'java-1.7.0-openjdk-debuginfo'
    module_run 'Chef::Client', %(
        run-list => [
          "recipe[java]"
        ]
    );

    На этом я заканчиваю. В заключении хочется сказать что в моей личной работе, связанной с ежедневной разработкой десятков кукбуков для сотен различных проектов sparrowdo зарекомендовал себя как отличный инструмент-компаньон существенно ускоряющий и упрощающий разработку и тестирование сценариев chef.


    Как обычно, буду рад вопросам и конструктивной критики.

    Поделиться публикацией

    Комментарии 21

    • НЛО прилетело и опубликовало эту надпись здесь
        –1

        да, все верно, chef клиент можно запускать в таком режиме ( здесь правда уместнее говорить о команде knife ssh — но разница небольшая относительно вашего примера ).


        возможно я не очень аккуратно выразился. вот что хотелось сказать — иногда мне хочется описать какую-либо конфигурацию ввиде сценария и тут же запустить все это на целевом сервере, в случае с шефом у вас всегда есть шаг связанный тем, что сценарий должен быть добавлен в виде кукбука на шеф сервер ( если это конечно не chef-solo но я здесь его не рассматриваю ) и только заетм шеф клиент ( когда вы его запускаете по ssh) запрашивает данный кукбук с шеф сервера (pull) — это определяет определенные накладные расходы на цикл разработки и тестирования кукбуков ( грубо говоря вы все время вынуждены делать knife upload каждый раз внося изменения в кукбук, плюс добавьте время когда шеф клиент скачает новую версию кукбука при запуске и т.д. ), в случае же с ansible или sparrowdo у вас нет этого лишнего шага, вы просто копируете ( в том или ином виде ) сценарий по ssh на целевой сервер и сразу же его выполняете…


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

        • НЛО прилетело и опубликовало эту надпись здесь
            0

            Мне кажется мы начинаем уходить немного в сторону от того что я хотел сказать в статье, здесь акцент не на времени исполнения ( хотя опять таки же накладные расходы в случае с использованием chef как клиент сервер есть ) или там на сравнении pull с push архитекурой. А на том, что можно использовать шеф вместе со Sparrowdo, при отладке сценариев управления конфигурациями.


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

            • НЛО прилетело и опубликовало эту надпись здесь
                0

                Смотрите, в случае когда вы запускаете шеф как клиент серверное приложение что де факто основной способ использования шеф возникают те самые накладные расходы с тем что вы все время вынуждены "прокидывать" изменения в коде через шеф сервер ввиде кукбуков. Если сравнивать шеф сервер по этому параметру с тем же ansible или Sparrowdo, то последние imho выигрывают по причине отсутствия лишнего звена в цепочки ввиде шеф сервера.


                Но давайте я скажу ещё раз — акцент этой статьи не на этом. Возможно я не очень аккуратно применил термин push based в данной статье, что увело нас в сторону.


                Шеф даже в случае с использованием его в режиме клиент сервер тоже хорош, но есть вещи которые удобнее, лучше и правильнее делать не через шеф.


                Примеры? Мне кажется я как раз их и привёл достаточно. Ещё раз — тестирование системы после отработавшего шеф клиента, установка или настройка чего-либо что нужно по каким-то причинам прямо здесь и сейчас, но совершенно не требуется для успешной работы самих шеф кукбуков и самое главное не является целевой конфигурацией. А так же дополнительная настройка системы с целью воспроизведения граничных условий или багов. Как отработает мой шеф рецепт — если в системе уже будет установлен пакет такой-то версии или если не будет существовать такой-то пользователь? И так далее и тому подобное. Так вот — приведение трестируемого окружения к требуемому состоянию лучше из шефа выносить, так же как и сами тесты.
                .


                Пример с остановкой сервиса nginx перед запуском шеф кукбуков очень показателен, вам необходим выполнить остановку сервиса только ради тестирования кукбука? нет совершенно никакого смысла делать это через какой-то вспомогательный кукбуков или что ещё хуже вносить это в тестируемый кукбук. Гораздо проще это сделать "прямо и по месту" через Sparrowdo как я показал это в статье. Ведь по сути данная операция ( остановка сервиса ) вам нужна только на момент тестирования кукбука и все. Нет смысла вносить ее в шеф.


                Здесь как раз хочется показать что использование только одного инструмента не всегда является best practice

                • НЛО прилетело и опубликовало эту надпись здесь
                  0

                  Мы можем даже убрать из статьи строчку про "который в отличие от chef является push based инструментом ..." и от этого ее суть не изменится. Предалагаю вам это сделать мысленно )) и перечитать…

                  • НЛО прилетело и опубликовало эту надпись здесь
          0

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


          Как раз таки разделение сценариев на Sparrowdo / chef позволяет разделять логически разный код на уровне разных инструментов.


          Примеров я вам привёл уже достаточно, я если честно не вижу смысл ещё в какой-то более подробной детализации.

          • НЛО прилетело и опубликовало эту надпись здесь
            0

            Да и кстати написание wrapper кукбука это как раз imho костыль, который можно избежать с помощью Sparrowdo.


            Во-первых вы создаете некоторую сущность которая вам нужна только для тестирования и заметьте загружаете ее в шеф сервер, как только вы закончите тестирование вам как придётся этот кукбук оттуда удалить, потому что он перестанет быть нужным. И заметьте у вас всегда будет как минимум один а то и несколько таких вспомогательных кукбуков или рецептов на каждый из тестируемых. Фактически вы плодите тем самым в шефе новые сущности, за которыми потом ещё надо следить и о которых очень легко потом забыть. В случае со sparrowdo — это просто один или несколько файлов положенных в SCM вместе с кодом кукбука и все. Шеф ничего о них не знает и вы никак не "загрязняете" его пространство кодом вспомогательных рецептов. Это кстати примерно то как работает тот же test- kitchen/serverspec например.


            Во-вторых сам шеф плохо подходит для тестирования инфраструктуры, все более или менее популярные решения для этого как раз вынесены за рамки шеф рецептов ( кроме пожалуй chef minitest handler, который как написано на странице проекта — in low maintainance mode ) — можете сами посмотреть если интресно — serverspec, inspec, goss и так далее — ссылки я приводил в статье )

            • НЛО прилетело и опубликовало эту надпись здесь
              0
              Хотелось бы все же знать о величине этих накладных расходов

              Вы почему-то все продолжаетесь цепляться за уже проговоренную нами тему ))) целью этой статьи было показать как разные виды задач относящиеся к разработке и отладке и тестированию рецептов шеф удобно решать с помощью разных инструментов, а не выбор инструмента которорй будет работать быстрее. И таки да, то что soarrowdo в своём цикле работы не требует промежуточного сервера я считаю плюсом по отношению к шефу запускаемым в режиме клиент-сервер. Но попытайтесь услышать меня ещё раз — это НЕ ТО почему я использую шеф в связке со Sparrowdo ( ну или наоборот, как вам угодно ) причины скорее идеологические ( разные виды задач и исходя из этого изоляция кода на уровне разных инструментов ) чем технические. Просто к слову пришлось я и сказал что вот дескать в soarrowdo такая архитектура запуска а у шеф такая-то, но в данном случае их не это главное, а главное то, что вы решаете разные задачи разными ( более подходящими ) инструментами и это хорошо. Надеюсь это поможет.

              • НЛО прилетело и опубликовало эту надпись здесь
                  0

                  Давайте так, я дискуссию продолжать смысла не вижу, мне кажется, я уже достаточно обосновал свою позицию. Предлагаю обсуждение закрыть, не потому что мне нечего сказать на все ваши ремарки, а просто я чувствую ( может конечно субъективно ) что мы попросту впустую тратим время и разговор уходит в деструктивное русло. Вы, кстати начали с того что вы шефе не спец — ну дак возьмите и попробуйте его поиспользовать, потом soarrowdo с ним или без него и сравните, и тогда уже из вашего практического опыта можем поговорить… а сейчас что-то вам доказывать я если честно говоря устал ))) тут как бы дело добровольное. — нравится инструмент — используйте, не нравится — не используйте, никто как бы не заставляет ))) просто иногда что бы реально понять нужно оно вам или нет — необходимо хотя несколько практических примеров реализовать… по крайней мере я так всегда делаю… удачи! )))

                  • НЛО прилетело и опубликовало эту надпись здесь
                0

                Я чего-то не понимаю или почему пост в хабе Rust?

                  0

                  Я извиняюсь, добавил этот хаб по ошибке, убрал.

                  0

                  Давайте по порядку отвечу на ваши последние комментарии


                  • писать тесты на одном языке есть смысл если вы пишите юнит тесты, когда же речь идёт об интеграционном тестировании, что примерно наш случай, язык написания интеграционных тестов и приведения окружения в требуемое состояние совершенно не обязан быть тем же что и язык на котором написано трестируемое приложение ( в нашем случае кукбуки шеф ). В этом случае, как я уже много раз говорил, выбираем язык, исходя из удобства
                  • вся ваша идея с использованием кукбуков для тестирования или кукбуков обёрток мне была ясна с самого начала, я сам так когда-то делал, основной минус этого подхода — сложность поддержания связанная с тем что шеф не предназначен для таких вещей и прямое подтверждение тому, что просто потому что вам нужно что-то поверить в вашей системе ( шеф сервер ) — появляется куча сущностей, которые являются для неё чужеродными. Еще раз — chef — инструмент управления конфигурациями, не надо запихивать в него ( читайте буквально — создавать кукбуки для тестирования ) сценарии тестирования — они должны быть в другом месте. Читайте внимательно мои предыдущие комментарии, я там объяснил почему.
                  • в случае со Sparrowdo у вас код для тестирования как раз лежит рядом с тестируемых кодом, и ещё ближе чем в варианте когда у вас есть некие кукбуки обертки которыми вы тестируете ваши другие кукбуки, как я вам уже сказал вы просто кладёте Sparrowdo сценарии рядом с кодом кукбука, куда уж ближе ...
                  • основной выйгрыш, который вы получаете со Sparrowdo — это отделение трестируемого от самих тестов ( у вас нет никаких тестовых кукбуков, сосушесвующиз совместно с трестируемыми кукбуками. ) и более короткий цикл запуска сценариев, так как у вас нет необходимости загружать из как кукбука в шеф сервер и вы просто запускаете их напряму по ssh, ваши варианты с копировннием шеф рецептов по scp и использованием шеф соло — ещё одно докозательство того, что в некоторых случаях шеф неудобен для быстрой разработки и отладки
                  • так же Sparrowdo отвязывает разработчика пишущего интеграционный или тестируемый код от необходимости даде знать chef dsl а использовать напрямую нативные команды того дистрибутива OC для которого идёт тестирование. Что делает код сценария лаконичней и эффективнее. Шеф хорош когда вы хотите абстрагироваться от "деталей реализации" целевого сервера, но но когда вам нужно чтото подебажить на более низком уровне все приимущества шеф исчезают и он становится неуклюжим. Примеры? Попробуй написать абстрактный код на bash, и запустил его через шеф — у вас возникнет несколько неприятных моментов с этим — но это тема для отдельного поста, может быть когда нибудь об этом напишу. Только не говорите мне про ресурсы execute и bash...
                  • НЛО прилетело и опубликовало эту надпись здесь

                  Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

                  Самое читаемое