![Puppet: Как использовать набор общих пакетов, но разрешить исключения?](https://rvso.com/image/658336/Puppet%3A%20%D0%9A%D0%B0%D0%BA%20%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D1%82%D1%8C%20%D0%BD%D0%B0%D0%B1%D0%BE%D1%80%20%D0%BE%D0%B1%D1%89%D0%B8%D1%85%20%D0%BF%D0%B0%D0%BA%D0%B5%D1%82%D0%BE%D0%B2%2C%20%D0%BD%D0%BE%20%D1%80%D0%B0%D0%B7%D1%80%D0%B5%D1%88%D0%B8%D1%82%D1%8C%20%D0%B8%D1%81%D0%BA%D0%BB%D1%8E%D1%87%D0%B5%D0%BD%D0%B8%D1%8F%3F.png)
У меня около 200 более или менее идентичных Linux VM. Для всех общих конфигураций есть класс:
class my_packages {
class { "::ntp":
servers => [ "de.pool.ntp.org" ],
}
....
}
который я включаю в каждый узел в site.pp.
Теперь я хочу запустить свой собственный локальный сервер времени, что тривиально с использованием пакета puppetlabs/ntp. Мне просто нужно заменить запись сервера в my_packages на IP-адрес новой виртуальной машины сервера времени, и эта виртуальная машина теперь имеет ту же запись класса ntp, которая ранее использовалась в my_packages.
node 'mytime' {
# include my_packages
class { '::ntp':
servers => [
'de.pool.ntp.org',
'ptbtime1.ptb.de',
'ptbtime2.ptb.de',
'ptbtime3.ptb.de',
],
}
...
}
Однако, поскольку запись класса "::ntp" теперь определена в узле, я не могу включить my_packages в запись узла для моей новой виртуальной машины сервера времени, поскольку в этом случае я получаю ошибку "Дублирующее объявление".
Аналогичная проблема возникла при использовании локального сервера имен. У каждой виртуальной машины есть файл /etc/resolv.conf, указывающий на локальный сервер имен, поэтому в my_packages есть файловый ресурс для этого. Но сам локальный сервер имен должен иметь другой файл /etc/resolv.conf — он не может указывать на себя, пока его установка не будет завершена, чего не происходит во время установки.
Какова наилучшая практика использования общего набора ресурсов, допускающая при этом исключения?
решение1
Если вы используете Puppet 3 или более позднюю версию, лучшим способом решения этой задачи будет использование hiera для выполненияавтоматический поиск параметров. Вкратце, он позволяет вам объявлять классы, используя синтаксис include, а не синтаксис в стиле ресурсов, что означает, что у вас может быть несколько объявлений для класса. Обратите внимание, что вы не можете смешивать объявления include и resource для класса.
Обычно, если вы используете синтаксис include для объявления класса, он терпит неудачу, если у него есть какие-либо обязательные параметры. Когда вы используете автоматический поиск параметров, puppet попытается найти значения параметров через hiera.
Hiera так названа, потому что она будет пытаться искать значения через иерархию источников данных. Вы можете указать эту иерархию в hiera.yaml, и она может сопоставлять различные факты (имя хоста, пользовательские факты и т. д.) или проверять жестко закодированные файлы.
Вот краткий пример, который может подойти в вашем случае:
Определение класса:
class my_packages {
include ::ntp
...
}
мое время.yaml:
----
ntp::servers:
- 'de.pool.ntp.org'
- 'ptbtime1.ptb.de'
- 'ptbtime2.ptb.de'
- 'ptbtime3.ptb.de'
общий.yaml:
---
ntp::servers: ['de.pool.ntp.org']
hiera.yaml:
...
:hierarchy:
- "${::fqdn}"
- common
...
В этом случае hiera попытается найти значение параметра servers в классе ntp, используя ключ ntp::servers. Сначала он будет искать этот ключ в любых файлах yaml, соответствующих имени хоста, а затем он будет искать в common.yaml.
В большинстве случаев он будет использовать ключ в common.yaml, но в случае с узлом mytime он найдет значение выше в иерархии и остановит поиск на нем.
Вот ссылка наполный пример, который, кстати, охватывает модуль ntp.