Puppet, Chef, Ansible — это так называемые системы управления конфигурациями, которые можно часто встретить в зарубежных IT вакансиях типа Server/DevOps Admin. Фактически же это мощные инструменты которые могут полностью настроить нулёвый сервер или же достаточно быстро массово перенастроить набор из 1-100+ серверов. Работа с пакетами, с командной строкой, файлами настроек, доступно всё.
Общий обзор можно прочитать в публикации «Как стать кукловодом».
Собственно к написанию этой начальной статьи для Puppet меня сподвигло крайне скудное описание во встречающихся в интернете результатах. И даже при использовании официальной документации умудряешься наткнуться на кучу грабель и подводных камней и получить не то, что ожидал.
Причина использования ветки 3.8, вместо 4.3 заключается в использовании именно этой версии на «моих» серверах из-за наличия именно этих пакетов в репо. Платный вариант Enterprise также не рассматривается, т. к. я с ним не работал. Причина использования Centos – он достаточно широко распространён, включая доработанные версии от Amazon.
Для локальных тестов можно использовать две виртуалки на VirtualBox под CentOS-6.5-x86_64.
Для начала настраиваются два интерфейса: для выхода во внешний инет и для создания локальной сети для puppet. Hostname условно будет pmaster.test.net, а узел для клиента (можно и больше узлов) stage.test.net. Пропишем их на всех узлах в hosts (конечно если только у вас нет под них своего ДНС сервера).
Доп рекомендация с офф сайта – открыть порт 8140.
upd. iscsi
Также рекомендуется поставить в /etc/sysconfig/selinux параметр SELINUX=permissive, в крайнем случае disabled.
Актуальная версия руководства по установке от puppetlabs есть тут, где указаны очень важные нюансы, отсутствующие в вашей статье, например, NTP.
/upd. iscsi
Начинаем установку сервера. Импортируем в систему два репо для пакетов:
Ставим пакет сервера:
В нагрузку поставится экзотика типа:
Т. ч. кому критично, аккуратнее с апдейтами. Как итог получаем:
/etc/init.d/puppetmaster — первый вариант работы через сервис для тестов и регистрации узлов. Далее будем переходить на вариант работы через гем под Апачем.
/etc/sysconfig/puppet — микроконфиг. Рекомендуется раскомментировать для получения отдельных логов строчку
/etc/puppet/environments — может использоваться для деления клиентов на группы, весьма неоднозначная технология, нужна, если узлов не меньше 30 и зачастую заменяется экзотической надстройкой R10K.
/etc/puppet/hieradata — используется для хранения, довольно интересная технология, требует отдельной статьи.
/etc/puppet/manifests/site.pp — основной конфиг запуска классов из модулей настройки клиентов.
/etc/puppet/modules — собственно сюда скачиваются/пишутся_свои модули для настройки клиентов, которые по сути представляют из себя набор классов (манифестов), написаных на DSL, похожем на Ruby. При желании можно даже делать вставки на чистом Ruby.
/var/lib/puppet — пока сюда не лезем, будет нужно для сертификатов.
/etc/puppet/puppet.conf — основной конфиг настройки сервера.
Добавляем в секцию [main]:
dns_alt_names — здесь прописываются узлы, которые могут работать с сервером через сертификаты. Тем у кого сервера сидят за проксёй и они хотят тянуть модули с forgeapi.puppetlabs.com, полезно будет знать, что puppet пофиг на ваши системные http_proxy=proxy01.int:8080 и https_proxy=proxy02.int:8080 и придётся забить в конфиг доп секцию.
Для проверки всех текущих параметров сервера есть полезная команда:
Причём даже демон перезагружать не надо, он всё время перечитывает свои конфиги.
На этом временно всё.
Импортируем в систему два репо для пакетов:
Ставим пакет клиента:
Нам нужны:
/etc/init.d/puppet — демон клиента для автопроверок, не изменилось ли что на сервере. Мы будем пользоваться ком строкой.
/etc/sysconfig/puppet — микроконфиг. Приводим его к виду вроде:
/etc/puppet/puppet.conf — основной конфиг.
Добавляем в секцию [main]:
Теперь нам надо сгенерировать и подписать сертификаты. На сервере будет самоподписной и сгенерируется при запуске сервера. На клиенте делаем запрос на верификацию:
Здесь нас может поджидать первый камень типа «забыли про порт или сервис на сервере». Неявно вы увидите ошибку:
Использовав ключ –debug, получите более подробное:
Ну а если всё нормально то нечто вроде:
Идём назад на сервер и проверяем список сертов:
Если он без плюса, значит его надо подписать:
Итог должен появиться в /var/lib/puppet/ssl. Если что то пошло не так всё там стираем и повторяем заново. Собственно теперь у нас готовая конфигурация и можно посмотреть доступное народное творчество, или поискать что то для себя напрямую из командной строки:
Видите имена через дефис? Это формат вида имя_автора-имя_модуля. Мы же напишем первый тестовый модуль чтобы понять схему их использования, а не забивать весь код в site.pp.
Заходим в /etc/puppet/modules и генерируем скелет:
Жмём раз 8 ввод, ибо это всё потом можно переделать.
Получаем каталог myname-mytest, который переименуем в mytest. Полное имя нужно, если вы хотите сбилдить и загрузить свой модуль на общественный forge. Нас интересует файл /etc/puppet/modules/mytest/manifests/init.pp. В class mytest забиваем тот самый псевдоруби типа:
Из особенностей:
— кавычки и апострофы взаимозаменяемы, но иногда кавычки лучше;
— запятые в конце ставьте до предпоследней строчки.
Теперь в /etc/puppet/manifests/site.pp добавляем код типа:
Для теста на клиенте запускаем:
И получаем что то вроде:
Проверим:
Теперь для чего нужен вариант с апачем. Подозреваю дело в производительности и кэшировании. Я не буду говорить сколько пламенных слов было сказано в сторону офф доков в процессе установки и настройки, но в итоге правильный вариант выглядел так:
Стопим сервис:
Ставим кучу добра:
Запускаем экзотическую хрень, которая сбилдит модуль. Он может ругнуться в конце, т. ч. проверим билд и перенастроим апач потом.
Теперь надо создать загрузчик под puppet:
И снова привет /etc/puppet/puppet.conf Добавляем секцию.
Настраиваем модуль и хост в Апаче. Мой вариант /etc/httpd/conf.d/passenger.conf.
Собственно остался запуск сервиса:
И протестить это на клиенте:
Ещё я заметил, что в ветке 3.8.4 теперь изменив код модуля, приходится перезапустить сервис puppetmaster или httpd, чтобы изменения применились сразу, раньше он это не игнорировал.
Создания более сложного модуля, использование Hiera и R10K и заодно описание работы с chef, который по сути наследник puppet но со своими заморочками — это тема отдельной статьи, если дойдут руки.
Общий обзор можно прочитать в публикации «Как стать кукловодом».
Собственно к написанию этой начальной статьи для Puppet меня сподвигло крайне скудное описание во встречающихся в интернете результатах. И даже при использовании официальной документации умудряешься наткнуться на кучу грабель и подводных камней и получить не то, что ожидал.
Причина использования ветки 3.8, вместо 4.3 заключается в использовании именно этой версии на «моих» серверах из-за наличия именно этих пакетов в репо. Платный вариант Enterprise также не рассматривается, т. к. я с ним не работал. Причина использования Centos – он достаточно широко распространён, включая доработанные версии от Amazon.
Для локальных тестов можно использовать две виртуалки на VirtualBox под CentOS-6.5-x86_64.
Для начала настраиваются два интерфейса: для выхода во внешний инет и для создания локальной сети для puppet. Hostname условно будет pmaster.test.net, а узел для клиента (можно и больше узлов) stage.test.net. Пропишем их на всех узлах в hosts (конечно если только у вас нет под них своего ДНС сервера).
10.1.1.10 pmaster.test.net
10.1.1.11 stage.test.net
Доп рекомендация с офф сайта – открыть порт 8140.
upd. iscsi
Также рекомендуется поставить в /etc/sysconfig/selinux параметр SELINUX=permissive, в крайнем случае disabled.
Актуальная версия руководства по установке от puppetlabs есть тут, где указаны очень важные нюансы, отсутствующие в вашей статье, например, NTP.
/upd. iscsi
Установка/настройка пары клиент/сервер
Начинаем установку сервера. Импортируем в систему два репо для пакетов:
rpm -ivh http://yum.puppetlabs.com/puppetlabs-release-el-6.noarch.rpm
rpm -ivh http://mirror.logol.ru/epel/6/i386/epel-release-6-8.noarch.rpm
Ставим пакет сервера:
yum –y install puppet-server
В нагрузку поставится экзотика типа:
hiera 1.3.4-1.el6
ruby 1.8.7.374-4.el6_
rubygems 1.3.7
Т. ч. кому критично, аккуратнее с апдейтами. Как итог получаем:
/etc/init.d/puppetmaster — первый вариант работы через сервис для тестов и регистрации узлов. Далее будем переходить на вариант работы через гем под Апачем.
/etc/sysconfig/puppet — микроконфиг. Рекомендуется раскомментировать для получения отдельных логов строчку
PUPPET_LOG=/var/log/puppet/puppet.log
/etc/puppet/environments — может использоваться для деления клиентов на группы, весьма неоднозначная технология, нужна, если узлов не меньше 30 и зачастую заменяется экзотической надстройкой R10K.
/etc/puppet/hieradata — используется для хранения, довольно интересная технология, требует отдельной статьи.
/etc/puppet/manifests/site.pp — основной конфиг запуска классов из модулей настройки клиентов.
/etc/puppet/modules — собственно сюда скачиваются/пишутся_свои модули для настройки клиентов, которые по сути представляют из себя набор классов (манифестов), написаных на DSL, похожем на Ruby. При желании можно даже делать вставки на чистом Ruby.
/var/lib/puppet — пока сюда не лезем, будет нужно для сертификатов.
/etc/puppet/puppet.conf — основной конфиг настройки сервера.
Добавляем в секцию [main]:
confdir = /etc/puppet
server = pmaster.test.net
certname = pmaster.test.net
environmentpath = $confdir/environments
basemodulepath = $confdir/modules
default_manifest = $confdir/manifests
hiera_config = $confdir/hiera.yaml
environment_timeout = unlimited
dns_alt_names = pmaster.test.net,stage.test.net
vardir=/var/lib/puppet
dns_alt_names — здесь прописываются узлы, которые могут работать с сервером через сертификаты. Тем у кого сервера сидят за проксёй и они хотят тянуть модули с forgeapi.puppetlabs.com, полезно будет знать, что puppet пофиг на ваши системные http_proxy=proxy01.int:8080 и https_proxy=proxy02.int:8080 и придётся забить в конфиг доп секцию.
[user]
http_proxy_host = proxy01.int
http_proxy_port = 8080
Для проверки всех текущих параметров сервера есть полезная команда:
puppet config print
Причём даже демон перезагружать не надо, он всё время перечитывает свои конфиги.
На этом временно всё.
Начинаем установку клиента
Импортируем в систему два репо для пакетов:
rpm -ivh http://yum.puppetlabs.com/puppetlabs-release-el-6.noarch.rpm
rpm -ivh http://mirror.logol.ru/epel/6/i386/epel-release-6-8.noarch.rpm
Ставим пакет клиента:
yum –y install puppet
Нам нужны:
/etc/init.d/puppet — демон клиента для автопроверок, не изменилось ли что на сервере. Мы будем пользоваться ком строкой.
/etc/sysconfig/puppet — микроконфиг. Приводим его к виду вроде:
PUPPET_SERVER=pmaster.test.net
PUPPET_PORT=8140
PUPPET_LOG=/var/log/puppet/puppet.log
PUPPET_EXTRA_OPTS=--waitforcert=500
/etc/puppet/puppet.conf — основной конфиг.
Добавляем в секцию [main]:
server = pmaster.test.net
Теперь нам надо сгенерировать и подписать сертификаты. На сервере будет самоподписной и сгенерируется при запуске сервера. На клиенте делаем запрос на верификацию:
puppet agent --test --ca_server=pmaster.test.net
Здесь нас может поджидать первый камень типа «забыли про порт или сервис на сервере». Неявно вы увидите ошибку:
Error: Could not request certificate: No route to host - connect(2)
Использовав ключ –debug, получите более подробное:
Debug: Creating new connection for https://pmaster.test.net:8140
Error: Could not request certificate: No route to host - connect(2)
Ну а если всё нормально то нечто вроде:
Info: Caching certificate for ca
Info: csr_attributes file loading from /etc/puppet/csr_attributes.yaml
Info: Creating a new SSL certificate request for stage.test.net
Info: Certificate Request fingerprint (SHA256): 89:19:56:C4:76:0F:7F:C3:14:F3:D7:91:81:8C:A3:07:C5:55:AC:32:35:F5:93:6A:1B:17:DE:AC:EB:5D:DD:44
Info: Caching certificate for ca
Exiting; no certificate found and waitforcert is disabled
Идём назад на сервер и проверяем список сертов:
puppet cert list --all
"stage.test.net" (SHA256) 89:19:56:C4:76:0F:7F:C3:14:F3:D7:91:81:8C:A3:07:C5:55:AC:32:35:F5:93:6A:1B:17:DE:AC:EB:5D:DD:44
+ "pmaster.test.net" (SHA256) 67:F8:6A:01:58:9B:1F:24:46:12:4E:5D:FB:39:60:12:79:4C:2C:6C:BE:EF:D2:27:52:95:6C:AE:B3:6C:05:1E (alt names: "DNS:pmaster.test.net", "DNS:stage.test.net")
Если он без плюса, значит его надо подписать:
puppet cert --sign –all
Notice: Signed certificate request for stage.test.net
Notice: Removing file Puppet::SSL::CertificateRequest stage.test.net at '/var/lib/puppet/ssl/ca/requests/stage.test.net.pem'
Итог должен появиться в /var/lib/puppet/ssl. Если что то пошло не так всё там стираем и повторяем заново. Собственно теперь у нас готовая конфигурация и можно посмотреть доступное народное творчество, или поискать что то для себя напрямую из командной строки:
puppet module search passwd
Notice: Searching https://forgeapi.puppetlabs.com ...
NAME DESCRIPTION AUTHOR KEYWORDS
fraenki-vpasswd Manage virtual users @fraenki dovecot proftpd virtual user passwd
wcooley-name_service Type & provider to manage system name service configuration @wcooley dns files ldap passwd lookup group
reidmv-local_user Example local user pattern @reidmv user local passwd
Видите имена через дефис? Это формат вида имя_автора-имя_модуля. Мы же напишем первый тестовый модуль чтобы понять схему их использования, а не забивать весь код в site.pp.
Заходим в /etc/puppet/modules и генерируем скелет:
puppet module generate myname-mytest
Жмём раз 8 ввод, ибо это всё потом можно переделать.
Получаем каталог myname-mytest, который переименуем в mytest. Полное имя нужно, если вы хотите сбилдить и загрузить свой модуль на общественный forge. Нас интересует файл /etc/puppet/modules/mytest/manifests/init.pp. В class mytest забиваем тот самый псевдоруби типа:
class mytest {
file { '/tmp/puppettestfile':
path => '/tmp/puppettestfile',
ensure => file,
content => 'test text'
}
file { '/tmp/puppettestdir':
path => "/tmp/puppettestdir",
ensure => directory
}
}
Из особенностей:
— кавычки и апострофы взаимозаменяемы, но иногда кавычки лучше;
— запятые в конце ставьте до предпоследней строчки.
Теперь в /etc/puppet/manifests/site.pp добавляем код типа:
node default { }
node 'stage.test.net' {
include mytest
}
Для теста на клиенте запускаем:
puppet agent –test
И получаем что то вроде:
puppet agent --test
Info: Retrieving pluginfacts
Info: Retrieving plugin
Info: Caching catalog for stage.test.net
Info: Applying configuration version '1448981968'
Notice: /Stage[main]/Mytest/File[/tmp/puppettestdir]/ensure: created
Notice: /Stage[main]/Mytest/File[/tmp/puppettestfile]/ensure: defined content as '{md5}1e2db57dd6527ad4f8f281ab028d2c70'
Notice: Finished catalog run in 0.15 seconds
Проверим:
ls -l /tmp/puppet*
-rw-r--r-- 1 root root 9 Dec 1 09:54 /tmp/puppetenv
-rw-r--r-- 1 root root 9 Dec 1 09:59 /tmp/puppettestfile
Теперь для чего нужен вариант с апачем. Подозреваю дело в производительности и кэшировании. Я не буду говорить сколько пламенных слов было сказано в сторону офф доков в процессе установки и настройки, но в итоге правильный вариант выглядел так:
Стопим сервис:
/etc/init.d/puppetmaster stop
Ставим кучу добра:
yum install httpd
yum install mod_passenger
yum install mod_ssl
yum install gcc-c++
yum install libcurl-devel openssl-devel zlib-devel httpd-devel ruby-devel
gem install rack
gem install passenger
Запускаем экзотическую хрень, которая сбилдит модуль. Он может ругнуться в конце, т. ч. проверим билд и перенастроим апач потом.
passenger-install-apache2-module
ls -l /usr/lib/ruby/gems/1.8/gems/passenger-5.0.21/buildout/apache2/mod_passenger.so
Теперь надо создать загрузчик под puppet:
mkdir -p /usr/share/puppet/rack/puppetmasterd
mkdir /usr/share/puppet/rack/puppetmasterd/public /usr/share/puppet/rack/puppetmasterd/tmp
cp /usr/share/puppet/ext/rack/config.ru /usr/share/puppet/rack/puppetmasterd/
chown puppet:puppet /usr/share/puppet/rack/puppetmasterd/config.ru
И снова привет /etc/puppet/puppet.conf Добавляем секцию.
[master]
always_cache_features = true
ssl_client_header = SSL_CLIENT_S_DN
ssl_client_verify_header = SSL_CLIENT_VERIFY
Настраиваем модуль и хост в Апаче. Мой вариант /etc/httpd/conf.d/passenger.conf.
LoadModule passenger_module /usr/lib/ruby/gems/1.8/gems/passenger-5.0.21/buildout/apache2/mod_passenger.so
<IfModule mod_passenger.c>
PassengerRoot /usr/lib/ruby/gems/1.8/gems/passenger-5.0.21
PassengerDefaultRuby /usr/bin/ruby
</IfModule>
PassengerHighPerformance on
PassengerMaxPoolSize 12
PassengerPoolIdleTime 600
PassengerMaxRequests 1000
PassengerStatThrottleRate 120
Listen 8140
<VirtualHost *:8140>
SSLEngine on
SSLProtocol ALL -SSLv2 -SSLv3
SSLCipherSuite EDH+CAMELLIA:EDH+aRSA:EECDH+aRSA+AESGCM:EECDH+aRSA+SHA384:EECDH+aRSA+SHA256:EECDH:+CAMELLIA256:+AES256:+CAMELLIA128:+AES128:+SS
SSLHonorCipherOrder on
SSLCertificateFile /var/lib/puppet/ssl/certs/pmaster.test.net.pem
SSLCertificateKeyFile /var/lib/puppet/ssl/private_keys/pmaster.test.net.pem
SSLCertificateChainFile /var/lib/puppet/ssl/ca/ca_crt.pem
SSLCACertificateFile /var/lib/puppet/ssl/ca/ca_crt.pem
SSLCARevocationFile /var/lib/puppet/ssl/ca/ca_crl.pem
SSLVerifyClient optional
SSLVerifyDepth 1
SSLOptions +StdEnvVars +ExportCertData
RequestHeader unset X-Forwarded-For
RequestHeader set X-SSL-Subject %{SSL_CLIENT_S_DN}e
RequestHeader set X-Client-DN %{SSL_CLIENT_S_DN}e
RequestHeader set X-Client-Verify %{SSL_CLIENT_VERIFY}e
DocumentRoot /usr/share/puppet/rack/puppetmasterd/public
RackBaseURI /
<Directory /usr/share/puppet/rack/puppetmasterd/>
Options None
AllowOverride None
Order allow,deny
allow from all
</Directory>
ErrorLog /var/log/httpd/puppet-server_error.log
CustomLog /var/log/httpd/puppet-server_access.log combined
</VirtualHost>
Собственно остался запуск сервиса:
/etc/init.d/httpd start
И протестить это на клиенте:
puppet agent --test
Ещё я заметил, что в ветке 3.8.4 теперь изменив код модуля, приходится перезапустить сервис puppetmaster или httpd, чтобы изменения применились сразу, раньше он это не игнорировал.
Создания более сложного модуля, использование Hiera и R10K и заодно описание работы с chef, который по сути наследник puppet но со своими заморочками — это тема отдельной статьи, если дойдут руки.
iscsi
Если вы не можете в SELinux, то оставьте, как минимум, permissive.
Делать rpm -ivh безграмотно, надо yum [install|localinstall] [url|path], потому что rpm -ivh не попадет в историю транзакций yum history.
Актуальная версия руководства по установке от puppetlabs есть тут, где указаны очень важные нюансы, отсутствующие в вашей статье, например, NTP.
Vas003
Спс, часть добавил в статью.
А насчёт -ivh направляю вас в офф док, пишите им ;-).