30 December 2012

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

System administrationPuppet
На Хабре несколько раз писали о системах менеджмента конфигураций 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
Tags:cfenginepuppetchefconfiguration managementавтоматизацияавтоматическая установка
Hubs: System administration Puppet
+13
22.4k 70
Comments 14