人偶收录与课程和最佳做法

Puppet Include vs Class and Best Practices

何时应该使用include与类声明?我现在正在探索创建一个概要文件模块,但是在方法论和如何布局方面苦苦挣扎。

有一些背景知识,我使用的是puppet-labs java模块,可以在这里找到。

我的./modules/profile/manifests/init.pp看起来像这样:

1
2
3
4
5
6
7
8
9
class profile {

  ## Hiera Lookups
  $java_version = hiera('profile::jdk::package')

  class {'java':
    package => $java_version,
  }
}

这很好用,但是我知道我也可以删除代码的class {'java':块,而改为使用include java。我的问题与两件事有关。一个,如果我出于任何原因想要使用include语句,如何将软件包版本从hiera传递给它?其次,是否有首选的方法可以做到这一点?是我真的不应该使用的东西,还是每种方法都有优点和缺点?

我的长期目标是为自己的环境构建个人资料(例如模块)。可能我会有一个适用于所有服务器的默认配置文件,然后是适用于不同应用程序负载的配置文件。我可以将概要文件包含到角色中,然后将其应用于该级别的各个节点。这有意义吗?

谢谢!


When should I be using an include vs a class declaration?

如果一个类声明了另一个属于同一模块的仅供内部使用的类,则可以考虑使用类似资源的类声明。这将利用您对模块的实现细节的了解,因为您需要能够证明不会在类资源声明之前评估任何其他有关该类的声明。如果违反了该约束,则目录构建将失败。

在所有其他情况下,应使用include或其同级之一requirecontain

One, if I wanted to use an include statement for whatever reason, how
could I still pass the package version from hiera to it?

与通过Hiera指定任何其他类参数的方式完全相同。我已经为您回答了。

Second, is
there a preferred method of doing this?

是的,请参见上文。

Is the include something I
really shouldn't be using, or are there advantages and disadvantages
to each method?

include是您应该使用的。这是您的默认设置,在某些情况下可以使用requirecontain作为替代。当Puppet团队在Puppet 2.6中首次引入它时,类似资源的声明语法似乎很不错,同时带有参数化类本身。但是事实证明,该语法在语言中引入了深层的设计问题,并且它是众多错误和头痛的来源。 Puppet 3中引入了自动数据绑定,以部分解决这些问题,从而使您无需使用类似资源的声明即可将值分配给类参数。

类资源的语法具有一个唯一的优势-如果您想将其视为一个优势-参数值直接在清单中表示。传统的Puppet智慧认为,最好将数据与代码分开,以免在配置要求更改时避免修改清单。因此,仅当您确信参数值永远不会改变时,才直接在清单中表达参数值是一个好主意。这种情况中最重要的类别是当一个类从外部源读取数据(即通过Hiera查找数据),并希望将这些值传递给另一个类时。

类资源的语法具有很大的缺点,即如果在为给定目标节点构建目录的过程中在任何地方评估了给定类的类资源声明,那么它必须是该类的第一个声明,即评估。相比之下,可以评估相同类的任意多个包含类声明,而不是替代类资源声明或在其基础上进行评估。

类是单例,因此多个声明对目标节点的影响不比单个声明大。允许它们非常方便。但是,众所周知,Puppet清单的评估顺序很难预测,因此,如果清单集中某处有给定类的类似资源的声明,则在一般情况下很难确保它是该清单的第一个声明被评估的类。在我上面描述的特殊情况下,可以解决该困难。这属于评估顺序依存关系的更一般类别,您应注意确保清单集不包含这些内容。

类似资源的语法还有其他问题,但没有一个像评估顺序相关性那么重要。

关于自动数据绑定的澄清

上面提到的

自动数据绑定将标识类参数的键与那些参数的对应值相关联。如果后端支持复合值,则支持这些值,而默认的YAML后端实际上支持复合值。您对这个答案的评论表明您尚未完全理解这些细节,尤其是您还没有意识到识别(整个)类参数的键的重要性。

我以您的类为例,该类一方面可以通过类似于资源的声明进行声明:

1
2
3
class { 'elasticsearch':
  config => { 'cluster.name' => 'clustername', 'node.name' => 'nodename' }
}

要改用类似include的声明,我们必须在Hiera数据中为类的" config"参数提供一个值。该值的键将是elasticsearch::config(<完全合格的类名> :: <参数名>)。关联的值在人偶侧需要作为散列(也称为"关联数组",也称为" map"),因此,这就是在YAML格式的Hiera数据中指定的方式:

1
2
3
elasticsearch::config:
   "cluster.name":"clustername"
   "node.name":   "nodename"

如果有多个条目,则该值的哈希性质会更清楚。如果您不熟悉YAML,那么至少略读底漆可能值得您花些时间,例如yaml.org上的那个。

有了这些数据之后,我们现在可以简单地通过

在Puppet清单中声明该类。

1
include 'elasticsearch'