首先,我正在使用 Chef Solo,我希望事情尽可能自动化。所以我有一个问题,我不太确定如何解决。我正在设置大量不同 Linux 设备的部署,所有这些都需要自定义安装节点/角色。示例:
/节点/app_server.json
{
"run_list": [ "role[app_server]" ]
}
/角色/app_server.rb
name 'app_server'
description 'App_Server'
override_attributes({ "apache" => {
"proxypass" => [" / http://localhost:8080/"]
}
})
run_list 'recipe[app_server]'
我的问题是,我将运行一个脚本在所有这些不同的盒子上安装 chef,但每个盒子之间都会有不同的 iphttp://[xxxxxx]:8080/
我需要一种方法,能够通过命令行指定这些 ip,而无需创建一百个节点或角色文件。
我在他们的网站上看到了一个例子,其中显示:
Web 服务器角色
description "The base role for systems that serve HTTP traffic"
run_list "recipe[apache2]", "recipe[apache2::mod_ssl]", "role[monitor]"
env_run_lists "prod" => ["recipe[apache2]"], "staging" => ["recipe[apache2::staging]"],"_default" => []
default_attributes "apache2" => { "listen_ports" => [ "80", "443" ] }
override_attributes "apache2" => { "max_children" => "50" }
这似乎很有用,但我想为每个 env_run_list 配置设置不同的覆盖集,然后当我运行所有 chef 命令时,能够定位我想要的每个命令。
我是不是用错了方法?我浏览了所有关于节点/角色/环境等的文档,但还是没有找到任何不需要我创建十几个不同文件的解决方案。
答案1
在无法访问您的 app_server 配方的情况下,我推断您正在使用该node['apache']['proxypass']
属性来填充从模板生成的 apache 配置文件中的一行。
我猜测你的模板中的相关行看起来像这样:
ProxyPass <%= node['apache']['proxypass'] %>
我认为,如果您使用更精细的元素在模板中编写该行,您将获得更大的成功。如果您希望代理请求的 IP 地址在每个环境中都不同,您可以利用 Chef 的搜索功能来确定所需的 IP 地址,并将该 IP 地址作为变量传递给模板。
您的配方中的代码可能看起来像这样:
# this search assumes that the role 'myapp_backend' is in the run list of the backend server you need to discover.
# the search returns an array of node objects, for simplicity we'll just take the first result.
proxypass_backend = search(:node, "roles:myapp_backend AND chef_environment:#{node.chef_environment}").first
template ::File.join(node['apache']['dir'],'sites-available','myapp.conf') do
variables({
:proxypass_local_path => '/',
:proxypass_remote_ip => proxypass_backend['ipaddress'],
:proxypass_remote_port => '8080',
:proxypass_remote_path => '/'
})
source 'myapp.conf.erb'
end
模板中的行看起来会像这样:
ProxyPass <%= @proxypass_local_path %> http://<%= @proxypass_remote_ip %>:<%= proxypass_remote_port %><%= @proxypass_remote_path %>
为简单起见,我为远程端口和路径指定了静态值,但也可以使用可在角色或环境级别覆盖的属性值来设置这些值。由于搜索返回整个节点对象,因此搜索返回的节点的任何属性(例如运行服务的端口)也可用于填充模板变量(例如proxypass_remote_port
)。
答案2
您可以为每台仅包含覆盖的服务器创建一个 json 文件,然后可以使用 -j 选项将该文件传递给 chef-solo:
chef-solo -j node.json
您可以在 chef 运行之前创建这些文件。请注意,输入重定向尚未实现:https://tickets.opscode.com/browse/CHEF-1918所以你不能只有一个 bash 命令。
但我赞同@cwjohnston的观点,你应该拆分该字符串并将ip、端口和协议放入单独的节点属性中。你可以使用Ohai(node['ipaddress'])或Ruby找到当前节点的IP,并为最后两个设置合理的默认值。