Puppet: в шкуре кукловода. Часть 2

В прошлой статье я рассказал что такое Puppet, как установить puppetmaster и проверить его работоспособность. В этой я расскажу как подключать ноды, опишу используемую мной организацию манифестов и дам небольшой пример конфигурирования ресурсов на примере описанной в недавней статье утилиты Fail2Ban.

В тексте будут встречаться термины «классы», «ноды», «ресурсы» и т.д., для тех кому смысл этих терминов очень важен советую почитать книгу по Puppet Pulling Strings with Puppet: Configuration Management Made Easy, я рассказывал про нее в промежутке между статьями цикла.

В дальнейшем я буду исходить из того что вы используете CentOS, но иногда буду давать ремарки для других ОС.

Добавление puppet ноды

Из соображений безопасности, а также для гарантированной авторизации хостов(нод) Puppet использует самоподписанные SSL сертификаты. Такой сертификат генерируется при первом запуске puppetd (клиента) на сервере, поэтому перед запуском убедитесь что ваш hostname корректен. Далее с помощью этого сертификата puppet пытается соединиться с хостом puppet. или просто puppet. Т.к. SSL сертификаты чувствительны ко времени, возможно вам придется синхронизировать время между серверами при помощи ntp или другого сервиса. Далее описана процедура установки puppet на сервер под управлением CentOS, если вы используете другой тип установки вы можете перейти сразу к самому концу раздела.

Для добавления puppet ноды нужно установить puppet клиент на сервер-ноду, для этого в систему нужно добавить репозиторий EPEL
Создаем файл /etc/yum.repos.d/epel.repo:

[epel]
name=Extra Packages for Enterprise Linux 5 - $basearch
mirrorlist=http://mirrors.fedoraproject.org/mirrorlist?repo=epel-5&arch=$basearch
failovermethod=priority
enabled=1
gpgcheck=1
gpgkey=http://download.fedora.redhat.com/pub/epel/RPM-GPG-KEY-EPEL
includepkgs=ruby*,puppet*,facter*,augeas*

Далее ставим пакет puppet:

yum install puppet.noarch

Теперь прописываем в файле /etc/hosts наш puppetmaster(возможно вы захотите воспользоваться DNS, тогда вам нужно создать домен puppet.):

# <PUPPETMASTER_IP> puppet
1.1.1.1 puppet

Затем включаем автозапуск puppet и запускаем его:

chkconfig puppet on
service puppet start

Переходим на сервер с puppetmaster`ом и выполняем проверяем соединился ли puppet с сервером:

puppetca --list

на выходе будет строчка с hostname нашей ноды, далее нужно подписать ее сертификат:

# puppetca --sign <NODE_HOSTNAME>
puppetca --sign node1.test.com

Структура конфигурационных файлов

В терминологии Puppet информация о том что и как нужно сделать называется манифест(manifest) или рецепт(recepe), список уже готовых рецептов вы можете найти на сайте Puppetlabs: http://projects.puppetlabs.com/projects/puppet/wiki/Puppet_Recipes. Здесь же я расскажу как начать создавать такие рецепты, покажу пример структуры рецептов.

Итак приступим. Все рецепты пляшут из одного файла site.pp(/etc/puppet/manifests/site.pp), уже оттуда при помощи директивы «import» вы можете подключать свои конфигурационные файлы. Моя структура католога /etc/puppet/manifests выглядит так:

./classes
./classes/fail2ban.pp
./classes/mail.pp
./classes/yumrepos.pp
./nodes
./nodes/default.pp
./nodes/test.com.pp
./site.pp

Т.е. я создал папку classes, куда я складываю описание классов (еще раз советую почитать книгу по Puppet) и папку «nodes» куда я складываю описание нод. В файл site.pp я вписал две строки в которых делаю импорт файлов в этих папках:

import "classes/*.pp"
import "nodes/*.pp"

Таким образом любой файл с расширением .pp (файл манифеста для Puppet) будет подгружен в систему.

Кофигурирование ресурсов

Теперь собственно можно приступить к конфигурированию, далее мы создадим рецепт которые устанавливает и настраивает утилиту для защиты от брутфорса Fail2Ban и рецепт который будет добавлять в систему mail alias для пользователя root, чтобы пересылать нам его письма.

Fail2Ban

создаем файл classes/yumrepos.pp, в нем мы опишем нужный нам репозиторий (см. подробное описание):

# RPMForge repo
yumrepo { 'rpmforge':
    descr => 'Red Hat enterprise $releasever - RPMforge.net - dag',
    mirrorlist => 'http://apt.sw.be/redhat/el5/en/mirrors-rpmforge',
    enabled => '1',
    gpgcheck => '0',
    protect => '0',
    gpgkey => 'http://dag.wieers.com/rpm/packages/RPM-GPG-KEY.dag.txt'
}

Думаю здесь излишние описания не нужны.

Теперь описываем класс fail2ban (за подробностями по типам ресурсов сюда):

class fail2ban{
        package { "fail2ban":
                ensure => latest,
        }
 
        service { "fail2ban":
                ensure => running,
                enable => true,
                hasrestart => true,
                require => Package["fail2ban"],
        }
 
        file {"fail2ban-conf":
                path => "/etc/fail2ban/jail.conf",
                owner => root,
                group => root,
                mode => 644,
                content => template("fail2ban/jail.conf.erb"),
                notify => Service["fail2ban"],
                require => Package["fail2ban"],
        }
}

Итак мы убеждаемся что у нас установлен пакет fail2ban последней версии. Затем мы описываем сервис fail2ban, указываем что он должен быть запущен и включен по умолчанию на автозагрузку, также указываем что сервис имеет команду restart (иначе puppet будет сначала останавливать сервис а потом стартовать). Далее описывается конфигурационный файл для fail2ban, первые четыре строки вроде понятны, в пятой используется функция «template», эта функция по файлу в формате ERB генерирует выходной файл, его то мы и помещаем в наш конфиг. Опция notify означает что нам нужно оповестить сервис о том что файл изменился, т.е. выполнить ему restart.
Теперь подробнее про функцию template, она берет указанный нами файл из папки /var/puppet/templates/ и прогоняет его через ERB (чуть подробнее можно почитать в документации). Т.е. в папке templates я создал папку fail2ban и положил туда подготовленный для него конфиг(см. статью про fail2ban), ERB я в нем не использовал, но для «единобезобразия» всех интерфейса получения конфигов решил использовать именно функцию template.

Mail alias

Теперь создадим еще один ресурс, но уже для управления mail alias`ами в системе. Для этого в папке classes создаем файл mail.pp и записываем в него сл. данные:

