Я установил Puppet 3.1.1 на сервер Ubuntu.
Моя папка манифестов выглядела так:
├── nodes
│ └── test1.pp
└── site.pp
Содержание site.pp было:
# site.pp
import "nodes/*.pp"
Узел test1 работал нормально.
Затем я создал новый файл с именем test2.pp
. Содержимое было таким же, как у test1.pp, за исключением имени узла, и я добавил его в папку узлов.
Итак, папка манифестов стала такой:
├── nodes
│ ├── test1.pp
│ └── test2.pp
└── site.pp
Я тогда побежал puppet agent --test
на узле test2.
Агент мог обмениваться ключами SSL с мастером марионетки, но я получил сообщение об ошибке:
Could not find default node or by name with test2
Если я не создам новый test2.pp
файл и просто добавьте содержимое в test1.pp
файл, ошибка не появляется.
Поэтому я думаю, что Puppet не будет динамически импортировать новый файл pp после запуска мастера марионетки.
Можно ли определять узлы в отдельных файлах pp и динамически импортировать их?
Рад любым предложениям.
Содержимое двух файлов pp:
node 'test1' {
include tmp::params
tmp::gtp { 'node1':
name => 'node1',
version => '6.0.0.0',
ip => '168.1.193.97',
port => '1255',
}
}
node 'test2' {
include tmp::params
tmp::gtp { 'node2':
name => 'node2',
version => '6.0.0.0',
ip => '168.1.193.98',
port => '1255',
}
}
Я бы рекомендовал перейти от определений узлов манифеста к Hiera. Вам нужно будет немного настроить вещи, чтобы отказаться от вызова этого определенного типа непосредственно из вашего узла, но похоже, что он все равно не используется несколько раз в каталоге, поэтому преобразование в класс должно работать нормально.
Так что с hiera.yaml
как это..
---
:backends:
- yaml
:hierarchy:
- '%{::clientcert}'
- 'os-%{::osfamily}'
- common
:yaml:
:datadir: /etc/puppet/hieradata
И site.pp
с помощью всего:
hiera_include(classes)
..ваши узлы будут считываться из файлов YAML в /etc/puppet/hieradata
. Например, скажем, что вы хотите tmp::params
на каждом узле, сообщающем Puppet, но, возможно, вы захотите tmp::gtp
только на определенных узлах. И вы хотите централизованно определить version
параметр, но оставьте другие параметры для каждого узла. Итак, мы положим tmp::params
и version
параметр /etc/puppet/hieradata/common.yaml
:
classes:
- tmp::params
tmp::gtp::version: 6.0.0.0
Тогда у вас будет файл для каждого узла.
/etc/puppet/hieradata/test1.yaml
:
classes:
- tmp::gtp
tmp::gtp::name : node1
tmp::gtp::ip : 168.1.193.97
tmp::gtp::port : 1255
/etc/puppet/hieradata/test2.yaml
:
classes:
- tmp::gtp
tmp::gtp::name : node2
tmp::gtp::ip : 168.1.193.98
tmp::gtp::port : 1255
И да, он получит изменения в файлах Hiera без перезапуска службы. Кажется, примерно то, что вам нужно?
редактировать: чтобы использовать Hiera для настройки нескольких экземпляров определенного типа, вам нужно сделать что-то вроде этого:
/etc/puppet/hieradata/test1.yaml
:
classes:
- gtpsetup
gtp_instances:
- node1_instance1
- node1_instance2
gtp_instanceconfig:
node1_instance1:
ip : 168.1.193.97
port : 1255
version : 5.3.2.1
node1_instance2:
ip : 168.1.193.97
port : 1268
version : 6.0.0.0
/etc/puppet/modules/gtpsetup/manifests/init.pp
:
class gtpsetup {
gtp_instances = hiera('gtp_instances')
gtp_instanceconfig = hiera('gtp_instanceconfig')
define gtp_instance {
# this is using your existing defined type, but you can just move the stuff it's doing to here.
tmp::gtp { $title:
name => $title,
version => gtp_instanceconfig[$title]['version'],
ip => gtp_instanceconfig[$title]['ip'],
port => gtp_instanceconfig[$title]['port'],
}
}
gtp_instance { $gtp_instances: }
}
Шейн дал отличный ответ, предложив лучший способ решения вашей проблемы, но я хочу сказать: «Я думаю, что Puppet не будет динамически импортировать новый файл pp после запуска мастера марионеток».
Это отчасти правда. Когда Puppet запускается, он читает все свои файлы конфигурации, а затем начинает отслеживать их изменения. Когда содержимое одного из этих файлов обновляется, Puppet повторно прочитает файл. Puppet также имеет набор стандартных расположений для файлов, с которыми он будет обращаться при необходимости, поэтому, если вы добавите новый класс foo::bar
к узлу в файле, который он отслеживает, он будет искать файл с именем foo/manifests/bar.pp
(или foo/manifests/bar.rb
) в своем $modulepath
, даже если он не нуждался в этом файле при запуске.
Важно отметить, что import
директивы оцениваются только при анализе файла, в котором они находятся. Когда кукловод начал, он прочитал site.pp
файл, увидел import
заявление, и найдено только nodes/test1.pp
, поэтому единственными файлами, которые он отслеживал на предмет изменений, были site.pp
и nodes/test1.pp
. Он никогда не видел nodes/test2.pp
.
Одним из способов решения этой проблемы было бы просто touch site.pp
после добавления нового файла в nodes
каталог. Это заставит кукловода перечитать site.pp
, что приведет к повторной обработке import
заявление, и тогда он увидит новый файл.
Однако в долгосрочной перспективе вам лучше следовать рекомендациям Шейна и отделять данные от кода. Если вы можете структурировать свои определения так, чтобы import
заявление, вам будет лучше; он все еще имеет свое применение, но во многих отношениях import
это пережиток старых марионеточных практик, которые больше не актуальны.