首先,我们先从配置文件说起,下面的URL是Puppet的配置说明页面。http://docs.puppetlabs.com/references/latest/configuration.html
其中有一个值叫manifests, 用途是指定Puppet Master的Manifests入口,意思是说Master是从这个文件开始读取Manifests的。manifest
The entry-point manifest for puppet master.
Default:$manifestdir/site.pp
这个参数的默认值是$manifestdir/site.pp,这里的$manifestdir是什么呢?它也是Puppet的一个配置项,默认值是$confdir/manifests。讨厌的是里面又有一个$confdir变量,同样它也是配置项,默认值是/etc/puppet manifestdir
Where puppet master looks for its manifests.
Default:$confdir/manifests
confdir
The main Puppet configuration directory. The default for this setting is calculated based on the user. If the process is running as root or the user that Puppet is supposed to run as, it defaults to a system directory,but if it’s running as any other user, it defaults to being in the user’s home directory.
Default:/etc/puppet
所以Master默认情况下Manifests入口就是/etc/puppet/manifests/site.pp。它会读取这个文件来查找请求主机的节点的定义的类和资源。
一般情况下,我们建议让site.pp的内容为"import nodes/*.pp",这样,我们就在同级目录下创建一个nodes目录,并创建相应的pp文件来书写每个(组)节点的配置。
同样,我建议在节点pp文件中,只写节点有关的变量,具体的实现由加载不同的模块来完成。比如production.ppnodes /^web\d+\.xxx\.com$/ { $www_home="/data/www" include httpd include httpd::vhost}这样是指定所有web开头的主机安装Apache应用,并指定了$www_home变量的内容。
而Puppet是如何去加载httpd的类的呢?
http://docs.puppetlabs.com/puppet/3/reference/modules_fundamentals.html这篇文章写了Puppet模块的基本原理,推荐阅读。在上面的配置列表中,我们可以查到模块默认可以存在$confdir/modules和/usr/share/puppet/modules中,一般情况下,我们是保存在/etc/puppet/modules下。模块中的结构如下
其中manifests/init.pp要求定义同模块名相同的类,然后其它的pp文件中应使用my_module::other_class形式的类名。原因是nodes中声明加载的类会被::打散,用来告诉自动加载器如何从模块中找到对应的文件。
When a class or defined resource is declared, Puppet will use its full name to find the class or defined type in your modules. Names are interpreted as follows:
当类或自定义资源类型被声明时,Puppet将使用全名来查找它们在你的模块中的位置。查找过程如下:
The first segment in a name (excluding the empty “top” namespace) identifies the module.Every class and defined type should be in its own file in the module’s manifests directory,and each file should have the .pp fileextension.
名字中的第一节用来识别模块,每个类都应该在自己的文件夹下有一个manifests文件名字的pp文件
If there are no additionalnamespaces, Puppet will look for the class or defined type in the module’sinit.pp file.
Otherwise, Puppet will treat the final segment as the file name and any interior segments as a series of subdirectories under the manifests directory.
Thus, every class or defined type name maps directly to a file path within Puppet’s modulepath:
如此,所有的类或自定义类型都对应能找到一个文件
namefile pathapache/apache/manifests/init.ppapache::mod/apache/manifests/mod.ppapache::mod::passenger/apache/manifests/mod/passenger.ppNote again that init.pp alwayscontains a class or defined type named after the module, and any other.pp filecontains a class or type with at least two namespace segments. (That is, apache.pp wouldcontain a class named apache::apache.)
记住只有init.pp中定义与模块名相同的类,其它的类名都至少有::分隔的两节。
PS:Puppet对语法和manifests的检查没有那么的严格,比如说,你可以把你的配置都写进site.pp,也可以在init.pp中写多个类,但是为了管理方便,我还是建议你按照它的最佳实践来写。
多看文档,现在Puppet里还有不少坑没解决,多看才能尽量避开。例如,命名空间和自动加载文件里写了如下内容: Importantnote: Earlier versions of Puppet used namespaces to navigate nested class/type definitions, and the code that resolves names still behaves as though this weretheir primary use.Thiscan sometimes result in the wrong class being loaded. This is a major outstanding design issue (issue#2053) which will not be resolved in Puppet 3. Seebelow for a full description of the issue.