如果我有一个软件系统对其他库有很多依赖,比如 libssl 或 libxml 等,我是否应该为每个库创建单独的食谱(使用实际上只有 2 行的配方)或者人们在食谱中做几个“包”块以确保依赖关系存在(而不是将这些包块拆分到他们的外部食谱中)?
答案1
如果您只需要安装包依赖项,您可以做一些简单的操作,如下:
%w{ package1 package2 package3 }.each do |pkg|
package pkg
end
或者您甚至可以创建一个属性并对其进行迭代。
属性/默认.rb:
default['app']['deps'] = [ "package1", "package2" ]
食谱/deps.rb:
node['app']['deps'].each do |pkg|
package pkg
end
第二种方法允许您通过覆盖来更新包列表。
您甚至可以将其添加到食谱中的单独食谱中,然后将其添加到引导 run_list 或应用程序角色中。
答案2
正如 CS3 所说,拥有数百本食谱只是为了安装一个应用程序,这确实不切实际。Chef 实际上使用系统的包管理器,可以自动为您解决依赖关系。
您想要分离依赖项的唯一原因是,如果您有一些特定的配置项,这些配置项可能会在系统之间发生变化,或者可能根据依赖于它的包而变化。
答案3
为了简单起见,我首先建议您直接在安装应用程序的手册中嵌入依赖项,例如安装 libssl-dev、libxml2-dev、libxslt-dev 等。
这种方法遇到麻烦的地方在于,如果您在同一映像上部署了两个不同的应用程序说明书,而这两个说明书都包含资源,例如,package "libssl-dev"
您会看到有关 CHEF-3694 资源克隆的警告。由于这两个说明书都包含同名的资源,因此您最终会遇到这个问题,在某个时候,我们确实希望这种情况消失,我们真的希望进入一个package "libssl-dev"
在 chef 运行中只定义一次的世界。
然后,您可以开始将这些依赖项收集到您的应用程序说明书都将包含的通用说明书中(如果它们对于您部署的每个应用程序来说都是相同的依赖项)。或者,您可以开始将它们分解为不同的应用程序子类型,或者非常明确地说明单一用途的说明书,例如 opscode xml 和 zlib 说明书。
我建议创建一个“平台”手册,收集您在所有平台上可能需要的各种杂项基础内容(安装 lsof、tcpdump、strace、zsh、htop 以及您通常需要的所有 -dev/-devel RPM 和 deb)。直到要安装的东西的列表变得太笨重,您才需要将其分解。
不过,所有这些都是有争议的,更细粒度的食谱的好处是,您可以更好地了解您的依赖关系,并且您的厨师运行应该拥有更少的资源并且规模更小。这有点像可管理性和精确性之间的权衡。作为最佳实践,您可能“应该”将它们全部分解。但如果太多的“应该”开始妨碍实际工作,那么我会合并。
Berkshelf 和 test-kitchen 以及对食谱进行适当的集成测试,使得拥有更小的单一用途食谱变得容易得多,但这有一个学习曲线,而且最好不要纠结于将 libssl-dev 安装到它自己的食谱中,直到你走得更远为止。