我想知道在 Puppet 中覆盖变量的最佳实践是什么。我希望所有节点(位于不同位置,其中一些是 qa,一些是实时)具有相同的类。现在我有这样的内容:
class base_linux {
<...> # something which requires $env and $relayhost variables
}
class linux_live {
$relayhost="1.1.1.1"
$env = "prod"
include base_linux
}
class linux_qa {
$relayhost="2.2.2.2" # override relayhost
include base_linux
}
class linux_trunk {
$env = "trunk" # override env
inlude linux_qa
}
node "trunk01" {
include linux_trunk
include <something else>
}
node "trunk02" {
$relayhost = "3.3.3.3" # override relayhost
include linux_trunk
include <something else>
}
node "prod01" {
include linux_prod
}
因此,我希望在 base_linux 中有一些默认值,可以被 linux_qa/linux_live 覆盖,又可以在更高级别的类和节点定义中覆盖。
当然,它不起作用(并且预计不会起作用)。它也不适用于类继承。也许我可以使用全局范围变量进行存档,但对我来说这似乎不是一个好主意。
解决这个问题的最好方法是什么?
答案1
最佳实践取决于您管理的节点/系统的数量。如果您可以跟踪数据,那么在 Puppet 清单中建模数据就足够了(我见过数千个系统这样做,但是如果您有大量变量和深度继承,特别是当您开始按范围引用时,例如 $value = $some_class::some_var,这将变得具有挑战性)。如果您拥有复杂的基础架构,那么使用 extlookup、heira 或外部节点分类器 (ENC) 将数据与 Puppet 清单分离是有意义的。
您在 Puppet 清单中执行此操作的方式是使用动态作用域和节点继承,而动态作用域在 Puppet 2.7 中已被弃用。如果在 extlookup 中重写,它将只是:
# configured globally
# linux_qa is more likely linux_%{env}
$extlookup_precedence = ["%{fqdn}", "linux_trunk", "linux_qa", "common"]
# in the appropriate class
$relayhost = extlookup("relayhost")
答案2
看来我找到了一个好办法:与其在类中定义变量,不如制作只包含变量的节点模板。因此,我最终得到了类似下面的代码:
node basenode {
}
node linux_prod inherits basenode {
$relayhost="1.1.1.1"
$env = "prod"
}
node linux_qa inherits basenode {
$relayhost="2.2.2.2"
}
node linux_trunk inherits linux_qa {
$env = "trunk"
}
class base_linux {
# no valuables defined here
<...>
}
node trunk01 inherits linux_trunk {
$relayhost = "3.3.3.3" # I can override here for single node
include base_linux
}
答案3
我自己的建议是不要将变量放在类上——只有当该类需要覆盖某些东西时才可以。
将您的变量放入 site.pp(或某个导入文件 - 我将我的文件命名为 globals.pp)中,放入规则以辨别它们应具有的值 - 选择而不是覆盖。然后,您可以根据需要对节点或类进行单独的覆盖。