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

Как устроен Puppet и когда он оправдан

Архитектура классическая: Puppet Server компилирует каталог для каждого узла, агент на машине применяет ресурсы и отправляет отчёт. Каталог строится из манифестов, шаблонов и данных Hiera. Ресурс описывает тип объекта — пакет, файл, службу, пользователя — и его параметры. Порядок внутри каталога задаётся зависимостями, а не порядком строк, поэтому важно явно связывать ресурсы через require, before, notify и subscribe.

Puppet выгоден, когда серверов десятки и нужна единая точка правды, аудит и воспроизводимость. Для одной машины или пяти контейнеров обычно хватает Ansible: Puppet требует сервера, сертификатов и дисциплины в данных, зато в большом парке даёт централизованные отчёты.

Установка Puppet Server и агента

Для Debian 12 Puppet распространяет собственный репозиторий. Пакет puppet8-release-bookworm.deb подключает ветку Puppet 8; для другой ОС имя файла отличается, поэтому сверяйтесь с официальным репозиторием. Серверу нужны стабильное имя, точное время и открытый порт 8140.

wget https://apt.puppet.com/puppet8-release-bookworm.deb
sudo dpkg -i puppet8-release-bookworm.deb
sudo apt update
sudo apt install puppetserver puppet-agent

После установки создайте CA и запустите службу. Puppet Server использует память Java; на стенде лимит можно уменьшить в /etc/default/puppetserver, а для production — 4 ГБ и больше. Убедитесь, что порт слушается.

sudo /opt/puppetlabs/bin/puppetserver ca setup
sudo systemctl enable --now puppetserver
sudo /opt/puppetlabs/bin/puppet --version
sudo ss -ltnp | grep 8140

На управляемой машине установите агент и пропишите certname с адресом сервера в /etc/puppetlabs/puppet/puppet.conf. Имя certname должно совпадать с FQDN либо быть явно задано на сервере.

[main]
certname = web01.example.lan
server = puppet.example.lan
environment = production
runinterval = 30m

Первый запуск создаёт запрос на сертификат. На сервере подпишите нужный узел и повторите запуск. Не включайте автоподпись в сети с посторонними устройствами.

sudo /opt/puppetlabs/bin/puppet agent -t
sudo /opt/puppetlabs/bin/puppetserver ca list --all
sudo /opt/puppetlabs/bin/puppetserver ca sign --certname web01.example.lan
sudo systemctl enable --now puppet

Первый манифест: пакет, файл и служба

Начните с профиля, который ставит nginx, кладёт конфигурацию из шаблона и держит службу запущенной. Ключевая деталь — notify: изменение файла перезапускает службу только при реальном изменении содержимого. Шаблон EPP получает переменные явно.

class profile::nginx {
  package { 'nginx':
    ensure => installed,
  }

  file { '/etc/nginx/conf.d/site.conf':
    ensure  => file,
    owner   => 'root',
    group   => 'root',
    mode    => '0644',
    content => epp('profile/nginx-site.epp', {
      'server_name' => $facts['networking']['fqdn'],
    }),
    notify  => Service['nginx'],
  }

  service { 'nginx':
    ensure => running,
    enable => true,
  }
}

Проверка синтаксиса и пробный прогон обязательны. puppet apply --noop показывает будущие изменения, не трогая систему; на агенте используйте puppet agent -t --noop.

sudo /opt/puppetlabs/bin/puppet parser validate manifests/site.pp
sudo /opt/puppetlabs/bin/puppet epp validate templates/profile/nginx-site.epp
sudo /opt/puppetlabs/bin/puppet agent -t --noop
sudo /opt/puppetlabs/bin/puppet agent -t

Роли и профили вместо свалки в site.pp

Паттерн roles and profiles разделяет ответственность. Профиль описывает одну технологию, роль собирает профили для типа сервера, а узел в site.pp получает только роль. Это упрощает повторное использование и борьбу с копипастой.

