Решение проблемы идентичности сред в DevOps методологии


Сегодня многие говорят о DevOps как о методологии, которая помогает разрушить «железный занавес» между IT отделом, QA и программистами и создать некий общий механизм, помогающий делать продукты быстрее и качественнее. Основная задача, которая встает перед DevOps разработчиком — это добиться максимальной автоматизации развертывания development. testing, production сред и переходов между ними. Соответственно одна из основных проблем в данном случае — это соблюсти полную идентичность сред разработки, тестирования и эксплуатации. Под катом приведу пример практического решения данной задачи, которое я использовал в нескольких компаниях в ходе интеграции DevOps методологии.

Так как речь идет о рабочем примере, сразу опишу те ограничения, которые задаются при решении данной задачи:
  • Стабильная версия популярный rpm-based дистрибутиа с большим сообществом, где помогут решить типовые проблемы связанные с ОС. Был выбран CentOS, так как на текущий момент это самое популярный rpm-based дистрибутив.
  • Возможность версионирования среды. Программисты занимались разработкой сразу нескольких форков продукта на CentOS 5 и CentOS 6
  • Обязательный набор софта для корректной работы и разворачивания продукта (это пример, в реальности список был значильно больше):
    Для CentOS 5:
    • python => 2.4
    • python-IPy
    • python-simplejson
    • mysql-server >= 5.0

    Для CentOS 6:
    • python => 2.6
    • python-IPy
    • python-simplejson
    • mysql-server >= 5.1


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

Чтобы унифицировать это решение я разработал утилиту build-tools https://github.com/scopenco/build-tools, которая позволяет создавать RHEL, CentOS, Fedora, Scientific yum репозитарии с метапакетом (пакет проекта) на базе XML спецификаций(aka ролей). Роли описывают набор обязательных пакетов и репозитариев, откуда эти пакеты вместе с зависимостями скачиваются в локальный yum репозитарий (aka билд). Данный репозитарий используется в качестве пакетной базы для продукта.

Итак, установка build-tools очень простая и описана в README.
Перейдем к спецификациям проектов.
Пример спецификации для СentOS 5:

<?xml version="1.0" encoding="UTF-8"?>
<project 
        name="myproject"
        summary="My First Project"
        repository="http://repo.domain.com/pub/repo/"
        version="0.1"
        >

  <!-- role with minimal set of packages -->
  <role path="roles/centos-5-minimal.xml" />

  <!-- python packages -->
  <package name="python" version="2.4.3" />
  <package name="python-IPy" />
  <package name="python-simplejson" />

  <!-- mysql packages -->
  <package name="mysql-server" version="5.0.95" />

  <!-- yum repos -->
  <role path="repos/centos-5-base.xml" />
  <role path="repos/centos-5-updates.xml" />
  <role path="repos/centos-5-epel.xml" />
</project>


Пример спецификации для СentOS 6:

<?xml version="1.0" encoding="UTF-8"?>
<project 
        name="myproject"
        summary="My First Project"
        repository="http://repo.domain.com/pub/repo/"
        version="0.2"
        >

  <!-- role with minimal set of packages -->
  <role path="roles/centos-6-minimal.xml" />

  <!-- python packages -->
  <package name="python" version="2.6.6" />
  <package name="python-IPy" />
  <package name="python-simplejson" />

  <!-- mysql packages -->
  <package name="mysql-server" version="5.1.71" />

  <!-- yum repos -->
  <role path="repos/centos-6-base.xml" />
  <role path="repos/centos-6-updates.xml" />
  <role path="repos/centos-6-epel.xml" />
</project>

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

cd src
cp ../repository .
./build-el5.sh
./build-el6.sh

Сборка репозитариев выполняется обязательно на CentOS 5. Причиной этому является тот факт, что yum обратно не совместим и репозитарии, собранные через yum API CentOS 6 не будут ставиться на CentOS 5 машины, тогда как репозитарии, собранные на CentOS 5 ставятся на CentOS 6, Fedora 13 и выше, Scientific 5 и выше.

После запуска сбоки на выходе получается 2-а репозитария, с которых можно заливать физические и виртуальные сервера по kickstart. Таким образом фиксируется набор софта, который можно хранить в корпоративном репозитарии и использовать для разворачивания продукта.