class mail{
 
exec{ "newaliases":
    command => "/usr/bin/newaliases",
    refreshonly => true,
}
 
#####################################################
#
#  mail_alias - mail aliases in local system 
#
#  recipient - e-mail of recipient
#
#  Example:
#
#  mail_alias{"root":
#       recipient => "sysadmin@test.com"
#  }
#
#####################################################
define mail_alias($recipient){
        mailalias { $name:
                ensure => present,
                recipient => $recipient,
                target => '/etc/aliases',
                notify => Exec['newaliases'],
        }
}
}

Мы объявляем новый класс mail, в него я планирую помещать ресурсы связанные с локальной почтовой системой сервера. Внутри класса мы определяем новый ресурс (при помощи ключевого слова «define») mail_alias. Ресурсу мы передаем email получателя. Для создания алиаса используется стандартный тип Puppet mailalias. Строка «notify => Exec['newaliases']» служит для того чтобы после добавления алиасов выполнялась команда newaliases, описанная выше, параметр refreshonly означает что команда не будет выполнятся при каждом запуске Puppet, а только если ему придет событие notify.

Конфигурирование нод

Вернемся к нашей ноде «node1.test.com», пришло время применить наши рецепты, для этого в папке nodes создаем файл node1.test.com и записываем туда:

node node1.test.com{
        include "fail2ban"
        mail::mail_alias { 'root':
                recipient => ['sysadmin@test.com'],
        }
}

Итак мы описали ноду, в ее описание мы включили описание класса fail2ban и определили mailalias для пользователя root. Теперь нужно проверить как это все работает, для этого на главном сервере останавливаем puppetmaster и запускаем его руками с параметрами «–verbose –nodaemonize»:

service puppetmaster stop
puppetmasterd --verbose --no-daemonize

Теперь переходим на ноду и выполняем ту же операцию но уже с puppet:

service puppet stop
puppetd --verbose --no-daemonize

Если все правильно сделано, должен вывестись лог выполняемых действий, если будут обнаружены ошибки, они будут подсвечены красным.

Конец

На этот раз все, в следующей статье постараюсь рассказать более подробно про язык (DSL) Puppet`а и возможно про утилиты входящие в состав пакета. Всем очень советую почитать доку к утилите ralsh http://docs.puppetlabs.com/guides/tools.html#ralsh а лучше ralsh –help

Похожие посты:

Комментарии

  1. IlyaS:

    Раскройте пожалуйста следущий вопросик. Можно ли ноды(компьютеры) организовывать в группы и применять действия к группам, а не к отдельным нодам? Как?

    • admin:

      Можно создать ноду с не используемым именем, а дальше уже наследовать от нее новые ноды:

      node defaul{

      }

      node node1.test.com inherits default{

      }

      Вот так, ответил ли я на вопрос?

      • IlyaS:

        А наследование от нескольких нод поддерживается?

        • У Puppet есть неприятная особенность, которая вытекает из его дизайна (разработчики, в irc и листе рассылки бьются лбом о пол, и утверждают, что это концептуально правильно): нельзя переназначать переменные без очень хитрых лингвистических конструкций, через селекторы, в обход.

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

          • admin:

            Спасибо за комментарий, а то я как-то сомневался в правильности конскрукций

            ...
            include apache
            include fail2ban
            include mail_server
            ...

            :)

  2. >На этот раз все, в следующей статье постараюсь рассказать более подробно про язык (DSL) Puppet`а и возможно про утилиты >входящие в состав пакета. Всем очень советую почитать доку к утилите ralsh http://docs.puppetlabs.com/guides
    >/tools.html#ralsh а лучше ralsh –help

    Кроме ralsh есть еще вот такая штука:

    http://cft.et.redhat.com/

Оставить комментарий