使用主机资源

I am not a number.

"The Prisoner" — Number Six

将机器搬来搬去是很常见的做法,尤其是在云的基础设施中搬动,所以一个特定主机的 IP 经常会改变。 正因为如此,在你的配置中使用硬编码的 IP 地址显然是个坏主意。 如果一台机器要访问另一台(例如,一个应用服务器需要访问一台数据库服务器), 那么使用主机名而不是 IP 地址会更好。

然而,如何映射主机名到 IP 地址呢?这通常会使用 DNS,但小型组织里一般没有 DNS 服务器, 而大型组织要想无困扰地实现 DNS 更新也是相当费时的。 此外,将 DNS 信息传播到不同机器也需要不同的时间,因此确保快速而一致的 IP 地址更新的一种方法是使用由 Puppet 管理的本地主机表文件 /etc/hosts 中的条目。

操作步骤

  1. 添加如下代码到你的配置清单:

    host { "www.bitfieldconsulting.com":
        ip     => "109.74.195.241",
        target => "/etc/hosts",
        ensure => present,
    }
    
  2. 运行 Puppet:

    # puppet agent --test
    info: Retrieving plugin
    info: Caching catalog for cookbook.bitfieldconsulting.com
    info: Applying configuration version '1305716418'
    
    notice: /Stage[main]//Node[cookbook]/Host[www.bitfieldconsulting.
    com]/ensure: created
    
    info: FileBucket adding /etc/hosts as {md5}977bf5811de978b7f041301
    9e77b4abe
    
    notice: Finished catalog run in 0.21 seconds
    

工作原理

Puppet 将检查由 target 指定的文件,若主机条目不存在,Puppet 就会添加此条目; 若主机条目存在但 IP 地址不同,Puppet 就会更新此条目。

虽然可以使用有别于 /etc/hosts 的目标文件,但这是默认值,你只需要一个目标文件 (即不能使用数组同时指定多个文件)。 我认为明确地指定 host 资源的默认值是个很好的做法, 因为依托默认的行为会有使代码变得脆弱的倾向。

更多用法

将你的 host 资源组织到类中会对你有帮助。例如,你可以将所有数据库服务器的 host 资源放置在一个名为 admin::dbhosts 的类中,然后在所有的 web 服务器中包含这个类。

一些主机可能需要在多个类中同时定义(例如,一个数据库服务器也可以是一个仓库服务器), 使用虚拟资源可以解决这个问题。例如你可以像下面这样, 在一个单独的类中将所有的主机定义成虚拟资源:

class admin::allhosts
{
    @host { "db1.bitfieldconsulting.com":}
}

然后在不同的类中 realize 你需要的主机:

class admin::dbhosts
{
    realize( Host["db1.bitfieldconsulting.com"] )
}

class admin::repohosts
{
    realize( Host["db1.bitfieldconsulting.com"] )
}