Можно создавать новые роли с публичными yum репозитариями и пакетами для кастомизации сред.
Рассмотрим несколько популярных вариантов:
  • Допустим для testing среды нужно добавить какие-то дополнительные rpm пакеты, которых не должно быть в production. В этом случае создается отдельная роль со списком этих пакетов и отдельный проект для testing среды, куда эта роль добавляется на ряду с ролями для остальных сред. Сборку билдов для всех сред нужно сделать в тот же день чтобы версии пакетов в билдах для development и production не отличались от testing а только их кол-во.
  • Допустим есть регламентированный список софта, который должен присутствовать на всех серверах проекта. В таком случае создается отдельная роль с этим списком, которая добавляться во все спецификации проектов. Таком образом гарантируется что софт будет установлен на всех серверах.

Подробное описание атрибутов можно найти в wiki build-tools.

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

Итоги:
Таким образом, используя build-tools мне удалось:
  1. решить проблему идентичности development, testing, production сред
  2. предоставить разработчикам широкие возможности по версионированию среды и совместимости софта в рамках всего проекта
Поделиться публикацией

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

    0
    Кстати говоря, создать универсальный репозиторий-то для centos5/6 вполне возможно. Репо OpenVZ тому пример — пакеты для обоих версий создаются идентичные.
      0
      А вы считали сколько весит репозитарий, который вмещает весь base, updates, epel и тд? Это Теробайты данных. Здесь же вам собирается готовый репозитарий 300мб причем вы можете регулярно его версионировать и иметь еще c 10-к ревизий.
      +1
      Но все равно честно говоря, не совсем понимаю, зачем это нужно. Сделать собственный репозиторий и назвать его MyAnotherCentosDistro и перенести туда десяток пакетов, например, из Epel? Это же ад адский каждый раз зависимости пакетов разбирать

      Но все равно вопрос — почему нельзя использовать исходные репозитории и в чем опасность этого?

      Единственное применение методу которое я могу найти — это создание оверлей репозитория, например, в котором подменен Apache на свой собственный.
        0
        Но все равно честно говоря, не совсем понимаю, зачем это нужно. Сделать собственный репозиторий и назвать его MyAnotherCentosDistro и перенести туда десяток пакетов, например, из Epel? Это же ад адский каждый раз зависимости пакетов разбирать


        Так в том то и соль что утилита стягивает все пакеты с зависимостями.

        Но все равно вопрос — почему нельзя использовать исходные репозитории и в чем опасность этого?

        Опишу проще, допустим программисты взялись что-то писать. Для них налили виртуалки и они что-то там химичат. Через месяц приходят с каким-то результатом, который нужно протестировать. Соответственно наливаются testing виртуалки а на них все работает по другому и немного криво потому что оказалось что за месяц обновился libxml2, из-за чего по другому стали работать какие-то функции. Ну и когда это все дойдет до продакшна, на тот момент тоже что-то обновится и вполне возможно работать не будет как надо. Поэтому и используются build-tools чтобы избежать подобных проблем.
          0
          Простите, а вы накатываете обновления пакетов на сервера без тестов?
          У нас подобная проблема решается средствами puppet с подробным описанием зависимостей и специфичными репами врода testing для тех пакетов, которые пересобираются руками у нас.
          И цикл deploy`я идет: локальные виртуалки -> тестовый продакшен -> продакшен.
          Мне кажется, ваш путь излишен в связи с современными утилитами развертывания…
          ps:
          Опишу проще, допустим программисты взялись что-то писать. Для них налили виртуалки и они что-то там химичат. Через месяц приходят с каким-то результатом, который нужно протестировать. Соответственно наливаются testing виртуалки а на них все работает по другому и немного криво потому что оказалось что за месяц обновился libxml2, из-за чего по другому стали работать какие-то функции.

          Это вообще недопустимый ад на мой взгляд.
            0
            Простите, а вы накатываете обновления пакетов на сервера без тестов?
            У нас подобная проблема решается средствами puppet с подробным описанием зависимостей и специфичными репами врода testing для тех пакетов, которые пересобираются руками у нас.
            И цикл deploy`я идет: локальные виртуалки -> тестовый продакшен -> продакшен.
            Мне кажется, ваш путь излишен в связи с современными утилитами развертывания…

            Объясню почему я против контроля версий софта через puppet. Допустим вы послали команду на testing среду обновить php. Puppet пришел все красиво обновил, передернул apache и все завелось и работает. Вы прогнали тесты и теперь очередь за продакшном. Вы посылаете команду обновить php на продакшне и puppet ушел обновлять всем и сразу. В итоге продашкн у вас находится под рабочей нагрузкой и apache при этом не рестартуется как положено из-за того что на некоторых серверах была высокая нагрузка и apache просто подвис и не смог перезапуститься, остался слушать сокет и ушел в себя. Его остается только прибить и запустить занова.
            Получается что в тестинге все обновилось как надо, а в продакшне получили пачку серверов с лежачим apache-ом, который нужно еще по мониторингу отследить и поднять. Спрашивается — это контролируемое обновление? Я считаю что нет.
            Puppet с моем понимании должен заниматься исключительно настройкой софта, но как ни установкой и обновлением.
              0
              Не вижу проблем использовать puppet как раз-таки для установки и обновления софта.
              + если у вас puppet обновляет все и сразу — есть смысл пересмотреть свои рецепты.
              У нас каждый кластер (и каждая виртуалка и тому подобное) имеет свои настройки. И возможно обновлять софт выборочно, штучно.
                0
                Тогда у вас получается очень увесистая конфигурация puppet. Считайте каждую node описать, да еще и с вервиями софта и рецепами настроек. Я как раз за простоту. Я уже писал что считаю что на puppet нельзя навешивать логику обновления и контроля версий, особенно если у вас много рецептов настройки и тд. Проходил это очень давно и личный опыт показывает что это сильно усложняет конфигурацию в puppet-е.
                Мне нравится схема = пакеты контролируются через build-tools, настройки через puppet. В таком варианте просто обнаруживать причину проблем, почему на том или ином сервере не та версия софта, или не те настройки. Понимаешь куда смотреть сразу.
                  0
                  У нас вся конфигурация таким образом получается в одном месте, и для деплоя, и для админов, и для разработчиков. Конфиги puppet храним в репозитории git с посткомитными скриптами проверок + каждый коммит перед мержем с мастером проходит пару проверок людьми (не теми, которые коммитили).
                  У нас таким образом ни разу не всплывала проблема «почему на том или ином сервере не та версия софта, или не те настройки», более того, наши разработчики используют один унифицированный образ с фиксированными версими всего и всея.
                  Поэтому мне ваш случай с новыми версиями пакетов и нестыковками не нравится.
                  Вы можете хранить конфиги и в build тулзах, по сути разницы нет, просто тогда у вас странно процесс разработки, деплоя и тестов построен, если допускается ситуация с конфликтом версий.
                  Все чистое имхо.
                    0
                    наши разработчики используют один унифицированный образ с фиксированными версими всего и всея.

                    Ну а как же обновление системы? Постоянно выходят новые обновления того же CentOS-а. Вы вообще все версии всех пакетов (в том числе системных) держите в puppet-е?

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

                    Так вот как раз с build-tools не допускается ситуация с конфликтом версий.
                      0
                      Ну а как же обновление системы?

                      Есть базовый образ, его же можно отдельно обновлять и полностью тестить на совместимость, если все ок — появляется новый унифицированный образ.
                        0
                        Как вы тогда обновляете сервера, если продакнт у вас на старом унифицированном образе а нужно переехать на новый?
            0
            > Для них налили виртуалки и они что-то там химичат

            Если админы просто налили виртуалки, а потом не знают, что программисты там «химичат», и лишь через месяц последние приходя к первым с релизом для тестирования со словами «на!», то, мне кажется, у вас не DevOps.
              0
              Вы слишком буквально воспринимаете мой пример. Конечно админы как и манагеры в курсе что «химичат» программисты. Я пытаюсь вам донести немного другое: может быть ситуация, что код в тестинге не работает, из-за того что версии пакеты более свежие. Происходит это из-за того что налали девел среду из публичных репозитариев, через какое-то время налили тестинг среду тоже из публичных репозитариев и софт уже новее и продукт по каким-то причинам не работает. В таком случае тестировщику придется вернуть продукт на доработку и время разработки автоматом увеличивается.
              С другой стороны если пакетная база фиксированная, то от девела до продакшна пакеты одинаковые и проблем связанных с версиями софта — не будет.
                0
                А не пробовали создать свой образ дистрибутива и использовать только его? С отключенным автообновлением и нужными настройками? И обновление оного только после прогона тестов.
                Решает кучу проблем, заодно и траффик экономит.
                  0
                  Как раз build-tools и создает образ дистрибутива в виде готового репозитария. Настройки часто меняются, оптимизируются, поэтому носятся они puppet-ом. Плюшки заключаются в том что вы используя build-tools можно держать много ревизий ОС и обновлять по необходимости.
              0
              Я стараюсь следовать этой идее Treating Your Infrastructure Like Garbage — Mike Fiedler.

              Потому что да, рано или поздно процесс апдейта чего либо через шеф/паппет дает сбой, зато оба прекрасно справляются с первоначальной настройкой. Таким образом приходим к идее что все находится за балансировчиками, включая сами балансировцики, и все разворачивается из образов. В продакшен попадает та же самая связка версий App+OS что и в тестинг.

              Подход плохо работает если у вас шаред хостинг — тогда приходится отделять версии всех приложений от версии OS и это вот реальная головная боль. В добавок обновления безопасности не накатываются в тот же день, а накапливаюстя — потом под них делается новый образ и этот образ выкатывается rolling update прямиком в продакшн.
                0
                Ну вот, я же предлагаю абсолютно универсальный метод, который подходит для любых проектов, начиная от хостинга и заканчивая веб проектами.
            0
            В практике я придерживаюсь того, что система всегда обновления до максимально возможного состояния в пределах мажорной версии дистрибутива. За все 7 лет работы с CentOS/Debian я не видел ни единого минорного обновления (в пределах версии дистрибутива), которое что-либо сломало. Это же собственно для чего и нужен стабильный дистриубтив — никаких изменений в функционале и полная обратная совместимость.

            Так что я по-прежнему не понимаю кейса.

            В данном примере разработчики должны получить до упора обновленную систему и поддерживать ее в таком состоянии все время, пока они что-либо пишут во избежание проблем.

            Да, это не касается, например, того же Epel и тем более уж всяких RpmForge, где творят весьма нестабильные вещи подчас, но и из них нужны обычно единицы пакетов.
              0
              В практике я придерживаюсь того, что система всегда обновления до максимально возможного состояния в пределах мажорной версии дистрибутива. За все 7 лет работы с CentOS/Debian я не видел ни единого минорного обновления (в пределах версии дистрибутива), которое что-либо сломало. Это же собственно для чего и нужен стабильный дистриубтив — никаких изменений в функционале и полная обратная совместимость.


              Как не печально какая бы стабильный не был CentOS, баги есть и будут. С тем же libxml2 недавно был случай связанный с php, когда после обновления не корректно работали некоторые функции в php. CentOS если говорить на чистоту стабилен только в своих base и updates репозитариях но все используют еще epel, repoforge и тд, так как никому не интересно пользоваться совсем старым софтом.

              Так что я по-прежнему не понимаю кейса.

              В данном примере разработчики должны получить до упора обновленную систему и поддерживать ее в таком состоянии все время, пока они что-либо пишут во избежание проблем.

              А зачем их напрягать этой проблемой, если им можно предоставить готовую среду разработки? Суть DevOps как раз состоит в кооперации труда. Время разработчиков стоит больших денег и я вам открою большую тайну — далеко не все разработчики умеют вмеяемо пользоваться консолью.
              Кроме того с момента разработки до продакшна как правило проходит много времени и за это время много может обновиться.

              Да, это не касается, например, того же Epel и тем более уж всяких RpmForge, где творят весьма нестабильные вещи подчас, но и из них нужны обычно единицы пакетов.

              Ну у кого как. Мне попадались билды, где epel-а было 15-20% пакетов и еще столько же собственной сборки. Даже банальные LAMP пакеты сильно старые в базовых репозитариях и почти все пользуются сторонними репозитариями.

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

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