创建去中心化的分布式 Puppet 架构
某些系统(尤其像 Mafia)在去中心化的分布式架构环境下运行良好。 使用 Puppet 的一个最常见的方法是运行一个 Puppetmaster 服务器, Puppet 客户端连接这个服务器并从它获取配置清单。 无论如何,你仍旧可以使用下面的方法直接针对配置清单运行 puppet apply
命令。 (通常会使用 -v
参数开启冗余输出模式, 这样就可以看到详细的执行过程):
# puppet apply -v manifest.pp info: Applying configuration version '1294313350'
你甚至可以直接在命令行上运行配置清单的代码片断:
# puppet apply -e "file { '/tmp/test': ensure => present }" notice: /Stage[main]//File[/tmp/test]/ensure: created
换言之,如果能安排合适的配置清单并分发到客户端,你就可以在 Puppet 客户端上直接执行它,而不必使用中心化的 Puppetmaster 服务器。 这将消除单台 Puppetmaster 服务器的性能瓶颈,也消除了单点故障。 与此同时,也避免了新增客户端时 SSL 证书签署以及证书交换的步骤。
将配置清单文件推送到客户端有多种实现方法, 显然 Git (或者其它版本控制系统,如 Mercurial 或 Subversion)能为你做绝大部分的工作。 你可以在本地编辑 Puppet 配置清单的本地副本,提交到 Git 并将更新推送到中心仓库, 然后从 Git 中心仓库自动将配置清单分发到客户机。
准备工作
如果你的 Puppet 配置清单还没有纳入 Git,请参考本章 使用版本控制 一节的操作步骤。
操作步骤
在客户端使用如下命令对 Puppet 仓库克隆一个裸仓库(裸仓库没有工作区,只包含
.git
目录中的所有内容):# git clone --bare ssh://git@repo.example.com/var/git/puppet
使用如下命令检出裸仓库内容到
/etc/puppet/
目录:# git archive --format=tar HEAD | (cd /etc/puppet && tar xf -)
使用 Puppet 命令执行
site.pp
文件# puppet apply -v /etc/puppet/manifests/site.pp info: Applying configuration version '1294313353'
一旦完成上面的工作,下一步就是配置仓库的自动推送将变动推送到客户端。 使用 Git 的 remote 命令可以实现此功能,即配置本地仓库的远程仓库别名。例如:
# git remote add web ssh://git@web1.example.com/etc/puppet
如果你有多个客户端, 可以为同一个远程别名添加多个 URL:
# git remote set-url --add webs ssh://git@web2.example.com/etc/puppet # git remote set-url --add webs ssh://git@web3.example.com/etc/puppet ...
或者像这样,简单编辑 Git 配置文件 (
.git/config
) :[remote "web"] url = ssh://git@web1.example.com/etc/puppet url = ssh://git@web2.example.com/etc/puppet url = ssh://git@web3.example.com/etc/puppet ...
现在你可以使用如下命令从 Git 中心仓库推送更新到任意一台(或一组)客户端:
# git push web
最后一步,每当客户端接收到从 Git 中心仓库的推送就应该更新它自己的
/etc/puppet
目录。你可以使用 Git 的postreceive
钩子来实现此功能。 在你的仓库中,创建一个名为hooks/post-receive
的文件并为其设置可执行权限(0755), 文件内容为:#!/bin/sh git archive --format=tar HEAD | (cd /etc/puppet && tar xf -)
工作原理
与连接 Puppetmaster 获取已经编译好的客户端配置清单不同, 使用这种方式每个客户端都要从本地副本编译自己的配置清单。 每当 Git 中心服务器推送一次更新(或者从 Git 仓库 checkout 检出)就会重新编译一次。 这大大高了网络带宽的利用率,因为客户端不必每次运行时都连接 Puppetmaster。 同时也消除了单点故障,因为客户端可以从任何分布式的 Git 仓库 (这些仓库的内容是由 Git 中心仓库自动推送的)获得更新。
使用基于 Git 的去中心化的分布式 Puppet 架构为你提供了一个非常灵活的处理方式。 你可以使用 SSH 密钥来配置访问控制,按需要允许每一个客户端或一组客户端的访问。 例如:用于数据库服务器的配置清单仅允许数据库组的机器访问获取。
当然还需要一些额外的配置工作,但对于大多数小型组织是没有必要的, 这种去中心化的 Puppet 部署方式提供了额外的灵活性,同时也适用于更为苛刻的权限控制环境。
更多用法
如果你希望每次中心仓库推送更新之后 Puppet 立即执行并应用更新, 可以编辑 post-receive
脚本来完成,或者执行你需要的其它的动作。 另外,你也可以手动运行 Puppet,还可以用 从 cron 运行 Puppet 一节描述的方法使用 cron
调度运行,但要记得是运行 puppet apply
, 而不是运行 puppet agent
。
使用基于 Git 的架构也存在一些缺点:不能使用 Puppet 提供的高级特性, 例如外部节点分类器(external node classifier)以及存储配置(stored configuration)等。 不管怎样,当你需要将 Puppet 的部署扩展到大量节点时,这是一种最简单的实现方式。
你可以在 Stephen Nelson-Smith 的这篇文章里找到更多更详细的关于这种架构的讨论,文章地址是: http://bitfieldconsulting.com/scaling-puppet-with-distributedversion-control 。
参见本书
本章的 使用 Passenger 扩展 Puppet 的部署规模 一节
本章的 使用版本控制 一节