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

Chef: Cookbook can't depend on older version of other cookbook

背景

注意:请记住我想使用 environment-cookbook.

版本 0.0.3 的整个问题

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

1。 environment-cookbookenvironment-cookbook-machines

为了构建域,我们有两本食谱:

当我检查 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.3metadata.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,我们分别为每个域使用包装器说明书

检查两个包装器的 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 食谱上时,我得到以下依赖关系图:

一切正常。

问题

当我 运行 通过 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. 删除缓存的说明书

    • .berkshelf/cookbooks
    • 中删除食谱
    • 重新运行构建(自动从 chef-server 下载)
    • 还在捡0.0.8
  2. 检查其他食谱中对 environment-cookbook 的依赖性:NONE.

  3. 删除并重新安装 environment-cookbook0.0.30.0.7 的所有版本:运气不好。

  4. 重新运行之前清理 Chef 客户端和节点:也不走运。

问题

这对我们来说真的是一场表演赛。

请问我任何进一步的说明,我会更新这个 post。

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

经验教训:运行 时代的无约束食谱版本在 运行 规模化厨师时是危险的。

背景

您正在使用 Berkshelf 来管理您的 cookbook 依赖项,这很好,并且可以确保将正确的版本加载到 Chef 服务器中。微妙的问题是每本食谱都有自己的依赖树。在 运行 时,当您将多个食谱添加到节点的 运行 列表时,厨师服务器必须计算新的依赖关系树。该问题可能会出现在 运行dom 中,因为它取决于您在 运行 列表中的食谱组合。食谱越多,冲突的可能性就越大。

我们试图通过显式设置说明书元数据文件的依赖关系来解决此问题。我们发现,Chef 会默默地无法解析我们某些食谱的依赖关系树,并默认返回到它会计算依赖关系的旧版本。很费解。

当我们开始在 运行-list 上明确设置说明书的版本时,我们离问题更近了。我们开始收到 chef 无法解析依赖项的错误消息。特别奇怪的是,这个问题对我们的生产厨师服务器影响最大。我们最终确定这是因为在生产时我们加载了食谱的所有历史版本。清除旧的食谱有帮助,但没有解决我们的问题。

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

分析

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

Maven 是管理每个应用程序依赖项并创建要上传到 tomcat 的包的构建工具。在 Chef 中,实现此功能的是 Berkshelf。

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

解决方案

虽然我不喜欢策略文件,但我将它们作为 Chef 偏爱的选项提供。

政策文件

虽然大多数用户都没有注意到正在解决的问题,但 Chef 开发了一项称为策略文件的新功能:

简而言之,他们正在做的是在编译时预先设置一个节点 运行-list。

策略文件的一大好处是它们可以使厨师更快 运行。 Chef 服务器不再需要弄清楚大型依赖树,这可以大大节省具有大量食谱的 Chef 安装。

环境食谱模式

就我个人而言,我不喜欢策略文件,因为我已经发现了 Environment cookbook 模式,这是一个鲜为人知但已经存在的 chef 强大功能:

现在每次部署说明书时,我总是使用 Chef 环境。在 chef 中提供隔离的自然方式(我是否指出它知之甚少)。下面是一个使用 berkshelf 的例子:

berks upload 
berks apply my_app_cookbook_version1

非常方便的 "apply" 命令将使用 Berkshelf 锁定文件来更新环境 "my_app_cookbook_version1" 中的说明书版本。现在您已经修复了 运行-time 以匹配您的测试条件。

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

  • my_app_cookbook_version1
  • my_app_cookbook_version2
  • 等等

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

knife bootstrap --environment my_app_cookbook_version1 ...

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

一个好处是环境提供了正在使用的说明书版本的记录,以及一个方便的地方来设置与部署相关的覆盖属性,如 "app_owner"、"app_version" 等

对发帖时间过长表示歉意。