厨师:食谱不能依赖于其他食谱的旧版本
Chef: Cookbook can't depend on older version of other cookbook
背景
注意:请记住我想使用 environment-cookbook
.
版本 0.0.3
的整个问题
注意 2:我们以前从未遇到过这个问题。这是最近发生的,我们不知道是什么原因造成的。
1。 environment-cookbook
和 environment-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-domain
和 wrapper-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
食谱上时,我得到以下依赖关系图:
一切正常。
问题
当我 运行 通过 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-cookbook
和 0.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]
到目前为止我们尝试了什么
删除缓存的说明书
- 从
.berkshelf/cookbooks
中删除食谱
- 重新运行构建(自动从 chef-server 下载)
- 还在捡
0.0.8
检查其他食谱中对 environment-cookbook
的依赖性:NONE.
删除并重新安装 environment-cookbook
从 0.0.3
到 0.0.7
的所有版本:运气不好。
重新运行之前清理 Chef 客户端和节点:也不走运。
问题
为什么要更改为 environment-cookbook (0.0.7)
的最新版本,从而选择它的依赖项 dir-library (0.13.7)
?
我该如何解决这个问题?
以后如何避免这种情况?
这对我们来说真的是一场表演赛。
请问我任何进一步的说明,我会更新这个 post。
我怀疑我们 运行 遇到的厨师也有同样的问题。它归结为 运行-time 版本控制,而不是 编译时间 版本控制。
经验教训:运行 时代的无约束食谱版本在 运行 规模化厨师时是危险的。
背景
您正在使用 Berkshelf 来管理您的 cookbook 依赖项,这很好,并且可以确保将正确的版本加载到 Chef 服务器中。微妙的问题是每本食谱都有自己的依赖树。在 运行 时,当您将多个食谱添加到节点的 运行 列表时,厨师服务器必须计算新的依赖关系树。该问题可能会出现在 运行dom 中,因为它取决于您在 运行 列表中的食谱组合。食谱越多,冲突的可能性就越大。
我们试图通过显式设置说明书元数据文件的依赖关系来解决此问题。我们发现,Chef 会默默地无法解析我们某些食谱的依赖关系树,并默认返回到它会计算依赖关系的旧版本。很费解。
当我们开始在 运行-list 上明确设置说明书的版本时,我们离问题更近了。我们开始收到 chef 无法解析依赖项的错误消息。特别奇怪的是,这个问题对我们的生产厨师服务器影响最大。我们最终确定这是因为在生产时我们加载了食谱的所有历史版本。清除旧的食谱有帮助,但没有解决我们的问题。
在我们发现这些问题之前,Chef 已经工作了将近两年。是时间和规模暴露了我们系统中的致命缺陷。在 运行 时,您需要修复食谱的版本以匹配您之前测试过的配置。
分析
来自 Java 背景,我将问题等同于我们如何 运行 在 tomcat 服务器上运行多个应用程序。
Maven 是管理每个应用程序依赖项并创建要上传到 tomcat 的包的构建工具。在 Chef 中,实现此功能的是 Berkshelf。
最大的区别在于 运行 时间。 Tomcat 为属于每个应用程序的 jar 创建一个单独的类路径。这在 运行 时间提供了应用程序之间的强隔离,安全地允许它们 运行 同一食谱的不同版本。这是 Chef 面临的不可能解决的问题,在 运行 时间 chef-client 只有 运行 一套食谱。
解决方案
虽然我不喜欢策略文件,但我将它们作为 Chef 偏爱的选项提供。
政策文件
虽然大多数用户都没有注意到正在解决的问题,但 Chef 开发了一项称为策略文件的新功能:
- https://docs.chef.io/config_rb_policyfile.html
- https://www.chef.io/blog/2015/08/18/policyfiles-a-guided-tour/
- https://www.chef.io/blog/2015/10/05/policyfiles-why-what-and-how/
简而言之,他们正在做的是在编译时预先设置一个节点 运行-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" 等
对发帖时间过长表示歉意。
背景
注意:请记住我想使用 environment-cookbook
.
0.0.3
的整个问题
注意 2:我们以前从未遇到过这个问题。这是最近发生的,我们不知道是什么原因造成的。
1。 environment-cookbook
和 environment-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-domain
和 wrapper-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
食谱上时,我得到以下依赖关系图:
一切正常。
问题
当我 运行 通过 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-cookbook
和 0.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]
到目前为止我们尝试了什么
删除缓存的说明书
- 从
.berkshelf/cookbooks
中删除食谱
- 重新运行构建(自动从 chef-server 下载)
- 还在捡
0.0.8
- 从
检查其他食谱中对
environment-cookbook
的依赖性:NONE.删除并重新安装
environment-cookbook
从0.0.3
到0.0.7
的所有版本:运气不好。重新运行之前清理 Chef 客户端和节点:也不走运。
问题
为什么要更改为
environment-cookbook (0.0.7)
的最新版本,从而选择它的依赖项dir-library (0.13.7)
?我该如何解决这个问题?
以后如何避免这种情况?
这对我们来说真的是一场表演赛。
请问我任何进一步的说明,我会更新这个 post。
我怀疑我们 运行 遇到的厨师也有同样的问题。它归结为 运行-time 版本控制,而不是 编译时间 版本控制。
经验教训:运行 时代的无约束食谱版本在 运行 规模化厨师时是危险的。
背景
您正在使用 Berkshelf 来管理您的 cookbook 依赖项,这很好,并且可以确保将正确的版本加载到 Chef 服务器中。微妙的问题是每本食谱都有自己的依赖树。在 运行 时,当您将多个食谱添加到节点的 运行 列表时,厨师服务器必须计算新的依赖关系树。该问题可能会出现在 运行dom 中,因为它取决于您在 运行 列表中的食谱组合。食谱越多,冲突的可能性就越大。
我们试图通过显式设置说明书元数据文件的依赖关系来解决此问题。我们发现,Chef 会默默地无法解析我们某些食谱的依赖关系树,并默认返回到它会计算依赖关系的旧版本。很费解。
当我们开始在 运行-list 上明确设置说明书的版本时,我们离问题更近了。我们开始收到 chef 无法解析依赖项的错误消息。特别奇怪的是,这个问题对我们的生产厨师服务器影响最大。我们最终确定这是因为在生产时我们加载了食谱的所有历史版本。清除旧的食谱有帮助,但没有解决我们的问题。
在我们发现这些问题之前,Chef 已经工作了将近两年。是时间和规模暴露了我们系统中的致命缺陷。在 运行 时,您需要修复食谱的版本以匹配您之前测试过的配置。
分析
来自 Java 背景,我将问题等同于我们如何 运行 在 tomcat 服务器上运行多个应用程序。
Maven 是管理每个应用程序依赖项并创建要上传到 tomcat 的包的构建工具。在 Chef 中,实现此功能的是 Berkshelf。
最大的区别在于 运行 时间。 Tomcat 为属于每个应用程序的 jar 创建一个单独的类路径。这在 运行 时间提供了应用程序之间的强隔离,安全地允许它们 运行 同一食谱的不同版本。这是 Chef 面临的不可能解决的问题,在 运行 时间 chef-client 只有 运行 一套食谱。
解决方案
虽然我不喜欢策略文件,但我将它们作为 Chef 偏爱的选项提供。
政策文件
虽然大多数用户都没有注意到正在解决的问题,但 Chef 开发了一项称为策略文件的新功能:
- https://docs.chef.io/config_rb_policyfile.html
- https://www.chef.io/blog/2015/08/18/policyfiles-a-guided-tour/
- https://www.chef.io/blog/2015/10/05/policyfiles-why-what-and-how/
简而言之,他们正在做的是在编译时预先设置一个节点 运行-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" 等
对发帖时间过长表示歉意。