Chef - 如何从节点特定值计算属性?

Ale*_*ger 7 chef

假设我有一本配置和安装神奇守护进程的食谱:

魔法守护进程/食谱/default.rb:

template "/etc/magical-deamon/magical.conf" do
    source "magical.conf"
    mode 0644
    notifies :restart, resources(:service => "magical-deamon")
end
Run Code Online (Sandbox Code Playgroud)

魔法守护进程/属性/default.rb:

default['magical-deamon']['memory'] = 1024
Run Code Online (Sandbox Code Playgroud)

magic-deamon/templates/default/magical.conf.erb:

memory = <%= node['magical-deamon']['memory'] %>
Run Code Online (Sandbox Code Playgroud)

据我了解,我会使用节点属性来设置内存值,例如:

{
    "normal": {
        "tags": [],
        "magical-deamon": {
            "memory": 256
        }
    },
    "name": "server.example.com",
    "chef_environment": "production",
    "run_list": [
        "role[base]"
    ]
}
Run Code Online (Sandbox Code Playgroud)

或者通过角色:

{
    "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": {
    },
  }
}
Run Code Online (Sandbox Code Playgroud)

或环境:

{
  "name": "production",
  "default_attributes": {
    "magical-deamon": {
        "memory": 756
    }
  },
  "json_class": "Chef::Environment",
  "description": "",
  "cookbook_versions": {
  },
  "override_attributes": {
  },
  "chef_type": "environment"
}
Run Code Online (Sandbox Code Playgroud)

到现在为止还挺好...

现在我有一个愚蠢的想法将“内存”设置为节点特定的动态值。

假设我们的魔法守护进程应该消耗节点拥有的总内存的 75%。

value = total_memory * 0.75
Run Code Online (Sandbox Code Playgroud)

来自程序员背景,我喜欢将这些知识从食谱中删除,因为我喜欢我的食谱可以重复使用给其他人。

我认为正确的地方应该是设置属性的地方。但是在 json 或 ruby​​ dsl 中进行这样的计算是不可能的。

所以我的问题是:

  • 我的一般方法(值 = total_memory * 0.75)是一个愚蠢的主意吗?
  • 你会如何设置这种属性?请记住:将有多个值和一个节点 :) 并且可能涉及 MB -> KB 和舍入等一些计算。将每个属性硬连接到配方中,不应该是一个选项;)

Tim*_*ter 10

我不太热衷于 total_memory 的想法,它有点间接数量。也许它在神奇的守护进程的上下文中更有意义。

对于像总内存这样的可调属性,我几乎会按照你在问题中提出的那样做,通过向 attributes/default.rb 添加一个合理的默认值(当有人忘记明确设置一个值时减少支持问题)并覆盖必要时环境、角色或特定于节点的值。

可以像这样在 ERB 文件中进行算术运算:

memory = <%= (node['memory']['total'][0..-3].to_i / 1024) * 
             node['magical-daemon']['memory'] %>
Run Code Online (Sandbox Code Playgroud)

Ohai 提供来自 free(1) 的统计信息,其中包括以 kB 为单位的总内存。node['memory']['total'] = '12312432kB' 在我的工作站上。

我还尝试尽可能多地使用具有最低优先级的属性,即优先于默认属性而不是普通属性,以及优先于覆盖属性的普通属性。所以,

  • 尽可能选择合理的配方默认值
  • 使用默认环境属性(您在示例中使用覆盖属性)
  • 对节点组使用角色属性(再次使用覆盖属性)
  • 最后是默认节点属性

有关属性相互覆盖的顺序,请参阅Chef wiki 中的属性优先级链接。

在可能的情况下使用最低优先级默认属性允许您根据环境、角色和节点设置属性值,但在您需要做一些棘手的事情时释放更高级别的优先级。