Пытаемся воспроизвести best practice разработчиков puppet. Всё ставится просто и по шагам. Только учитываем, что в самом лучшем случае, если в вашей компании нормальное руководство и им не жалко денег на нужды оркестровки, администрирования и экономию времени своих администраторов, то вам понадобится 3 сервера: 1 – puppetmaster, 2 – postgresql, 3 – puppetdb. Так же такая схема в будущем поможет вам при росте вашей инфраструктуры в кластеризации puppet сервиса. В моём случае, увы, я буду использовать 2 физических сервера: 1 – puppetmaster, 2 – postgresql/puppetdb.
Centos 7
- Берём образ centos 7 netinstall либо minimal из официальных реп либо зеркал. Расписывать подробный процесс установки centos в рамках этой статьи не буду.
- После установки centos добавляем необходимые нам репозитарии:
yum -y install epel-release rpm -ivh https://yum.puppetlabs.com/puppetlabs-release-pc1-el-7.noarch.rpm
- Устанавливаем набор необходимых утилит:
yum install vim-enhanced htop mc screen tcpdump wget ethtool traceroute bind-utils dmidecode iptables ntp bash-completion iptables-services pciutils telnet sudo puppet
- [Необязательно] Изменяем названия интерфейсов с enp на привычное eth. Для этого редактируем /etc/default/grub и добавляем в GRUB_CMDLINE_LINUX параметр net.ifnames=0 . В итоге получится что-то типа:
GRUB_TIMEOUT=5 GRUB_DISTRIBUTOR="$(sed 's, release .*$,,g' /etc/system-release)" GRUB_DEFAULT=saved GRUB_DISABLE_SUBMENU=true GRUB_TERMINAL_OUTPUT="console" GRUB_CMDLINE_LINUX="crashkernel=auto rhgb net.ifnames=0 quiet" GRUB_DISABLE_RECOVERY="true"
Переписываем конфиг загрузчика:
grub2-mkconfig -o /boot/grub2/grub.cfg
- Разбираемся с Selinux. Отключать совсем не будем, но изменим дефолтную политику на “разрешить всё” и используем только DAC (избирательное управление доступом). Для этого приводим /etc/selinux/config к виду:
# This file controls the state of SELinux on the system. # SELINUX= can take one of these three values: # enforcing - SELinux security policy is enforced. # permissive - SELinux prints warnings instead of enforcing. # disabled - No SELinux policy is loaded. SELINUX=permissive # SELINUXTYPE= can take one of three two values: # targeted - Targeted processes are protected, # minimum - Modification of targeted policy. Only selected processes are protected.. # mls - Multi Level Security protection. SELINUXTYPE=targeted
Выполняем:
/usr/sbin/setenforce 0
- Добавляем нового пользователя в систему под которым будем производить все дальнейшие изменения, потому что под пользователем root это делать небезопасно.
useradd -m -G wheel vasya
Приводим /etc/sudoers к виду:
Defaults requiretty Defaults !visiblepw Defaults always_set_home Defaults env_reset Defaults env_keep = "COLORS DISPLAY HOSTNAME HISTSIZE INPUTRC KDEDIR LS_COLORS" Defaults env_keep += "MAIL PS1 PS2 QTDIR USERNAME LANG LC_ADDRESS LC_CTYPE" Defaults env_keep += "LC_COLLATE LC_IDENTIFICATION LC_MEASUREMENT LC_MESSAGES" Defaults env_keep += "LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER LC_TELEPHONE" Defaults env_keep += "LC_TIME LC_ALL LANGUAGE LINGUAS _XKB_CHARSET XAUTHORITY" Defaults secure_path = /sbin:/bin:/usr/sbin:/usr/bin root ALL=(ALL) ALL %wheel ALL=(ALL) ALL
- Апдейтим систему если это необходимо и перезагружаемся:
yum update /sbin/reboot
- Заходим в систему под нашим пользователем vasya , получаем привилегии root командой sudo -s и далее все изменения в системе производим из под него.
- Выключаем firewalld и включаем iptables:
systemctl stop firewalld systemctl disable firewalld systemctl enable iptables.service systemctl start iptables.service
Разрешаем всё, что необходимо для работы puppetmaster и puppetdb приведя файл /etc/sysconfig/iptables к виду:
# sample configuration for iptables service # you can edit this manually or use system-config-firewall # please do not ask us to add additional ports/services to this default configuration *filter :INPUT ACCEPT [0:0] :FORWARD ACCEPT [0:0] :OUTPUT ACCEPT [0:0] -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT -A INPUT -p icmp -j ACCEPT -A INPUT -i lo -j ACCEPT -A INPUT -p tcp -m tcp -m multiport --dports 8140,8081 -j ACCEPT -A INPUT -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT -A INPUT -j REJECT --reject-with icmp-host-prohibited -A FORWARD -j REJECT --reject-with icmp-host-prohibited COMMIT
Перезагружаем правила сетевого фильтра:
iptables-restore < /etc/sysconfig/iptables [/sourcecode]</li> <li>Правим часовую зону и время наших серверов. Это очень важно при подписывании сертификатов <em>timedatectl set-timezone Russia/Moscow </em>и синхронизируем время <em>ntpdate ntp4.stratum2.ru </em>либо с любым сервером из <a href="https://www.ntp-servers.net/servers.html">списка</a>.</li> <li>Тюним ядро. Можно использовать мой <a href="https://avalon.land/blog/?p=253">strong optimization</a> из предыдущей статьи.</li> </ul> </ul> Готово! Настройка серверов завершена. Если вы используете виртуальные машины, то с этой точки можно сделать <em>snapshot</em>. <hr /> <h1 style="text-align: center;"><span style="color: #808080;">Puppet Server</span></h1> <strong>Puppet Server</strong> он же <em>puppet master</em> в нашей схеме будет отвечать за хранение и раздачу конфигурации для нод клиентов и хранение сертификатов. Вообще, хранить конфигурации правильнее в git с помощью модуля <strong>r10k</strong> , а сертификаты нод на отдельном сервере при кластеризации puppet-сервиса, но в этой статье мы всего этого использовать не будем. <ul> <li>Переименуем наш puppet server в <em>puppet</em> как рекомендуют нам разработчики. Для этого внесём изменения в <em>/etc/hostname</em> : [sourcecode] puppet.my.domain
так же нам понадобится внести изменения в нашу dns-зону my.domain (если она у нас есть) добавив туда соответствующую символьную A-запись. В противном случае на всех наших серверах правим /etc/hosts приводя его к виду:
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4 ::1 localhost localhost.localdomain localhost6 localhost6.localdomain6 192.168.0.1 puppet puppet.my.domain 192.168.0.2 puppetdb puppetdb.my.domain
- Наконец делаем то, ради чего написана вся эта статья – ставим пакет puppetserver:
yum install puppetserver
- Так как всё это дело написано на ruby/java , оно очень прожорливо в плане системных ресурсов, значит сходу правим /etc/sysconfig/puppetserver увеличив минимальные значения:
########################################### # Init settings for puppetserver ########################################### # Location of your Java binary (version 7 or higher) JAVA_BIN="/usr/bin/java" # Modify this if you'd like to change the memory allocation, enable JMX, etc JAVA_ARGS="-Xms4g -Xmx4g -XX:MaxPermSize=1g" # These normally shouldn't need to be edited if using OS packages USER="puppet" GROUP="puppet" INSTALL_DIR="/opt/puppetlabs/server/apps/puppetserver" CONFIG="/etc/puppetlabs/puppetserver/conf.d" BOOTSTRAP_CONFIG="/etc/puppetlabs/puppetserver/bootstrap.cfg" SERVICE_STOP_RETRIES=60 # START_TIMEOUT can be set here to alter the default startup timeout in # seconds. This is used in System-V style init scripts only, and will have no # effect in systemd. # START_TIMEOUT=120
Тут нас интересует пока только JAVA_ARGS указывающий объём памяти отдаваемый демону и максимальное кол-во памяти потребляемое каждым тредом.
- Добавляем нашему серверу возможность автоподписи сертификатов. Все ноды, попавшие под определённую маску, будут автоматически признаны мастером своими клиентами и начнут попадать под манифесты написанные для них, если такие конечно же будут. Для этого создаём файл /etc/puppetlabs/puppet/autosign.conf с содержимым:
*.my.domain
То есть все сервера чей FQDN попадает под данную маску – будут нашими клиентами.
- Запускаем наш puppetmaster:
systemctl enable puppetserver.service systemctl start puppetserver.service
- В принципе, минимальный набор действий для работы master’а мы совершили. Можно убедиться что всё впорядке прочитав логи: /var/log/puppetlabs/puppetserver/
- На puppetserver’е установим необходимые модули для работы puppetdb. Вся прелесть этого способа в том, что нам даже не надо ставить каждый модуль отдельно, так как в puppet’е предусмотрена система зависимостей, а значит он самостоятельно удовлетворит все необходимые зависимости:
puppet module install puppetlabs-puppetdb
Смотрим что у нас получилось командой puppet module list:
/etc/puppetlabs/code/environments/production/modules +-- puppetlabs-apt (v2.2.2) +-- puppetlabs-concat (v2.1.0) +-- puppetlabs-firewall (v1.8.0) +-- puppetlabs-inifile (v1.5.0) +-- puppetlabs-postgresql (v4.7.1) +-- puppetlabs-puppetdb (v5.1.2) L-- puppetlabs-stdlib (v4.11.0) /etc/puppetlabs/code/modules (no modules installed) /opt/puppetlabs/puppet/modules (no modules installed)
- Теперь нам следует написать манифест, который установит и настроит всё это на нашем puppetdb сервере. Для этого создаём файл /etc/puppetlabs/code/environments/production/manifests/pmdb.pp следующего содержания:
$master_host = 'puppet.my.domain' $puppetdb_host = 'puppetdb.my.domain' node puppet.my.domain { # Here we configure the Puppet master to use PuppetDB, # telling it the hostname of the PuppetDB node class { 'puppetdb::master::config': puppetdb_server => $puppetdb_host, } } node puppetdb.my.domain { # Here we install and configure PostgreSQL and the PuppetDB # database instance, and tell PostgreSQL that it should # listen for connections to the `$postgres_host` class { 'puppetdb::database::postgresql': listen_addresses => $puppetdb_host, } class { 'puppetdb::server': database_host => $puppetdb_host, } }
Данный манифест содержит инструкции для двух нод: первая нода это наш puppetmaster которому мы говорим отсылать все данные facter’a нашей puppetdb и наоборот брать их оттуда при необходимости. Второй ноде puppetdb мы говорим установить postgresql и настроить его на работу с адресом puppetdb , так как у нас postgresql и puppetdb на одном хосте, затем установить и настроить аналогично puppetdb.
- Наконец-то на нашем puppetdb-сервере устанавливаем и настраиваем с помощью puppet’a всё необходимое одной командой:
puppet agent --debug --no-daemonize --onetime
- Подтюним немного настройки puppetdb отдав ему большую часть нашей ОЗУ приведя /etc/sysconfig/puppetdb к виду:
########################################### # Init settings for puppetdb ########################################### # Location of your Java binary (version 7 or higher) JAVA_BIN="/usr/bin/java" # Modify this if you'd like to change the memory allocation, enable JMX, etc JAVA_ARGS="-Xmx14g" # These normally shouldn't need to be edited if using OS packages USER="puppetdb" GROUP="puppetdb" INSTALL_DIR="/opt/puppetlabs/server/apps/puppetdb" CONFIG="/etc/puppetlabs/puppetdb/conf.d" BOOTSTRAP_CONFIG="/etc/puppetlabs/puppetdb/bootstrap.cfg" SERVICE_STOP_RETRIES=60 # START_TIMEOUT can be set here to alter the default startup timeout in # seconds. This is used in System-V style init scripts only, and will have no # effect in systemd. # START_TIMEOUT=300
- Теперь пришло время сказать нашему puppetserver’у настроиться на работу с puppetdb.
Для этого запустим агента: puppet agent --debug --no-daemonize --onetime
PostgreSQL/PuppetDB
Есть несколько способов установки postrgesql и puppetdb. По какой-то непонятной для меня причине, производитель рекомендует новичкам установку из пакетов. То есть нам сначала предлагают поставить postgresql и настроить его, что, я вам скажу, ни разу не просто, затем поставить пакетом puppetdb и так же его настраивать на работу с нашей БД. Второй способ – установка модулем puppetmaster’а и настройка puppet client’ом – это наш способ! Иначе, на кой ляд бы мы вообще ставили этот puppet, если собираемся делать его работу за него?
В результате всех этих действий мы получили рабочий puppet-сервис способный, по утверждениям разработчиков, выдерживать нагрузку от 500 машин. Впрочем, если вам интересно моё личное мнение, используйте лучше ansible, не портите себе жизнь как это сделал автор статьи.
В следующих статьях постараемся завести hiera вместо дефолтных манифестов puppet’a и возможно, если нам очень сильно повезёт, r10k для хранения конфигураций на git’е.
Всю прочую инфу можно найти на официальном сайте продукта.
ооо, vasya!
Ага, это ты со своими васями меня заразил 8D