我有一台 Chef 服务器管理着一些节点。该服务器有包含各种机密的配方和数据包。我想对其中一个配方进行更改,并仅在单个节点上进行测试:我不希望其他节点更新和使用修改后的配方。
我探索过的解决方案:
测试厨房等等
测试很好,但如果没有数据包和 chef 服务器特有的其他东西,有些细节我无法测试。
将代码 rsync 到 /var/chef/cache/cookbooks
然后运行chef-client --skip-cookbook-sync
这次失败是因为我的食谱源代码缺少metadata.json
和其他各种东西。
更新食谱版本,上传,编辑节点的运行列表
协调多个开发人员之间的并发工作非常困难(特别是如果测试持续几天或几周)。还有几个环境超出了我的控制范围,我不能真的假设它们都锁定在我想要修改的食谱的特定版本上。
重命名食谱,上传到服务器,将替代角色应用于节点
这是我目前使用的解决方案。这很繁琐,因为更改食谱名称会更改其定义的任何资源的名称,所以我必须对食谱进行大量编辑。维护备用角色集以使用重命名的食谱也是一件烦人的事情。
答案1
我通过将食谱版本设置为 0.0.1 之类的版本并将目标环境锁定到该版本来处理这个问题 - 这避免导致每个拥有解锁环境的人采用新的食谱。
如果您需要它真正成为特定节点,您可以创建一个“依赖于”特定 0.0.1 食谱的虚拟食谱,并将该配方作为附加运行列表条目分配给节点。只要环境的 pin 允许较旧的食谱(即 <= xyz 而不是 = xyz),它就会强制该节点使用特殊食谱。
另外,查看 test-kitchen + chef-zero 来测试厨房内的服务器功能。
答案2
如果你的测试确实持续数周,你可能会考虑应用软件工程领域的成功想法,例如功能切换。这样,您就可以使用通过 Chef 中的角色属性或标签实现的切换功能在旧/新代码之间切换。
然而,我们也会不时地翻转特定节点的环境,并限制生产到版本latest - 1
,我目前正在尝试以下内容,以简化具有相同设置的多个环境的使用(不能保证它真的运行良好,我还没有在生产中尝试过):
# environments/production.rb
name "production"
env_cookbook_versions = {
"mysql" => "<= 6.0.18",
"extra-constrained" => "= 1.1.2"
}
env_default_attributes = {}
eval File.read("production_settings.rb")
此文件(我通过 上传knife environment from file
)包含一些特定的约束,这些约束不适用于其他环境,例如pre-production
,没有extra-constrained
食谱的版本引脚。
最后,production_settings.rb
(所有这些环境之间的共同部分(对我来说,我只说production
和pre-production
,没有更多了))看起来像这样:
# environments/production_common.rb
env_cookbook_versions["foo"] = "= 0.0.1"
cookbook_versions(env_cookbook_versions)
env_default_attributes.merge!({
"rabbitmq" => {
"server" => "mq.example.org"
},
"base" => {
"flags" => {
"production" => true
}
}
})
default_attributes(env_default_attributes)
如您所知,在搜索同一环境中的其他节点时,您必须小心谨慎。此外,我并不完全确定所有这些是否实际上都有效。production_settings.rb
一旦发生更改,您必须确保每个依赖的环境都已上传。但也许这能给你一些启发。
顺便说一句,关于不使用 Chef-Server 的可测试性:我很少遇到无法使用 test-kitchen 测试的东西。你知道你也可以添加数据包还有其他假货节点到你的菜谱中测试使用此类搜索查询的代码?