假设我有一本配置并安装神奇守护进程的食谱:
magic-deamon/recipes/default.rb:
template "/etc/magical-deamon/magical.conf" do
source "magical.conf"
mode 0644
notifies :restart, resources(:service => "magical-deamon")
end
魔法守护进程/属性/默认.rb:
default['magical-deamon']['memory'] = 1024
magic-deamon/模板/默认/magical.conf.erb:
memory = <%= node['magical-deamon']['memory'] %>
据我了解 Chef,我将使用节点属性来设置内存值,例如:
{
"normal": {
"tags": [],
"magical-deamon": {
"memory": 256
}
},
"name": "server.example.com",
"chef_environment": "production",
"run_list": [
"role[base]"
]
}
或者通过角色:
{
"name": "base",
"default_attributes": {
"magical-deamon": {
"memory": 756
}
},
"json_class": "Chef::Role",
"env_run_lists": {
},
"run_list": [
],
"description": "base role applied to all nodes",
"chef_type": "role",
"override_attributes": {
},
}
}
或者环境:
{
"name": "production",
"default_attributes": {
"magical-deamon": {
"memory": 756
}
},
"json_class": "Chef::Environment",
"description": "",
"cookbook_versions": {
},
"override_attributes": {
},
"chef_type": "environment"
}
到目前为止,一切都很好...
现在我有一个愚蠢的想法,将“内存”设置为特定节点的动态值。
假设我们的神奇守护进程应该消耗节点所拥有的总内存的 75%。
value = total_memory * 0.75
作为一名程序员,我喜欢将这些知识排除在菜谱之外,因为我希望我的菜谱可以被其他人重复使用。
我认为正确的位置应该是设置属性的地方。但是在 json 或 ruby dsl 中无法进行这样的计算。
我的问题是:
- 我的一般方法(值 = total_memory * 0.75)是一个愚蠢的想法吗?
- 您将如何设置这种属性?请记住:将有多个值和一个节点 :) 并且可能涉及 MB -> KB 和舍入等计算。将每个属性硬编码到配方中不应该是一种选择 ;)
答案1
我不太喜欢 total_memory 这个概念,因为它有点像间接量。不过,也许在魔法守护进程的上下文中它更有意义。
对于诸如总内存之类的可调属性,我基本上会按照您在问题中提出的那样去做,即向attributes/default.rb 添加一个合理的默认值(当有人忘记明确设置值时减少支持问题)并在必要时用环境、角色或节点特定的值覆盖。
可以在 ERB 文件内部进行如下算术运算:
memory = <%= (node['memory']['total'][0..-3].to_i / 1024) *
node['magical-daemon']['memory'] %>
Ohai 提供了 free(1) 的统计数据,其中包括以 kB 为单位的总内存。我的工作站上 node['memory']['total'] = '12312432kB'。
我还尝试尽可能使用优先级最低的属性,即默认属性优于普通属性,普通属性优于覆盖属性。因此,
- 尽可能选择一个合理的默认配方
- 使用默认环境属性(在示例中使用了覆盖属性)
- 对节点组使用角色属性(再次使用覆盖属性)
- 最后是默认节点属性
查看属性优先级请参阅 Chef wiki 中的链接)以了解属性相互覆盖的顺序。
尽可能使用优先级最低的默认属性允许您根据环境、角色和节点设置属性值,但是当您需要做一些棘手的事情时,可以释放较高优先级。