厨师:食谱不能依赖其他食谱的旧版本

时间:2016-02-06 03:21:41

标签: chef versioning cookbook

背景

注意:请注意我要使用0.0.3版本environment-cookbook的整个问题。

注2:我们之前从未遇到过这个问题。这是最近的,我们不知道是什么造成的。

1。 environment-cookbookenvironment-cookbook-machines

要构建域,我们有两本烹饪书:

  • 一个用于配置计算机environment-cookbook-machines
  • 一个用于域配置environment-cookbook

当我检查Chef-server时:

$ knife cookbook list -a | grep environment
environment-cookbook 0.0.3 0.0.4 0.0.5 0.0.6 0.0.7

查看company-environment-cookbook 0.0.3' metadata.json,我认为这取决于dir-library 0.13.6

"dependencies": {
  "dir-library": "= 0.13.6"
}

environment-cookbook 0.0.4 及更高取决于dir-library 0.13.7

"dependencies": {
  "dir-library": "=0.13.7"
}

2。 wrapper-domainwrapper-domain-machines

由于每个域都可以依赖于environment-cookbook的特定版本,我们分别为每个域使用包装器烹饪书

  • wrapper-domain-machines
  • wrapper-domain

检查metadata.json两个包装器显示对environment-cookbook 0.0.3的依赖关系(这是我想要的版本):

"dependencies": {
  "environment-cookbook": "= 0.0.3"
  ...
}

wrapper-domain-machines也显示对environment-cookbook-machines 0.0.3的依赖。

这些包装器食谱的Berksfile.lock如下所示:

GRAPH 
environment-cookbook (0.0.3)
    dir-library (= 0.13.6)
environment-cookbook-machines (0.0.3)  # Only here for wrapper-cookbook-machines
    dir-library (= 0.13.6)

3。依赖图

当我在berks wiz食谱上运行wrapper-domain-machines时,我会得到以下依赖关系图: enter image description here

一切都很精致。

问题

当我通过Hudson上的CI作业运行域构建时,我在日志文件的开头看到以下内容:

INFO: Using dir-library (0.13.6)
INFO: Using environment-cookbook (0.0.3)
INFO: Using environment-cookbook-machines (0.0.3)
INFO: Installing environment-cookbook (0.0.3) from chef-server-url
INFO: Using dir-library (0.13.6)

再远一点:

INFO: Run List is [recipe[wrapper-domain-machines::up-machines]]
INFO: Run List expands to [wrapper-domain-machines::up-machines]
INFO: Loading cookbooks [wrapper-domain-machines@0.0.2, dir-library@0.13.6, environment-cookbook-machines@0.0.3]

到目前为止一直很好。它使用版本0.0.3代表environment-cookbook0.13.6代表dir-library

稍后在构建期间:

