我想让 puppet 在执行任何类型的更改之前运行特定命令。我知道prerun_command
主 puppet.conf 中的选项,但这不是我想要的。我希望该命令仅在即将发生更改时运行,而不是在每次 puppet 运行时运行。
场景如下。假设我在负载均衡器后面有一堆 Web 服务器。然后我想让 Puppet 更新网站文件。但为了防止某些文件已更新但其他文件未更新以及混合版本导致问题,我想将服务器从负载均衡器池中移除。
我可以编写一个脚本,在运行时会告诉负载均衡器从池中移除该服务器。然后 Puppet 可以进行更改,并postrun_command
在完成后将服务器放回池中。但我需要一种方法来运行该脚本以从池中移除服务器。
我能想到的唯一解决方案是在盒子上保留 2 个文件副本。一个是暂存副本,当 Puppet 更新该副本时,使用通知操作触发删除脚本,然后从暂存复制到实时位置。但我希望有一个更通用的方法,可以任何正在执行的更改(升级包、重新启动服务、创建用户等等)。
答案1
Puppet 的主要目的是配置管理也就是说,它将强制执行您声明的配置。您需要的是(根据您在问题中概述的场景)命令与控制。正如@Mike 指出的那样,fabric 是一种选择。我个人喜欢 Marionette Collective,因为它是 Puppet Labs 的产品,并且与 Puppet 内部组件(事实等)配合良好。
答案2
这是我的看法。。你可以在 puppet 中做到这一点,但我一直发现用 puppet 部署 webapps 非常麻烦。当然它可以工作,但当你需要快速恢复时会发生什么。用 puppet 不会发生这种情况。
我会研究像 fabric 这样的部署工具
http://docs.fabfile.org/en/1.4.3/index.html
它将允许您在所有 Web 节点上运行命令来处理部署。因此,在部署之前,您可以停止 Web 服务器,然后在部署结束后重新启动它。
编辑
这是一个简化的示例,说明你可以在 Puppet 中做什么
所以您有一个文件,但需要在更改文件之前执行一个命令?
file { "/path/to/file":
ensure => file,
require => Exec['command to run'],
}
因此,在需要更改文件之前将运行一个命令。
答案3
在尝试了几种不同的方法之后,包装脚本成为了我的最终解决方案。
puppet agent
每次运行后都会调用该脚本。
- 它设置一个用于查找的
FACTER_
环境变量。如果没有找到该变量,则会显示一条错误消息。init.pp
init.pp
fail()
- 脚本首先运行
puppet agent --noop --onetime --no-daemonize --verbose --color=false | grep -q ' (noop)$'
(它比这更智能一点,因为它还会检查puppet agent
运行中的错误代码。它也不能使用,--detailed-exitcodes
因为错误 6322。 - 如果上述内容与 匹配
(noop)$
,它会从负载均衡器中移除服务器,并再次运行 puppet(不带--noop
,而带有 )--detailed-exitcodes
。 - 如果运行以
0
或退出2
,则脚本会运行一些额外的检查以确保所有服务都正常运行,然后将该框放回负载均衡器中。