Настало время занимательных историй вместе с r10k. Давайте сначала узнаем, что же это за зверь и зачем он нужен?
По мнению разработчиков:
R10k provides a general purpose toolset for deploying Puppet environme
nts and modules. It implements the Puppetfile format and provides a native implementation of Puppet dynamic environments
По-моему сугубо личному мнению:
r10k – это просто бесполезный костыль с очень ему подходящим именем (Robot 10000 killer) написанный на ruby с монументально скудным функционалом.
NAME r10k - Killer robot powered Puppet environment deployment USAGE r10k <subcommand> [options] DESCRIPTION r10k is a suite of commands to help deploy and manage puppet code for complex environments. COMMANDS deploy Puppet dynamic environment deployment help show help puppetfile Perform operations on a Puppetfile version Print the version of r10k OPTIONS -c --config Specify a global configuration file --color Enable colored log messages -h --help Show help for this command -t --trace Display stack traces on application crash -v --verbose Set log verbosity. Valid values: fatal, error, warn, notice, info, debug, debug1, debug2
… вот собственно и всё, что он умеет. Конкретно из этого гигантского вывода help нам понадобится только deploy для разворачивания наших конфигов/модулей из git/svn, НО и даже тут не всё так гладко как хотелось бы.
Из минусов:
– Ruby и его гемы. Давайте смотреть правде в глаза, да эту штуковину можно написать хоть на bash’е потому что абсолютно всё, что она делает – скачивает из гита файлы и просто заменяет ими те, что в рабочей директории puppet’a. Но что делают разработчики? Они пишут его на тяжёлом ruby + установку поручают gem’у, то есть нам придётся при апдейте системы, апдейтить и этот дурацкий gem в том числе, либо ставить модуль zack-r10k и заставлять puppetmaster делать это за нас. Лично я ему апдейты не доверяю.
– Отсутствие системы контроля версий. Что это значит? А значит это, что ему нельзя сказать “Эй, друг, задеплой мне версию 952a65d9ea”, нет, он всегда будет деплоить последнюю версию.
– Отсутствие агента. То есть, чтоб нам задеплоить наши изменения, нам надо будет зайти на puppetmaster и сказать r10k deploy environment -p -v , однако есть костыльные решения комрадов: 1. Написание hooks (если есть свой git) либо webhooks; 2. Просто по крону гонять эту команду, НО и тут есть жирный минус который описан в предыдущем пункте, а именно – r10k не знает о том что в данный момент у нас на сервере самый свежий коммит, и запуская это по крону он будет его скачивать и заменять самим же собой снова и снова, тратя на это процессорное время и прочие важные ресурсы машины.
– Он может устанавливать модули, но не их зависимости. То есть, когда мы хотим поставить модулем, к примеру, банальный ntp, нам сначала надо найти его методату, глазами найти зависимости и руками указать ему их в конфиге. Но я ленивый админ, я не хочу делать это, это должна делать машина, иначе зачем она мне? Ладно, допустим я это сделаю, НО опять есть но… а что если я скажу ему ставить только последнюю версию модуля, а в последней версии автор добавит ещё одну зависимость? Ответ прост – у меня просто на всём серверном парке сломается ntp. То есть, я не могу ему доверить поддерживать модули в актуальном состоянии, мне придётся делать это самому.
Ну и конечно же плюсы:
+ Он очень прост в установке и использовании…
+ Может как git так и svn
+ Может устанавливать модули из реп puppetforge либо любых других
+ Поддерживает версионирование модулей (Не путать с манифестами!) то есть ему можно сказать в конфиге “Эй, r10k, установи такую-то версию, такого-то модуля”
Если вы дочитали до этого момента и до сих пор не передумали это устанавливать – вы сумасшедший. Впрочем, это рекомендуют сделать разработчики puppet, а значит и мы сделаем то же самое, ведь это серия Best Practice ;(
Установка
Для начала поправим /etc/sudoers изменив там Defaults на следующий:
Defaults secure_path = /sbin:/bin:/usr/sbin:/usr/bin:/usr/local/bin:/usr/local/sbin:/opt/puppetlabs/bin
Разработчик предлагает нам на выбор установку с помощью системного ruby, либо с помощью ruby уже “вшитого” в puppet. Разумеется мы выбираем первый вариант. Устанавливаем гемы и гит.
yum install rubygems git
Теперь можно установить и виновника сей статьи.
gem install r10k
Создадим необходимые каталоги и файлы для работы r10k.
mkdir -p /var/r10k/cache mkdir -p /etc/puppetlabs/r10k touch /etc/puppetlabs/r10k/r10k.yaml
Настроим этого маленького монстра редактировав для этого /etc/puppetlabs/r10k/r10k.yaml
# location for cached repos :cachedir: '/var/r10k/cache' # git repositories containing environments :sources: :base: remote: 'https://gitlab.com/vasya/puppet.git' basedir: '/etc/puppetlabs/code/environments' # purge non-existing environments found here :purgedirs: - '/etc/puppet/environments'
В remote у вас будет указана ваша репа, разумеется. Подробнее об этом ниже.
Чтоб нам где-то хранить наши конфиги, нам нужно это “где-то” организовать. Можно поднять приватный git, можно даже хоть на сервере с puppet’ом это сделать
git init --bare --shared=group /srv/puppet.git chgrp -R puppet /srv/puppet.git cd /srv/puppet.git git symbolic-ref HEAD refs/heads/production
НО я не заморачивался и просто создал репу на gitlab. Единственное что вам нужно будет сделать – переименовать branch master в production, потому что у этой штуки все ваши environments должны соответствовать именам веток в репе. То есть, допустим, у вас дефолтный environment production и есть ещё один для тестирования testing, соответственно в вашей репе будут аналогичные ветки production и testing.
В своём домашнем хомяке (vasya, – вы же не забыли что мы работаем из под него?) пишем:
git clone https://gitlab.com/vasya/puppet.git cd puppet git checkout -b production
Вместо https://gitlab.com/vasya/puppet.git у вас будет своя репа, как вы уже поняли. Создаём необходимые директории и файлы.
mkdir -p {modules,site/profile/manifests,hieradata/nodes} touch hieradata/common.yaml touch site/profile/manifests/base.pp touch environment.conf touch Puppetfile touch site.pp
Редактируем environment.conf
manifest = site.pp modulepath = modules:site
Редактируем site.pp внося туда одну единственную строку вместо всего того, что у нас там есть, которая будет говорить нашему puppet’у, чтоб он руководствовался исключительно hiera для всех нод.
hiera_include('classes')
И наконец самый главный файл Puppetfile – это конфиг того, что r10k будет ставить при деплое.
forge 'forge.puppetlabs.com' # Forge Modules mod 'puppetlabs/ntp', :latest mod 'puppetlabs/puppetdb', :latest mod 'puppetlabs/stdlib', :latest mod 'puppetlabs/apt', :latest mod 'puppetlabs/concat', :latest mod 'puppetlabs/firewall', :latest mod 'puppetlabs/inifile', :latest mod 'puppetlabs/postgresql', :latest # Local Modules mod 'tm', :local => true
Здесь мы объявили все модули которые мы используем, сказали, что хотим использовать только последнюю версию (Хоть я и зарекался это делать (см. минусы в начале)) и место откуда хотим их брать.
Как бонус к статье – создаём hieradata/common.yaml в котором укажем использование профиля по-умолчанию, он будет применяться ко всем нодам.
--- classes: - 'profile::base' ntp::restrict: - ntp::enable: true ntp::servers: - 0.ru.pool.ntp.org - 1.ru.pool.ntp.org
Создаём сам профиль site/profile/manifests/base.pp и записываем туда
class profile::base { class { '::ntp': } }
Не забываем про наши манифесты. Создаём из в hieradata/nodes
puppet.my.domain.yaml
--- # Declare our classes classes: - tm # Here is example our module "Test Module" via /etc/puppetlabs/code/environments/production/modules/tm tm::parameter_one: "There is no other way, and there never was. I lost in this place. Pls, i beg u, help me if u can"
и puppetdb.my.domain.yaml
--- # Declare our classes classes: - tm - puppetdb # After declare, work with it, we can transfer any var that supports to it puppetdb::globals::version: "latest" Here is example our module "Test Module" via /etc/puppetlabs/code/environments/production/modules/tm tm::parameter_one: "There is no other way, and there never was. I lost in this place. Pls, i beg u, help me if u can"
С этим вроде бы закончили… пришла пора первого коммита!
git checkout -b production git add * git commit -a -m "initital commit" git push -u origin production
Ответ здорового человека:
Username for 'https://gitlab.com': vasya Password for 'https://[email protected]': Counting objects: 3, done. Delta compression using up to 4 threads. Compressing objects: 100% (2/2), done. Writing objects: 100% (2/2), 211 bytes | 0 bytes/s, done. Total 2 (delta 1), reused 0 (delta 0) To https://gitlab.com/vasya/puppet.git 7bd8f3c..b78f485 production -> production Branch production set up to track remote branch production from origin.
Ну и собсно деплоим из гита наши изменения
sudo r10k deploy environment -p -v
На что он должен сказать что-то вроде
INFO -> Deploying environment /etc/puppetlabs/code/environments/production INFO -> Environment production is now at b78f4851629fb94209c41615d96f5fc15f8e950d INFO -> Deploying module /etc/puppetlabs/code/environments/production/modules/ntp INFO -> Deploying module /etc/puppetlabs/code/environments/production/modules/puppetdb INFO -> Deploying module /etc/puppetlabs/code/environments/production/modules/stdlib INFO -> Deploying module /etc/puppetlabs/code/environments/production/modules/apt INFO -> Deploying module /etc/puppetlabs/code/environments/production/modules/concat INFO -> Deploying module /etc/puppetlabs/code/environments/production/modules/firewall INFO -> Deploying module /etc/puppetlabs/code/environments/production/modules/inifile INFO -> Deploying module /etc/puppetlabs/code/environments/production/modules/postgresql INFO -> Deploying module /etc/puppetlabs/code/environments/production/modules/tm
Проверяем на нашем puppetdb
puppetdb vasya # sudo puppet agent --no-daemonize --onetime --verbose Info: Using configured environment 'production' Info: Retrieving pluginfacts Info: Retrieving plugin Info: Loading facts Info: Caching catalog for puppetdb.local Info: Applying configuration version '1468782923' Notice: /Stage[main]/Tm/File[/tmp/test_module]/ensure: defined content as '{md5}ef4186a646a01838b0427bdffeae7cc6' Notice: /Stage[main]/Ntp::Config/File[/etc/ntp.conf]/ensure: defined content as '{md5}2083e99dd158ddc605aff2a01a30ea5f' Info: Class[Ntp::Config]: Scheduling refresh of Class[Ntp::Service] Info: Class[Ntp::Service]: Scheduling refresh of Service[ntp] Notice: /Stage[main]/Ntp::Service/Service[ntp]: Triggered 'refresh' from 1 events Notice: Applied catalog in 2.10 seconds
Удивительно, но всё работает!
Мораль
r10k как самостоятельный продукт – бесполезен чуть менее чем полностью. Всё то, что он умеет и не умеет делать, может описать в bash-скрипте даже… автомеханик. Лично я бы поручил деплоинг и контроль версий специализированному продукту, например, jenkins‘у. Впрочем, это уже совсем другая история. (с)
Подскажите, пожалуйста, стоит ли использовать r10k на puppet 4, если у меня environments это отдельный проект в gitlab?
Лично я б Вам порекомендовал в 20!8 гэ использовать для этих нужд либо gitlab CI, либо jenkins, либо если у Вас нет времени с этим разбираться, то да, можно и vcsrepo. r10k не развивается, в гит не принимаются новые pull request’ы, они даже не могут реализовать установку модулей с их зависимостями, хотя я открыл этот feature request в момент написания этой статьи. В общем, как я и писал в статье, категорически рекомендую Вам воздержаться от использования r10k.
Или для этого случая достаточно будет vcsrepo?