Puppet:如何使用一组通用的包但允许例外?

Puppet:如何使用一组通用的包但允许例外?

我有大约 200 个或多或少相同的 Linux VM。所有常见配置都有一个类:

class my_packages {

    class { "::ntp":
        servers     => [ "de.pool.ntp.org" ],
    }
    ....
}

我将其包含在 site.pp 中的每个节点中。

现在我想运行自己的本地时间服务器,使用 puppetlabs/ntp 包即可轻松完成。我只需将 my_packages 中的服务器条目替换为新时间服务器 VM 的 IP 地址,该 VM 现在具有与之前在 my_packages 中使用的相同的 ntp 类条目。

node 'mytime' {

#    include my_packages

    class { '::ntp':
        servers => [
            'de.pool.ntp.org',
            'ptbtime1.ptb.de',
            'ptbtime2.ptb.de',
            'ptbtime3.ptb.de',
        ],
    }
    ...
}

但是,由于类“::ntp”条目现在已在节点中定义,我无法将 my_packages 包含在新的时间服务器 VM 的节点条目中,因为在这种情况下会出现“重复声明”错误。

使用本地名称服务器时也出现了类似的问题。每个虚拟机都有一个指向本地名称服务器的 /etc/resolv.conf 文件,因此 my_packages 中有一个该文件资源。但本地名称服务器本身必须有一个不同的 /etc/resolv.conf 文件 - 它在安装完成之前不能指向自身,而在安装过程中则不是这种情况。

使用一组通用资源但允许偶尔出现例外的最佳做法是什么?

答案1

如果你使用的是 Puppet 3 或更高版本,最好的方法是使用 hiera 来执行自动参数查找。简而言之,它允许您使用包含语法而不是资源样式语法来声明类,这意味着您可以对类进行多次声明。请注意,您不能混合使用包含和资源样式声明。

通常,如果您使用 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 会尝试使用键 ntp::servers 查找 ntp 类中 servers 参数的值。它会首先在与主机名匹配的任何 yaml 文件中查找该键,然后在 common.yaml 中查找。

在大多数情况下,它会使用 common.yaml 中的键,但在 mytime 节点的情况下,它会在层次结构中找到更高级别的值并停止在那里查找。

以下是完整示例,它恰好涵盖了 ntp 模块。

相关内容