我在 Ubuntu 服务器上安装了 Puppet 3.1.1。
我的清单文件夹如下所示:
├── nodes
│ └── test1.pp
└── site.pp
site.pp的内容为:
# site.pp
import "nodes/*.pp"
节点test1工作正常。
然后我新建了一个名为的文件test2.pp
,内容和test1.pp一样,只是节点名不一样,然后我把它添加到nodes文件夹中。
因此清单文件夹变成了这样:
├── nodes
│ ├── test1.pp
│ └── test2.pp
└── site.pp
然后我puppet agent --test
在节点 test2 上运行。
代理可以与 Puppet Master 交换 SSL 密钥,但是我收到一条错误消息:
Could not find default node or by name with test2
如果我不创建新test2.pp
文件,而只是将内容添加到test1.pp
文件中,则不会出现错误。
因此,我认为 Puppet Master 启动后,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',
}
}
答案1
我建议从清单节点定义转移到 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: }
}
答案2
Shane 给出了一个很好的答案,并且提供了一个更好的方法来解决你的问题,但我想说的是,“所以我认为 Puppet 不会在 Puppet Master 启动后动态导入新的 pp 文件。”
这倒是真的。当 Puppet 启动时,它会读取所有配置文件,然后开始监视这些文件是否有变化。当其中一个文件的内容更新时,Puppet 会重新读取该文件。Puppet 还为文件设置了一组标准位置,它会在需要时查阅这些位置,因此,如果您向其foo::bar
监视的文件中的节点添加新类,它会在其 中查找名为foo/manifests/bar.pp
(或foo/manifests/bar.rb
)的文件$modulepath
,即使它在启动时并不需要该文件。
重要的是,import
指令仅在解析其所在的文件时才会被评估。当 Puppet Master 启动时,它会读取其site.pp
文件,查看import
语句,并只找到nodes/test1.pp
,因此它监控更改的唯一文件是site.pp
和nodes/test1.pp
。它从未看到过nodes/test2.pp
。
解决此问题的一个方法是touch site.pp
将新文件添加到nodes
目录后简单地执行。这将导致 Puppet Master 重新读取site.pp
,从而导致它重新处理该import
语句,然后它将看到新文件。
但从长远来看,你最好遵循 Shane 的建议,将数据与代码分开。如果你可以构造你的定义,使其不需要语句import
,那么你会更好;它仍然有用,但在很多方面,import
它是不再相关的旧 Puppet 实践的遗留。