Cfengine3 — система управления конфигурациями

    На Хабре несколько раз писали о системах менеджмента конфигураций puppet и chef, но по какой-то причине первопроходец этой темы — cfengine, обделен вниманием, давайте воспоним этот пробел.

    Первое, что надо отметить касательно cfengine — это декларативный фреймворк, а не императивный. Мы не описываем подробные последовательные шаги для достижения нужной нам конфигурации, мы описываем желаемое состояние системы. Например, «удостовериться, что все вебсерверы с именем web.* имели пакет nginx» или «удостовериться, что скрипт bckup.sh был запущена в 5-й час суток и * успешно* завершился». Cfengine оперирует понятием «обещание» (promice), кроме того cfengine будет пытаться «восстановить» (repair) его периодически, и даже после успешного восстановления будет проверять состояние (state) и восстанавливать опять и опять, что бы достичь конвергенции (convergent configuration). Плюс такого подхода заключается в том, что нет необходимости знать текущее состояние, что бы придти к желаемому. Это особенно важно если у вас часть нод не доступны на момент добавления новых политик (policy) или же наоборот, вы добавляете не сконфигурированные ноды.

    Надеюсь, достаточно вводной информации, давайте рассмотрим примеры.
    Установка проста и не требует много времени. Для Debian:
    cd /tmp
    wget http://cfengine.com/pub/gpg.key
    apt-key add gpg.key
    rm gpg.key
    echo "deb http://cfengine.com/pub/apt squeeze main" >  \
    /etc/apt/sources.list.d/cfengine-community.list
    apt-get update
    apt-get install cfengine-community
    

    Теперь создадим файл содержащий один простой cfengine bundle и совсем
    базовый body который импортирует стандартную библиотеку.
    cat /var/cfengine/inputs/python_virtualenv.cf:
    body common control 
         {
         bundlesequence => { "python_virtualenv" };
                 inputs => { 
                           "cfengine_stdlib.cf", 
                           };
         }
    
    
    bundle agent python_virtualenv {
     vars:
      "package_list" slist => { "virtualenvwrapper", "python-pip" };
      "environments" slist => { "s1.example.com", "s2.example.com" };
    
     packages:
      "${package_list}"
      package_policy => "add",
      package_method => generic;
    
     classes:
       "incorrect_$(environments)" not => fileexists("/tmp/$(environments)/bin/python") ;
    
      reports:
       linux::
       "Virtual environment $(environments) is not installed correctly."
       ifvarclass => canonify("incorrect_$(environments)");
    
      commands:
        linux::
        "/usr/bin/virtualenv /tmp/$(environments) --no-site-packages"
        ifvarclass => canonify("incorrect_$(environments)");
    
    }
    

    Мы декларируем бандл типа agent и с именем python_virtualenv, как можно догадаться, я хочу удостоверится что у меня установлено два независимых python virtualenv, для примера они будут созданы в /tmp/s1.example.com и /tmp/s2.example.com, предварительно «обещаем» переменные в slist. Очевидно, нам нужен python, что мы и декларируем в обещании типа packages. Заметьте, что cfengine автоматически итерирует по list, никаких циклов писать не надо — мы просто декларируем наше намерение. Далее, мы декларируем класс в зависимости от того есть определенный файл или нет. Надо сказать, классы не совсем удачное название, правильнее бы назвать контекстами, и вообще они практически boolean — класс в cfengine или есть или нет! Далее идет обещание типа report, в нем мы видим так называемый hard class linux, hard классы декларирует сам cfengine и они включают тип операционной системы, IP, версию дистрибутива и много еще что, их можно увидеть запустив /var/cfengine/bin/cf-agent -v. Обещания в reports и commands отработают только если установлен класс «incorrect_$(environments)» (вызывается опция canonify, потому-что класс может содержать запрещенные символы и проверка может провалиться). Пробуем запустить:
    /var/cfengine/bin/cf-agent -K -f /var/cfengine/inputs/python_virtualenv.cf
    Получаем:
    Q: "...virtualenv /tmp": New python executable in /tmp/s1.example.com/bin/python
    Q: "...virtualenv /tmp": Installing distribute.................................................................................................................................................................................done.
    I: Last 2 quoted lines were generated by promiser "/usr/bin/virtualenv /tmp/s1.example.com --no-site-packages"
    Q: "...virtualenv /tmp": New python executable in /tmp/s2.example.com/bin/python
    Q: "...virtualenv /tmp": Installing distribute.................................................................................................................................................................................done.
    I: Last 2 quoted lines were generated by promiser "/usr/bin/virtualenv /tmp/s2.example.com --no-site-packages"
    R: Virtual environment s1.example.com is not installed correctly.
    R: Virtual environment s2.example.com is not installed correctly
    

    Смотрим в /tmp и убеждаемся что наши virtualenv созданы.
    Удаляем rm -rf /tmp/s2.example.com!
    И запускаем /var/cfengine/bin/cf-agent -K -f /var/cfengine/inputs/python_virtualenv.cf
    Видим:
    Q: "...virtualenv /tmp": New python executable in /tmp/s2.example.com/bin/python
    Q: "...virtualenv /tmp": Installing distribute.................................................................................................................................................................................done.
    I: Last 2 quoted lines were generated by promiser "/usr/bin/virtualenv /tmp/s2.example.com --no-site-packages"
    R: Virtual environment s2.example.com is not installed correctly.
    

    Cfengine пересоздал только удаленный virtualenv, что вообщем-то что и ожидалось.
    Очевидно, cfengine может работать как standalone, так и с policy hub. Заинтригованы? Можно начать отсюда http://cfengine.com/manuals/cf3-quickstart
    Поделиться публикацией
    Комментарии 14
      0
      Спасибо за статью! Действительно, Cfengine3 все время как-то обделяют вниманием.

      А есть ли подобие solo-mode, как у Chef?
        0
        Пример выше работает в «solo» режиме. Просто кладем файлы в /var/cfengine/inputs/ и все.
        0
        Ещё вопрос: как у него с кросс-платформенностью? Хорошо отрабатывет и на Linux-дистрибутивах и на Windows?
          0
          Я пользуюсь только на linux, windows версия есть, но я ее никогда не проверял.
            –1
            Видел в документации, что Windows поддерживаются только для хостов, а для хаба требуется Linux. Не подскажете, существуют ли подобные системы c полной поддержкой Windows?
              0
              Дело в том есть еще cfengine enterprise платный и там mission портал и много еще что, это все изначально завязано на linux, из этого вытекает факт того что хаб экономически не оправдано делать для нескольких платформ (вольный пересказ слов разработчиков).
          +1
          Спасибо. В этом как раз было моё возражение против чифа/паппета — наличие императивного фреймворка никакой существенной разницы с просто скриптами не даёт. Декларативный формат интереснее.
            +1
            Простите, а где там императивные фреймворки? И там, и там все построено на guarded commands по сути. Классический декларативный подход.
              0
              Мой краткий опыт работы с chef показал и публичные рецепты подтверждают это еще в большей степени, что chef чаще использует императивные конструкции, чем puppet и, тем более, чем cfengine. Кроме того, сам язык политик cfengine делает императивный подход сложным. В любом случае «на любом языке можно писать как фортране».
                0
                В шефе золотыми буквами написано правило «recipe must be idempotent». Если кто-то его не соблюдает — сам себе злобный буротино.
            • НЛО прилетело и опубликовало эту надпись здесь
                0
                Ага, собственно как и Chef.
              0
              Как дела с расширяемостью?

              Агенты, как я понял, написаны на С…
                0
                Сengine написан на C, полиси пишутся на своем декларативном языке. Есть большая стандартная библиотека, которая поддерживается core разработчиками cfengine.com/manuals/CfengineStdLibrary и появился design center, что-то в стиле CPAN cfengine.com/cfengine-design-center

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

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