class role::web {
  include profile::base
  include profile::nginx
  include profile::php
}

node 'web01.example.lan' {
  include role::web
}

Модули храните в отдельном репозитории с metadata.json. Для доставки окружений подойдёт r10k: он читает Puppetfile, скачивает модули из git и раскладывает по environments. Команда r10k deploy environment -p обновляет их перед запуском агента.

mod 'puppetlabs/stdlib', '9.6.0'
mod 'puppetlabs/nginx', '8.0.0'
mod 'our/profile', git: 'https://git.example.lan/puppet/profile.git'
sudo r10k deploy environment -p

Версии модулей фиксируйте: ветка main однажды принесёт несовместимое изменение. Собственные модули фиксируйте тегом или коммитом, обновляйте через отдельное окружение.

Hiera: данные отдельно от логики

Параметры, которые различаются между средами и узлами, выносите в Hiera 5. Иерархия включает общие данные, данные окружения и узла; приоритет идёт сверху вниз. Секреты не храните в git — используйте eyaml или внешнее хранилище.

version: 5
defaults:
  datadir: data
  data_hash: yaml_data
hierarchy:
  - name: "Per-node data"
    path: "nodes/%{facts.networking.hostname}.yaml"
  - name: "Common data"
    path: "common.yaml"
profile::base::admin_users:
  - ops
  - deploy
profile::nginx::worker_processes: 4

В манифесте значение читается функцией lookup с типом и значением по умолчанию: каталог не упадёт, если данных ещё нет.

$workers = lookup('profile::nginx::worker_processes', Integer, 'first', 2)
file { '/etc/nginx/nginx.conf':
  ensure  => file,
  content => template('profile/nginx.conf.erb'),
  notify  => Service['nginx'],
}

Диагностика типичных сбоев

Большинство проблем связано с сертификатами, путями и порядком применения. Начните с конфигурации агента и журнала сервера, затем повторите запуск с отладкой.

  • Агент не видит сервер: проверьте puppet config print server, DNS и ss -ltnp | grep 8140.
  • Ошибка проверки сертификата: чаще всего рассинхронизировано время; сверьте timedatectl и перевыпустите сертификат.
  • Класс не найден: модуль отсутствует в modulepath или повреждён metadata.json.
  • Файл обновился, служба не перезапустилась: нет notify либо службой управляет другой ресурс.
  • Каталог не компилируется: смотрите journalctl -u puppetserver и запускайте агент с --debug.
  • Запуск слишком долгий: ищите exec без unless и onlyif, а также лишние ресурсы.
sudo /opt/puppetlabs/bin/puppet config print server certname modulepath
sudo /opt/puppetlabs/bin/puppet agent -t --debug --verbose
sudo journalctl -u puppetserver -n 100 --no-pager
sudo /opt/puppetlabs/bin/puppetserver ca list --all

Чек-лист перед production

  • Время синхронизировано на сервере и агентах, порт 8140 доступен только из доверенных сетей.
  • CA и закрытые ключи лежат вне git, доступ к ним ограничен.
  • Все модули зафиксированы по версиям, обновление проходит через отдельное окружение.
  • Секреты вынесены в eyaml или внешнее хранилище, а не в common.yaml.
  • Есть резервная копия /etc/puppetlabs и план восстановления сервера.

Итог

Puppet оправдывает себя там, где важны повторяемость и контроль парка серверов. Начните с одного профиля и честного --noop, затем добавьте роли, Hiera и фиксированные версии модулей. Так вы сначала видите, что изменится, и только потом разрешаете применение. Главное — не превращать site.pp в свалку и хранить данные отдельно от логики.

Насколько публикация полезна?

Нажмите на звезду, чтобы оценить!

Средняя оценка 0 / 5. Количество оценок: 0

Оценок пока нет. Поставьте оценку первым.

Поделиться: Telegram ВКонтакте