INFO: Run List is [recipe[environment-cookbook::prepare_machine]]
INFO: Run List expands to [environment-cookbook::prepare_machine]
INFO: Starting Chef Run for domain.company.com
INFO: Running start handlers
INFO: Start handlers complete.
resolving cookbooks for run list: ["environment-cookbook::prepare_machine"][0m
INFO: Loading cookbooks [environment-cookbook@0.0.7, dir-library@0.13.7]

停止,什么?

信息:加载食谱[environment-cookbook@0.0.7,dir-library@0.13.7]

到目前为止我们尝试了什么

  1. 删除缓存的cookbook

    • .berkshelf/cookbooks
    • 删除食谱
    • 重新运行构建(从chef-server自动下载)
    • 仍然选择0.0.8
  2. 检查其他食谱中environment-cookbook的依赖关系:

  3. environment-cookbook删除并重新安装0.0.3的所有版本0.0.7:没有运气。

  4. 在重新运行之前清理厨师客户端和节点:没有运气。

  5. 问题

    • 为什么它会更改为最新版本的environment-cookbook (0.0.7),从而选择它的依赖关系dir-library (0.13.7)

    • 我该如何解决这个问题?

    • 将来如何避免这种情况?

    这对我们来说真的是一个阻碍。

    再向我解释一下,我将更新这篇文章。

1 个答案:

答案 0 :(得分:3)

我怀疑这与我们遇到的厨师有同样的问题。它归结为运行时版本控制,而不是编译时版本控制。

获得的经验:在大规模经营厨师时,运行时无限制的食谱版本很危险。

背景

您正在使用Berkshelf管理您的食谱依赖关系,这非常棒,并确保将正确的版本加载到厨师服务器中。微妙的问题是每个食谱都有自己的依赖树。在运行时,当您将多个cookbook添加到节点的运行列表时,Chef服务器必须计算一个新的依赖树。问题可能看起来是随机的,因为它取决于您在运行列表中的烹饪书组合。烹饪书越多,冲突的可能性就越大。

我们尝试通过显式设置我们的cookbook元数据文件的依赖项来解决此问题。我们发现,Chef会默默地无法解析某些cookbook的依赖关系树,并默认返回旧计算版本,它会计算依赖关系。非常令人费解。

当我们开始在运行列表中明确设置cookbook的版本时,我们更接近问题了。我们开始收到厨师无法解决依赖关系的错误消息。特别奇怪的是,这个问题影响了我们的生产厨师服务器。我们最终确定这是因为在生产中我们已经装载了所有历史版本的烹饪书。清除旧食谱有所帮助,但没有解决我们的问题。

在我们发现这些问题之前,厨师已经工作了近两年。时间和规模暴露了我们系统中的致命缺陷。在运行时,您需要修复烹饪书的版本以匹配您之前测试的配置。

分析

来自Java背景我将问题等同于我们如何在tomcat服务器上运行多个应用程序。

Maven是一个构建工具,它管理每个应用程序依赖项并创建一个用于上传到tomcat的包。在厨师中,Berkshelf充实了这个功能。

最大的区别在于运行时。 Tomcat为属于每个应用程序的jar创建一个单独的类路径。这在运行时提供了应用程序之间的强大隔离,安全地允许它们运行相同cookbook的不同版本。这是Chef面临的一个不可能解决的问题,在运行时,chef-client只运行一套cookbook。

解决方案

虽然我不是政策文件的粉丝,但我将它们作为Chef青睐的选项。

政策文件

虽然大多数用户都不知道正在解决的问题,但是大厨已经开发了一项名为策略文件的新功能:

简而言之,他们正在做的是在编译时提前设置节点运行列表。

政策文件的一大好处是它们可以加快厨师的运行速度。厨师服务器不再需要弄清楚大型依赖树,这对于拥有大量烹饪书的厨师装置来说可以大大节省。

环境食谱模式

就个人而言,我并不是政策文件的粉丝,因为我已经发现了环境食谱模式,这是一个很难理解但功能强大的厨师特色:

现在,每次配置cookbook时,我总是使用Chef环境。在厨师中提供隔离的自然方式(我是否指出它很难理解)。这是使用berkshelf的一个例子:

berks upload 
berks apply my_app_cookbook_version1

非常方便"适用"命令将使用Berkshelf锁定文件更新环境中的cookbook版本" my_app_cookbook_version1"。现在,您已经修复了运行时间以匹配您的测试条件。

当然,结果是每个应用程序都有一个环境:

  • my_app_cookbook_version1
  • my_app_cookbook_version2

这对我来说实际上是一个奖励,因为它使我能够针对我已经测试过的东西引导基础设施:

knife bootstrap --environment my_app_cookbook_version1 ...

它创造了可预测性,意味着加载新的烹饪书不会在生产中神奇地改变我的服务器。

奖励是环境提供正在使用的食谱版本的记录,以及设置与部署相关的覆盖属性的便利位置,例如" app_owner"," app_version"等。

长期发帖道歉。