Сергей Яремчук
Централизованная настройка UNIX-систем с помощью Puppet
Управление большим количеством UNIX-систем нельзя назвать удобным. Для изменения одного параметра администратору приходится обращаться к каждой машине, скрипты лишь частично могут помочь, да и не во всех ситуациях.
Следует признать, что администраторы Windows-сетей находятся все-таки в более выгодном положении. Достаточно изменить настройки групповых политик, и через некоторое время все компьютеры сети, в том числе и с недавно установленной операционной системой, «узнают» о нововведении, если они их, конечно, касаются. Оглянувшись на долгий период развития UNIX, можно заметить, что ничего подобного так и не прижилось. Есть решения вроде kickstart, которые помогают при первичной установке операционной системы, но дальнейшая доводка потребует значительных усилий. Коммерческие решения, вроде BladeLogic и OpsWare , проблему автоматизации настроек решают лишь отчасти, основное их достоинство – наличие графического интерфейса, да и позволить их приобрести могут только крупные организации. Есть, конечно, и проекты, предлагающие свободные решения, но за все время своего существования они так и не смогли создать большого сообщества. Например, Cfengine не очень пользуется популярностью уадминистраторов, хотя, кроме Linux, может использоваться в *BSD, Windows и Mac OS X. Возможно, это связано с относительной сложностью в создании конфигураций. Приописании заданий приходится учитывать особенности каждой конкретной системы и вручную контролировать последовательность действий при выполнении команд. То есть администратор должен помнить, что для одних систем следует писать adduser для других – useradd, учитывать расположение файлов в разных системах и так далее. Это на порядок усложняет процесс написания команд, с ходу создать правильную конфигурацию очень сложно, а созданные конфигурации прочитать через некоторое время практически нереально. Несмотря на GPL-лицензию Cfengine, фактически проект одного человека, который контролирует все изменения и не очень заинтересован в построении открытого общества. В результате возможности Cfengine вполне удовлетворяют разработчика, а для остальных администраторов это скорее лишняя головная боль. Чтобы улучшить Cfengine, сторонними разработчиками были созданы различные дополнения, что часто только ухудшало ситуацию. Автор нескольких таких модулей к Cfengine Люке Каниес (Luke Kanies) витоге решил разработать подобный инструмент, но лишенный многих недостатков Cfengine.
Возможности Puppet
Puppet , как и Cfengine, является клиент-серверной системой, использующей декларативный, то есть обязательный для выполнения язык для описания задач и библиотеки дляихреализации. Клиенты периодически (по умолчанию каждые 30 минут) соединяются с центральным сервером и получают последнюю конфигурацию. Если полученные настройки не совпадают с системным состоянием, они будут выполнены, при необходимости серверу отсылается отчет о произведенных операциях. Сервер сообщения может сохранить вsyslog или файл, создать RRD-график, отослать на указанный e-mail. Дополнительные уровни абстракции Transactional и Resource обеспечивают максимальную совместимость ссуществующими настройками и приложениями, позволяя сфокусироваться на системных объектах, не заботясь о различиях в реализации и описании подробных команд иформатах файлов. Администратор оперирует лишь с типом объекта, остальное Puppet берет на себя. Так, тип packages знает о 17 пакетных системах, нужная автоматически будет распознана на основании информации о версии дистрибутива или системы, хотя при необходимости пакетный менеджер можно задать принудительно.
В отличие от скриптов, которые часто невозможно использовать в других системах, конфигурации Puppet, написанные сторонними администраторами, будут в большинстве безпроблем работать в любой другой сети. В Puppet CookBook уже имеется три десятка готовых рецептов. В настоящее время Puppet официально поддерживает следующие операционные системы и сервисы: Debian, RedHat/Fedora, Solaris, SUSE, CentOS, Mac OS X, OpenBSD, Gentoo и MySQL, LDAP.
Язык Puppet
Чтобы идти дальше, вначале следует разобраться с основными элементами и возможностями языка. Язык – это одна из сильных сторон Puppet. С его помощью описываются ресурсы, которыми администратор планирует управлять, и действия. В отличие от большинства подобных решений, в Puppet язык позволяет упростить обращение ко всем схожим ресурсам на любой системе в гетерогенной среде. Описание ресурса, как правило, состоит из названия, типа и атрибутов. Например, укажем на файл /etc/passwd и установим его атрибуты:
file { "/etc/passwd":
Owner => root,
Group => root,
Mode => 644,
Теперь клиенты, подключившись к серверу, скопируют файл /etc/passwd и установят указанные атрибуты. В одном правиле можно определять сразу несколько ресурсов, разделяя их с помощью точки с запятой. А что делать, если конфигурационный файл, используемый на сервере, отличается от клиентских или вообще не используется? Например, такая ситуация может возникнуть при настройках VPN-соединений. В этом случае следует указать на файл директивой source. Здесь два варианта, можно, как обычно указать путь кдругому файлу, а также с помощью поддерживающихся двух URI протоколов: file и puppet. В первом случае используется ссылка на внешний NFS-сервер, во втором варианте насервере Puppet запускается NFS-подобный сервис, который и экспортирует ресурсы. В последнем случае по умолчанию путь указывается относительно корневого каталога puppet– /etc/puppet. То есть ссылка puppet://server.domain.com/config/sshd_config будет соответствовать файлу /etc/puppet/config/sshd_config. Переопределить этот каталог можно спомощью директивы filebucket, хотя более правильно использовать одноименную секцию в файле /etc/puppet/fileserver.conf. В этом случае можно ограничить доступ к сервису только сопределенных адресов. Например, опишем секцию config:
Path /var/puppet/config
Allow *.domain.com
Allow 127.0.0.1
Allow 192.168.0.*
Allow 192.168.1.0/24
Deny *.wireless.domain.com
А затем обращаемся к этой секции при описании ресурса:
source => "puppet://server.domain.com/config/sshd_config"
Перед двоеточием располагается название ресурса. В самых простых случаях в качестве имени можно просто указать полный путь к файлу. В более сложных конфигурациях лучше использовать псевдоним или переменные. Псевдоним устанавливается с помощью директивы alias:
file { "/etc/passwd":
Alias => passwd
Другой вариант создания псевдонима хорошо подходит в том случае, когда приходится иметь дело с разными операционными системами. Например, создадим ресурс, описывающий файл sshd_config:
file { sshdconfig:
Name => $operatingsystem ? {
Solaris => "/usr/local/etc/ssh/sshd_config",
Default => "/etc/ssh/sshd_config"
В этом примере мы столкнулись с возможностью выбора. Отдельно указан файл для Solaris, для всех остальных будет выбран файл /etc/ssh/sshd_config. Теперь к этому ресурсу можно обращаться как к sshdconfig, в зависимости от операционной системы будет выбран нужный путь. Например, укажем, что в случае, если демон sshd запущен и получен новый файл, следует перезапустить сервис:
service { sshd:
Ensure => true,
Subscribe => File
Переменные часто используются при работе с пользовательскими данными. Например описываем месторасположение домашних каталогов пользователей:
$homeroot = "/home"
Теперь к файлам конкретного пользователя можно обратиться как:
${homeroot}/$name
В параметр $name будет подставлено учетное имя пользователя. В некоторых случаях удобно определить значение по умолчанию для некоторого типа. Например, для типа exec очень часто указывают каталоги, в которых он должен искать исполняемый файл:
Exec { path => "/usr/bin:/bin:/usr/sbin:/sbin" }
В том случае, если нужно указать на несколько вложенных файлов и каталогов, можно использовать параметр recurse:
file { "/etc/apache2/conf.d":
Source => "puppet:// puppet://server.domain.com/config/apache/conf.d",
Recurse => "true"
Несколько ресурсов могут быть объединены в классы или определения. Классы являются законченным описанием системы или сервиса и используются обособленно:
class linux {
File {
"/etc/passwd": owner => root, group => root, mode => 644;
"/etc/shadow": owner => root, group => root, mode => 440
Как и в объектно-ориентированных языках, классы могут переопределяться. Например, в FreeBSD группой-владельцем этих файлов является wheel. Поэтому, чтобы не переписывать ресурс полностью, создадим новый класс freebsd, который будет наследовать класс linux:
class freebsd inherits linux {
File["/etc/passwd"] { group => wheel };
File["/etc/shadow"] { group => wheel }
Для удобства все классы можно вынести в отдельный файл, который нужно подключать директивой include. Определения могут принимать многочисленные параметры в качестве аргументов, но не поддерживают наследования и используются в том случае, если нужно описать многократно используемые объекты. Например, определим домашний каталог пользователей и команды, необходимые для создания новой учетной записи:
define user_homedir ($group, $fullname, $ingroups) {
User { "$name":
Ensure => present,
Comment => "$fullname",
Gid => "$group",
Groups => $ingroups,
Membership => minimum,
Shell => "/bin/bash",
Home => "/home/$name",
Require => Group[$group],
Exec { "$name homedir":
Command => "/bin/cp -R /etc/skel /home/$name; /bin/chown -R $name:$group /home/$name",
Creates => "/home/$name",
Require => User[$name],
Теперь, чтобы создать новую учетную запись, достаточно обратиться к user_homedir:
user_homedir { "sergej":
Group => "sergej",
Fullname => "Sergej Jaremchuk",
Ingroups => ["media", " admin]
Отдельно стоят описания узлов (node), которые поддерживают наследование, как и классы. При подключении клиента к серверу Puppet будет произведен поиск соответствующей секции node и выданы специфические только для этого компьютера настройки. Для описания всех остальных систем можно использовать node default. Описание всех типов приведено в документе «Type Reference», с которым необходимо ознакомиться в любом случае, хотя бы для того, чтобы понять все возможности языка Puppet. Различные типы позволяют выполнять указанные команды, в том числе и при выполнении определенных условий (например, изменение конфигурационного файла), работать с cron, учетными данными и группами пользователей, компьютерами, монтированием ресурсов, запуском и остановкой сервисов, установкой, обновлением и удалением пакетов, работой с SSH-ключами, зонами Solaris и так далее. Вот так просто можно заставить обновлять список пакетов в дистрибутивах, использующих apt, ежедневно между 2 и 4 часами:
schedule { daily:
Period => daily,
Range =>
exec { "/usr/bin/apt-get update":
Schedule => daily
Обновление за тот период каждой системой будет выполнено только один раз, после чего задание считается выполненным и будет удалено с клиентского компьютера. Язык Puppet поддерживает другие привычные структуры: условия, функции, массивы, комментарии и подобные.
Установка Puppet
Для работы Puppet потребуются Ruby (начиная с версии 1.8.1 и выше) с поддержкой OpenSSL и библиотеками XMLRPC, а также библиотека Faster . В репозитарии Ubuntu 7.04, который использовался при тестовой установке, уже включен пакет puppy:
$ sudo apt-cache search puppet
~$ ruby -rxmlrpc/client -e "puts:yep"
yep |
Если не получено ошибок, значит, все необходимое уже включено. Файлы, в которых описывается желательная конфигурация систем, в терминологии Puppet называются манифестами (manifests). При запуске демон пытается прочитать файл /etc/puppet/manifests/site.pp, при его отсутствии выдает предупреждающее сообщение. При тестировании можно указать демону на работу в автономном режиме, при котором манифест не требуется:
$ sudo /usr/bin/puppetmasterd --nonodes
При необходимости к site.pp можно подключать другие файлы, например, с описаниями классов. Для тестового запуска в этот файл можно занести самую простую инструкцию.
class sudo {
File { "/etc/sudoers":
Owner => root,
Group => root,
Mode => 440,
node default {
Include sudo
Все конфигурационные файлы, как сервера так и клиентов, расположены в /etc/puppet. Файл fileserver.conf, о котором мы уже говорили, не обязателен и используется только в том случае, когда Puppet будет работать еще и как файл-сервер. В Ubuntu в этом файле экспортируется подкаталог /etc/puppet/files. В подкаталоге ssl расположены сертификаты и ключи, которые будут использоваться для шифрования при подключениях клиентов. Ключи создаются автоматически при первом запуске puppetmasterd, вручную их можно создать командой:
$ sudo /usr/bin/puppetmasterd --mkusers
Файлы puppetd.conf и puppetmasterd.conf похожи. В них указываются некоторые параметры работы демонов на клиентской системе и сервере. Клиентский файл отличается только наличием параметра server, указывающего на компьютер, на котором запущен puppetmasterd:
server = grinder.com
logdir = /var/log/puppet
vardir = /var/lib/puppet
rundir = /var/run
# отсылаем отчет серверу
report = true
Чтобы не печатать все вручную, можно создать шаблон с помощью самого puppetd:
$ puppetd --genconfig > /etc/puppet/puppetd.conf
Аналогично можно создать и site.pp на сервере:
$ puppetd --genmanifest > /etc/puppet/manifests/site.pp
Еще один файл tagmail.conf, позволяет указать почтовые адреса, на которые будут отсылаться отчеты. В простейшем случае можно использовать одну строку:
all: [email protected]
Конфигурационных файлов недостаточно, чтобы клиент мог подключаться к серверу. Для этого необходимо еще подписать сертификаты.
Сначала, чтобы сервер узнал о новом компьютере, на клиентской системе вводим команду:
$ sudo puppetd --server grinder.com --waitforcert 60 –test
Межсетевой экран должен разрешать соединения на порт 8140.
На сервере получаем список сертификатов, нуждающихся в подписи:
$ sudo puppetca –list
nomad.grinder.com |
И подписываем сертификат клиента:
$ sudo puppetca –sign nomad.grinder.com
Теперь клиент может свободно подключаться к серверу и получать настройки.
К сожалению, все возможности Puppet в пределах статьи показать невозможно. Но, как видите, это функциональный и гибкий инструмент, позволяющий решить большую часть задач по одновременному администрированию большого числа систем. И самое главное, проекту удалось собрать пока небольшое, но постоянно растущее сообщество. Поэтому будем надеяться, что хорошей идее не дадут умереть или уйти в сторону.
Удачи!
- Сайт проекта BladeLogic – http://www.bladelogic.com .
- Сайт проекта OpsWare – http://www.opsware.com .
- Сайт проекта Cfengine – http://www.cfengine.org .
- Сайт проекта Puppet – http://reductivelabs.com/projects/puppet .
- Puppet CookBook – http://www.reductivelabs.com/trac/puppet/tagspuppet%2Crecipe .
- Библиотека Faster –
Управление большим количеством Unix систем нельзя назвать удобным. Для изменения одного параметра администратору приходится обращаться к каждой машине, скрипты лишь частично могут помочь, да и не во всех ситуациях.
Следует признать, что администраторы Windows сетей находятся все-таки в более выгодном положении. Достаточно изменить настройки групповых политик и через некоторое время все компьютеры сети, в том числе и с недавно установленной операционной системой “узнают” о нововведении, если они их конечно касаются. Оглянувшись на долгий период развития Unix, можно заметить, что ничего подобного так и не прижилось. Есть решения вроде kickstart, которые помогают при первичной установке операционной системы, но дальнейшая доводка потребует значительных усилий. Коммерческие решения вроде BladeLogic и OpsWare , проблему автоматизации настроек решают лишь отчасти, основное их достоинство наличие графического интерфейса, да и позволить их приобрести могут только в крупных организациях. Есть конечно и проекты предлагающие свободные решения, но за все время своего существования они так и не смогли создать большого сообщества. Например Cfengine не очень пользуется популярностью у администраторов, хотя кроме Linux, может использоваться в *BSD, Windows и Mac OS X. Возможно это связано с относительной сложностью в создании конфигураций. При описании заданий приходится учитывать особенности каждой конкретной системы, и вручную контролировать последовательность действий при выполнении команд. То есть администратор должен помнить, что для одних систем следует писать adduser для других useradd, учитывать расположение файлов в разных системах, и так далее. Это на порядок усложняет процесс написания команд, с ходу создать правильную конфигурацию очень сложно, а созданные конфигурации прочитать через некоторое время практически не реально. Не смотря на GPL лицензию Cfengine фактически проект одного человека, который контролирует все изменения и не очень заинтересован в построении открытого общества. В результате возможности cfengine вполне удовлетворяют разработчика, а для остальных администраторов это скорее лишняя головная боль. Чтобы улучшить cfengine сторонними разработчиками были созданы различные дополнения, что часто только ухудшало ситуацию. Автор нескольких таких модулей к cfengine Люке Каниес (Luke Kanies) в итоге решил разработать подобный инструмент, но лишенный многих недостатков cfengine.
Возможности Puppet
Puppet как и cfengine является клиент-серверной системой использующей декларативный, то есть обязательный для выполнения язык для описания задач и библиотеки для их реализации. Клиенты периодически (по умолчанию 30 минут) соединяются с центральным сервером и получают последнюю конфигурацию. Если полученные настройки не совпадают с системным состоянием, они будут выполнены, при необходимости серверу отсылается отчет о произведенных операциях. Сервер сообщения может сохранить в syslog или файл, создать RRD график, отослать на указанный e-mail. Дополнительные уровни абстракции Transactional и Resource обепечивают максимальную совместимость с существующими настройками и приложениями, позволяя сфокусироваться на системных объектах, не заботясь о различиях в реализации и описании подробных команд и форматах файлов. Администратор оперирует лишь с типом объекта, остальное Puppet берет на себя. Так тип packages знает о 17 пакетных системах, нужная автоматически будет распознана на основании информации о версии дистрибутива или системы, хотя при необходимости пакетный менеджер можно задать принудительно.
В отличие от скриптов, которые часто не возможно использовать в других системах, конфигурации Puppet написанные сторонними администраторами будут в большинстве без проблем работать в любой другой сети. В Puppet CookBook [http://www.reductivelabs.com/trac/puppet/tags/puppet%2Crecipe ] уже имеется три десятка готовых рецептов. В настоящее время Puppet официально поддерживает следующие операционные системы и сервисы: Debian, RedHat/Fedora, Solaris, SUSE, CentOS, Mac OS X, OpenBSD, Gentoo и MySQL, LDAP.
Язык Puppet
Чтобы идти дальше, вначале следует разобраться с основными элементами и возможностями языка. Язык это одна из сильных сторон Puppet. С его помощью описываются ресурсы которыми администратор планирует управлять и действия. В отличие от большинства подобных решений, в Puppet язык позволяет упростить обращение ко всем схожим ресурсам на любой системе в гетерогенной среде. Описание ресурса, как правило, состоит из названия, типа и атрибутов. Например укажем на файл /etc/passwd и установим его атрибуты:
file { «/etc/passwd»:
owner => root,
group => root,
Теперь клиенты, подключившись к серверу скопируют файл /etc/passwd и установят указанные аттрибуты. В одном правиле можно определять сразу несколько ресурсов, разделяя их с помощью точки с запятой. А что делать если конфигурационный файл используемый на сервере отличается от клиентских или вообще не используется? Например такая ситуация может возникнуть при настройках VPN соединений. В этом случае следует на файл можно указать директивой source. Здесь два варианта, как обычно указать путь к другому файлу, также поддерживается два URI протокола: file и puppet. В первом случае используется ссылка на внешний NFS сервер, во втором варианте на сервере Puppet, запускается NFS подобный сервис, который и экспортирует ресурсы. В последнем случае по умолчанию путь указывается относительно корневого каталога puppet — /etc/puppet. То есть ссылка puppet://server.domain.com/config/sshd_config будет соответствовать файлу /etc/puppet/config/sshd_config. Переопределить этот каталог, можно с помощью директивы filebucket, хотя более правильно использовать одноименную секцию в файле /etc/puppet/fileserver.conf. В этом случае можно ограничить доступ к сервису только с определенных адресов. Например опишем секцию config.
path /var/puppet/config
allow *.domain.com
allow 192.168.0.*
allow 192.168.1.0/24
deny *.wireless.domain.com
А затем обращаемся к этой секции при описании ресурса.
source => «puppet://server.domain.com/config/sshd_config»
Перед двоеточием располагается название ресурса. В самых простых случаях в качестве имени можно просто указатьлучше использовать псевдоним или переменные. Псевдоним устанавливается с помощью директивы alias. полный путь к файлу. В более сложных конфигурациях
file { «/etc/passwd»:
alias => passwd
Другой вариант создания псевдонима, хорошо подходит в том случае, когда приходится иметь дело с разными операционными системами. Например, создадим ресурс описывающий файл sshd_config:
file { sshdconfig:
name => $operatingsystem ? {
solaris => «/usr/local/etc/ssh/sshd_config»,
default => «/etc/ssh/sshd_config»
В этом примере мы столкнулись с возможностью выбора. Отдельно указан файл для Solaris, для всех остальных будет выбран файл /etc/ssh/sshd_config. Теперь к этому ресурсу можно обращаться как к sshdconfig, в зависимости от операционной системы будет выбран нужный путь. Например укажем, что в случае если демон sshd запущен и получен новый файл, следует перезапустить сервис.
ensure => true,
subscribe => File
Переменные часто используются при работе с пользовательскими данными. Например описываем месторасположение домашнних каталогов пользователей:
$homeroot = «/home»
Теперь к файлам конкретного пользователя можно обратиться как
${homeroot}/$name
В параметр $name будет подставлено учетное имя пользователя. В некоторых случаях удобно определить значение по умолчанию для некоторого типа. Например для типа exec очень часто указывают каталоги в которых он должен искать исполняемый файл:
Exec { path => «/usr/bin:/bin:/usr/sbin:/sbin» }
В том случе если нужно указать на несколько вложенных файлов и каталогов, можно использовать параметр recurse.
file { «/etc/apache2/conf.d»:
source => «puppet:// puppet://server.domain.com/config/apache/conf.d»,
recurse => «true»
Несколько ресурсов могут быть объеденены в классы или определения. Классы являются законченным описанием системы или сервиса и используются обособленно.
«/etc/passwd»: owner => root, group => root, mode => 644;
«/etc/shadow»: owner => root, group => root, mode => 440
Как и в объектно-ориентированных языках классы могут переопределяться. Например в FreeBSD группой-владельцем этих файлов является wheel. Поэтому чтобы не переписывать ресурс полностью, создадим новый класс freebsd, который будет наследовать класс linux:
class freebsd inherits linux {
File[«/etc/passwd»] { group => wheel };
File[«/etc/shadow»] { group => wheel }
Для удобства все классы можно вынести в отдельный файл, который подключать директивой include. Определения могут принимать многочисленные параметры в качестве аргументов, но не поддерживают наследования и используются в том случае если нужно описать многократно используемые объекты. Например определим домашний каталог пользователей и команды необходимые для создания новой учетной записи.
define user_homedir ($group, $fullname, $ingroups) {
user { «$name»:
ensure => present,
comment => «$fullname»,
gid => «$group»,
groups => $ingroups,
membership => minimum,
shell => «/bin/bash»,
home => «/home/$name»,
require => Group[$group],
exec { «$name homedir»:
command => «/bin/cp -R /etc/skel /home/$name; /bin/chown -R $name:$group /home/$name»,
creates => «/home/$name»,
require => User[$name],
Теперь чтобы создать новую учетную запись достаточно обратиться к user_homedir.
user_homedir { «sergej»:
group => «sergej»,
fullname => «Sergej Jaremchuk»,
ingroups => [«media», » admin]
Отдельно стоят описания узлов (node), которые поддерживают наследование как и классы. При подключении клиента к серверу Puppet будет произведен поиск соотетсвующей секции node и выданы специфические только для этого компьютера настройки. Для описания всех остальных систем можно использовать node default. Описание всех типов приведено в документе “Type Reference” с которым необходимо ознакомиться в любой случае, хотя бы, для того чтобы понять все возможности языка Puppet. Различные типы позволяют выполнять указанные команды, в том числе и при выполнении определенных условий (например изменение конфигурационного файла), работать с cron, учетными данными и группами пользователей, компьютерами, монтированием ресурсов, запуском и остановкой сервисов, установкой, обновлением и удалением пакетов, работой с SSH ключами, зонами Solaris и так далее. Вот так просто можно заставить обновлять список пакетов в дистрибутивах использующих apt, ежедневно между 2 и 4 часами.
schedule { daily:
period => daily,
range =>
exec { «/usr/bin/apt-get update»:
schedule => daily
Обновление за тот период каждой системой будет выполнено только один раз, после чего задание считается выполненным и будет удалено с клиентского компьютера. Язык Puppet поддерживает другие привычные структуры: условия, функции, массивы, комментарии и подобные.
Установка Puppet
Для работы Puppet потребуются Ruby (>= 1.8.1) с поддержкой OpenSSL и библиотеками XMLRPC, а также библиотека Faster [http://reductivelabs.com/projects/facter ]. В репозитарии Ubuntu 7.04, который использовался при тестовой установке, уже включен пакет puppy.
$ sudo apt-cache search puppet
puppet — centralised configuration management for networks
puppetmaster — centralised configuration manangement control daemon
При инсталляции будут установлены все необходимые зависимости пакеты: facter libopenssl-ruby libxmlrpc-ruby.
$ sudo apt-get install puppet puppetmaster
Проверить наличие библиотек Ruby можно командой.
$ ruby -ropenssl -e «puts:yep»
~$ ruby -rxmlrpc/client -e «puts:yep»
Если не получено ошибок, значит все необходимое уже включено. Файлы в которых описывается желательная конфигурация систем в терминологии Puppet называются манифестами (manifests). При запуске демон пытается прочитать файл /etc/puppet/manifests/site.pp, при его отсутствии выдает предупреждающее сообщение. При тестировании можно указать демону на работу в автоновном режиме при котором манифест не требуется
$ sudo /usr/bin/puppetmasterd —nonodes
При необходимости к site.pp можно подключать другие файлы, например с описаниями классов. Для тестового запуска в этот файл можно занести самую простую инструкцию.
file { «/etc/sudoers»:
owner => root,
group => root,
Все конфигурационный файлы как сервера так и клиентов расположены в /etc/puppet. Файл fileserver.conf о котором мы говорили выше, не обязателен и используется только в том случае когда Puppet будет работать еще и как файл-сервер. В Ubuntu в этом файле экспортируется подкаталог /etc/puppet/files. В подкаталоге ssl расположены сертификаты и ключи, которые будут использоваться для шифрования при подключениях клиентов. Ключи создаются автоматически при первом запуске puppetmasterd, вручную их создать можно командой.
$ sudo /usr/bin/ puppetmasterd —mkusers.
Файлы puppetd.conf и puppetmasterd.conf похожи. В них указываются некоторые параметры работы демонов на клиенской системе и сервере. Клиенский файл отличается только наличием параметра server, указывающего на компьютер на котором запущен puppetmasterd.
server = grinder.com
logdir = /var/log/puppet
vardir = /var/lib/puppet
rundir = /var/run
# отсылаем отчет серверу
Чтобы не печатать все вручную, можно создать шаблон с помощью самого puppetd.
$ puppetd —genconfig > /etc/puppet/puppetd.conf
Аналогично можно создать и site.pp на сервере.
$ puppetd —genmanifest > /etc/puppet/manifests/site.pp
Еще один файл tagmail.conf, позволяет указать почтовые адреса на которые будут отсылаться отчеты. В простейшем случае можно использовать одну строку.
all: [email protected]
Конфигурационных файлов недостаточно, чтобы клиент мог подключаться к серверу. Для этого необходимо еще подписать сертификаты. Сначала чтобы сервер узнал о новом компьютере на клиентской системе вводим команду:
$ sudo puppetd —server grinder.com —waitforcert 60 —test
info: Requesting certificate
warning: peer certificate won’t be verified in this SSL session
notice: Did not receive certificate
Если будет выдана другая строка, следует проверить работу сервера.
$ ps aux | grep puppet
puppet 5779 0.0 1.4 27764 15404 ? Ssl 21:49 0:00 ruby /usr/sbin/puppetmasterd
Межсетевой экран должен разрешать соединения на порт 8140.
На сервере получаем список сертификатов нуждающихся в подписи.
$ sudo puppetca —list
nomad.grinder.com
И подписываем сертификат клиента.
$ sudo puppetca –sign nomad.grinder.com
Теперь клиент может свободно подключаться к серверу и получать настройки.
К сожалению все возможности Puppet в пределах статьи показать просто не возможно. Но как видите это функциональный и гибкий инструмент, позволяющий решить большую часть задач по одновременному администрированию большого числа систем. Если вам по роду работы приходится настраивать несколько систем. И самое главное проекту удалось собрать пока небольшое, но постоянно растущее сообщество. Поэтому будем надеяться, что хорошей идее не дадут умереть или уйти в сторону.
Puppet - это кроссплатформенная структура, позволяющая системным администраторам выполнять общие задачи с использованием кода. Код позволяет выполнять различные задачи от установки новых программ до проверки прав доступа файлов или обновлений пользовательских учетных записей. Puppet превосходна не только в процессе изначальной установки системы, но и на протяжении всего жизненного цикла системы. В большинстве случаев puppet используется в конфигурации клиент/сервер.
Этот раздел показывает установку и настройку Puppet в конфигурации клиент/сервер. Этот простой пример демонстрирует как установить Apache с использованием Puppet .
Установка
Для установки Puppet введите в терминале:
Sudo apt-get install puppetmaster
На клиентской машине (или машинах) введите:
Sudo apt-get install puppet
Настройка
Прежде чем настраивать puppet вам возможно захочется добавить запись DNS CNAME для puppet.example.com , где example.com - это ваш домен. По умолчанию клиенты Puppet проверяют DNS на наличие puppet.example.com в качестве имени puppet сервера (Puppet Master ). Смотрите Служба доменных имен для дополнительных деталей использования DNS .
Если вы не предполагаете использовать DNS , вы можете добавить записи в файл /etc/hosts на сервере и клиенте. Например, в файл /etc/hosts Puppet сервера добавьте:
127.0.0.1 localhost.localdomain localhost puppet 192.168.1.17 meercat02.example.com meercat02
На каждом Puppet клиенте добавьте запись для сервера:
192.168.1.16 meercat.example.com meercat puppet
Замените IP адреса и доменные имена из примера на ваши актуальные адреса и имена сервера и клиентов.
Теперь настроим некоторые ресурсы для apache2 . Создайте файл /etc/puppet/manifests/site.pp , содержащий следующее:
Package { "apache2": ensure => installed } service { "apache2": ensure => true, enable => true, require => Package["apache2"] }
Node "meercat02.example.com" { include apache2 }
Замените meercat02.example.com на актуальное имя вашего Puppet клиента.
Финальным шагом для этого простого Puppet сервера является перезапуск сервиса:
Sudo /etc/init.d/puppetmaster restart
Теперь на Puppet сервере все настроено и время настроить клиента.
Сначала настроим сервис Puppet агента для запуска. Отредактируйте /etc/default/puppet, заменив значение START на yes :
Sudo /etc/init.d/puppet start
Возвращаемся на Puppet сервер для подписи клиентского сертификата с помощью команды:
Sudo puppetca --sign meercat02.example.com
Проверьте /var/log/syslog на любые ошибки конфигурации. Если все прошло хорошо, пакет apache2 и его зависимости будут установлены на Puppet клиенте.
Этот пример очень простой и не показывает многие возможности и преимущества Puppet . Для дополнительной информации смотрите
Некоторое время назад список серверов у меня в закладках перевалил за отметку в 200. По мере увеличения количества серверов развертывание любой новой конфигурации или установка новых пакетов, приводит к трате огромного количества времени. Так я решил использовать puppet.
Puppet
(англ. марионетка) - кроссплатформенное клиент-серверное приложение, которое позволяет централизованно управлять конфигурацией операционных систем и программ, установленных на нескольких компьютерах. Puppet написан на языке программирования Ruby.
Еще говорят, что puppet это система удаленного управления конфигурациями, наиболее известными представителями которых являются открытые системы Cfengine и Puppet.
Ознакомившись с отзывами я решил использовать puppet.
Puppet сервер установка и настройка:
Установка puppet-сервера
:
Установим puppet-server на OpenSuSE 11.4:
zypper in puppet-server
Изменим имя сервера на puppet:
/etc/HOSTNAME:
DNS запись должна резолвиться на 127.0.0.2
cat /etc/hosts:
127.0.0.2 puppet.site puppet
Дадим права для пользователя puppet :
Запустим сервис Puppet Master:
rcpuppetmasterd start
Добавим запуск puppet демона в автозагрузку:
chkconfig -a puppetmasterd
Настройка puppet-сервера:
Определим директорию, где будут храниться файлы, которые puppet-server будет передавать на машины-клиенты в манифестах типа file.
vim /etc/puppet/fileserver
path /etc/puppet/files
allow *
mkdir /etc/puppet/files
chown -R puppet:puppet /etc/puppet/files
Создадим файл любого содержания для развертывания и тестирования на клиентах
touch /etc/puppet/files/puppettesting
Перезагрузим puppet сервер:
rcpuppetmasterd restart
Puppet использует собственный язык описания конечного состояния операционной системы, с помощью которого сисадмин указывает то, к какому виду должны быть приведены компоненты ОС, чтобы она достигла желаемого состояния. Под состоянием может подразумеваться наличие определенного файла, папки, запущенных сервисов установленных пакетов, обновлений и другое. Все настройки состояний описываются в файлах или манифестах, которые расположены в каталоге: /etc/puppet/manifests. Эти файлы имею имена типа *.pp.
Создадим простейший манифест
:
/etc/puppet/manifests/1.file.pp:
file { "/tmp/puppettesting" :
source => "puppet:///files/puppettesting",
}
Для применения даннного манифеста:
puppet apply 1.file.pp
Установка и настройка клиента puppet:
zypper in puppet
Дадим права puppet пользователю:
chown -R puppet.puppet /var/lib/puppet/
Для установки связи с puppet-сервером puppet-клиент посылает запрос на подтверждение сертификата, после того, как на сервере будет подтвержден этот запрос, puppet клиент начнет использовать манифесты предназначенные для него. Пошлем запрос на подтверждение сертификата:
На сервере мы можем увидеть какие запросы на подтверждение ожидают:
"puppet-client.localdomain" (B5:12 :69 :63 :DE:19 :E9:75 :32 :2B:AA:74 :06:F6:8E:8A)
Подтверждаем:
puppetca --sign "puppet-client.localdomain"
Самое время рассмотреть простейшие примеры создание манифестов:
создадим файл /etc/puppet/manifests/site.pp:
node default {
file
{
"/tmp/puppettesting"
:
source
=>
"puppet:///files/puppettesting"
,
}
service {
"ntp"
:
ensure =>
running,
enable
=>
true
,
}
package {
"htop"
:
ensure =>
installed,
}
}
default - применять для всех клиентов
file - эта секция говорит создать или перезаписать файл /tmp/puppettesting который находится на сервере в каталоге /etc/puppet/files
service: проверить запущен ли сервис, если не запущен, то запустить его, а также добавить в автозагрузку
package: проверить установлен ли на клиенте пакет htop и если нет, то установить его.
Для проверки запустим на клиенте:
Как видим на клиенте был добавлен ntp в автозагрузку, запущен ntp демон, установлен пакет htop, а также скопирован файл puppettesting в директорию /tmp/
info: Caching catalog for
puppet-client.localdomain
info: Applying configuration version "1370163660"
notice: /
Stage[
main]
//
Node[
default]
/
Service[
ntp]
/
ensure: ensure changed "stopped"
to "running"
notice: /
Stage[
main]
//
Node[
default]
/
Package[
htop
]
/
ensure: created
notice: /
Stage[
main]
//
Node[
default]
/
File[
/
tmp/
puppettesting]
/
ensure: defined content as
"{md5}f2171ac69ba86781bea2b7c95d1c8e67"
notice: Finished catalog run in
3.95
seconds
В следующей статье я опишу более сложные примеры создания манифестов и web-интерфейс puppet-dashboard.
Популярные типы ресурсов Puppet
cron
- управление заданиями cron
exec
- запуск скриптов и команд
file
- управление файлами
filebucket
- резервное копирование файлов
group
- управление группами
host
- управление записями в файле /etc/hosts
interface
- конфигурирование сетевых интерфейсов
mount
- монтирование файловых систем
notify
- посылка сообщения в лог-файл Puppet
package
- управление пакетами
service
- управление сервисами
sshkey
- управление ключами SSH
tidy
- удаление файлов в зависимости от условий
user
- управление пользователями
zones
- управление зонами Solaris
Когда число серверов, которыми вы управляете меньше десяти — редко кто задумывается об их централизованном управлении, этого может и не требоваться. Когда серверов десятки — централизованное управление ПО и конфигурациями крайне полезно. Когда серверов сотни и тысячи — это жизненно необходимо. Программ такого рода много, например: Chef, CFEngine, Puppet… Вот о последнем и пойдет речь в этой записи.
Puppet по достоинству считается одним из лучших решений в этом роде. Его используют такие компании как Google, Citrix и Red Hat. Это собой клиент-серверное приложение написанное на языке программирования Ruby, которое распространяется в двух вариантах:
- Puppet Open Source — полностью бесплатная версия
- Puppet Enterprise — бесплатная в конфигурации до 10 серверов, далее требуется приобретение лицензий
Рассмотрим установку сервера и агента Puppet Open Source, которые присутствует в пакетах большинства современных дистрибутивов. Далее речь пойдет о Ubuntu 12.04 Precise Pangolin.
Серверная часть Puppet называется puppetmaster , начнем установку с нее:
:~# apt-get install puppetmasterА теперь клиент:
:~# apt-get install puppetВ конфигурационном файле клиента /etc/puppet/puppet.conf необходимо рассказать о сервере, добавив следующую секцию:
Server=puppet.local report=true pluginsync=false
На первоначальном этапе pluginsync лучше выключить.
Запустим клиент puppet чтобы он создал запрос на получение сертификата:
:~# puppetd --verbose --test info: Creating a new SSL key for linux.local info: Caching certificate for ca info: Creating a new SSL certificate request for linux.local info: Certificate Request fingerprint (md5): E5:EA:AC:5B:22:9A:BA:42:B8:A1:63:9E:1F:1F:23:51 Exiting; no certificate found and waitforcert is disabledНа сервере необходимо проверить что запрос сертификата получен и, если это так, выписываем сертификат:
:~# puppetca --list "linux.local" (E5:EA:AC:5B:22:9A:BA:42:B8:A1:63:9E:1F:1F:23:51) :~# puppetca --sign linux.local notice: Signed certificate request for linux.local notice: Removing file Puppet::SSL::CertificateRequest linux.local at "/var/lib/puppet/ssl/ca/requests/linux.local.pem"Повторяем предыдущий шаг на клиенте:
:~# puppetd --verbose --test info: Caching certificate for linux.local info: Retrieving plugin info: Caching certificate_revocation_list for ca info: Caching catalog for linux.local info: Applying configuration version "1356278451" info: Creating state file /var/lib/puppet/state/state.yaml notice: Finished catalog run in 0.02 secondsОтлично, все работает. Переходим к созданию первого манифеста. Манифесты, они же конфигурации описываются на специальном декларативном языке. Будем сразу приучаться к хорошему, использовать модульную структуру и классы. Для примера напишем модуль который будет поддерживать в актуальном виде файл /etc/hosts на всех наших серверах.
Проверим, где puppet ищет модули:
:~# puppet apply --configprint modulepath /etc/puppet/modules:/usr/share/puppet/modulesСоздаем каталоги для своего модуля
:~# cd /etc/puppet/modules :~# mkdir hosts; cd hosts; mkdir manifests; cd manifestsПервый манифест, он же основной файл модуля — должен называться init.pp
Class hosts { # puppet.local host { "puppet.local": ensure => "present", target => "/etc/hosts", ip => "192.168.0.1", host_aliases => "puppet", } # linux.local host { "linux.local": ensure => "present", target => "/etc/hosts", ip => "192.168.0.2", host_aliases => "linux", } }
По-умолчанию puppet ищет файл /etc/puppet/manifests/site.pp чтобы загрузить конфигурацию, приведем его к следующему виду:
Node default { include hosts }
Проверяем манифест на сервере:
:~# puppet apply --verbose /etc/puppet/manifests/site.pp info: Applying configuration version "1356281036" notice: /Stage//Host/ensure: created info: FileBucket adding {md5}notice: /Stage//Host/ensure: created notice: Finished catalog run in 0.03 secondsНа клиенте:
:~# ll /etc/hosts rw-r--r-- 1 root root 290 Dec 16 19:10 /etc/hosts :~# puppetd --verbose --test info: Caching catalog for linux.local info: Applying configuration version "1356283380" info: FileBucket adding {md5}notice: /Stage/Hosts/Host/ensure: created notice: /Stage/Hosts/Host/ensure: created notice: Finished catalog run in 0.04 seconds :~# ll /etc/hosts -rw-r--r-- 1 root root 551 Dec 23 20:43 /etc/hostsПосле того как мы убедились что все работает, разрешаем запуск службы, в /etc/default/puppet меняем:
# Start puppet on boot? START=yes
Запускаем службу
:~# service puppet startPuppet будет каждые 30 минут опрашивать сервер puppetmaster на предмет изменения конфигурации и, при необходимости, производить соответствующую настройку системы.
Похожие статьи