Chef“通知”无法重新启动或重新加载服务

Chef“通知”无法重新启动或重新加载服务

我正在使用 chef-solo v10.12.0 配置 Ubuntu 12.04 VM,并且我一直遇到一个问题:当配置文件更改时,服务无法按预期重新启动或重新加载。

虽然它显然在执行配方中的所有其他操作,但日志中没有错误。作为一种解决方法,我一直在手动重新启动服务或在每次执行配方时强制重新加载/重新启动,但我更愿意找出问题所在并让它按预期工作。

一个始终无法按预期工作的示例配方:

package "pgbouncer"

cookbook_file "/etc/default/pgbouncer" do
    source "pgbouncer/pgbouncer"
    owner "root"
    group "root"
    mode 0644
end

service "pgbouncer" do
    supports :start => true, :stop => true, :restart => true, :reload => true, :status => true
    action [:enable, :start]
end

cookbook_file "/etc/pgbouncer/userlist.txt" do
    source "pgbouncer/userlist.txt"
    owner "postgres"
    group "postgres"
    mode 0640
    notifies :restart, "service[pgbouncer]"
end

template "/etc/pgbouncer/pgbouncer.ini" do
    source "pgbouncer/pgbouncer.ini"
    owner "postgres"
    group "postgres"
    mode 0640
    variables :postgres_host => node[:postgres_host]
    notifies :restart, "service[pgbouncer]"
end

答案1

我要检查的第一件事是运行 chef-client 的用户是否有权限启动/重新启动该服务(通常不是问题)。

接下来我会检查是否有其他正在运行的配方与该配方的逻辑相抵触(有时是个问题,但并不常见)。

我真正认为导致您出现问题的是 chef 处理需要通过 shell 执行的队列的方式。对同一服务的多次且有些冲突的调用可能会导致意外行为(正如您已经看到的)。默认情况下,所有“shell”调用都作为 chef-client 运行中收敛阶段的最后一部分进行处理。此外,chef 不保证任何特定的执行顺序,因此事情可能经常发生无序情况,并且可能根据您正在操作的服务的软件产生不良行为。通常,使用下面的技术来解决这个问题就是您所需要的。

对你的问题的快速而粗略的回答是在你的通知调用中添加一个 :timer 参数。DOC:http://docs.opscode.com/resource_common.html#notifications-timers

以下是对上述示例代码的建议更新:

package "pgbouncer"

service "pgbouncer" do
    supports :start => true, :stop => true, :restart => true, :reload => true, :status => true
    action [:enable, :start]
end

cookbook_file "/etc/default/pgbouncer" do
    source "pgbouncer/pgbouncer"
    owner "root"
    group "root"
    mode 0644
end

cookbook_file "/etc/pgbouncer/userlist.txt" do
    source "pgbouncer/userlist.txt"
    owner "postgres"
    group "postgres"
    mode 0640
    notifies :restart, "service[pgbouncer]", :immediately
end

template "/etc/pgbouncer/pgbouncer.ini" do
    source "pgbouncer/pgbouncer.ini"
    owner "postgres"
    group "postgres"
    mode 0640
    variables :postgres_host => node[:postgres_host]
    notifies :restart, "service[pgbouncer]", :immediately
end

这不是最有效的方法,因为它可能导致守护进程执行过多的冗余操作(一次运行最多 3 个“类似启动”调用:start、restart、restart)。在 chef 中,还有另一种更 OOP 友好的方法,即利用定义 (DOC:http://docs.opscode.com/essentials_cookbook_definitions.html)。这本质上是您定义的 pgbouncer 服务资源的自定义包装器,以减少执行冗余调用的低效率,同时确保它们有效执行,但我将由您来决定最适合您的用例的方法。

答案2

我会尝试将您的服务定义更改为以下内容

service "pgbouncer" do
    supports :start => true, :stop => true, :restart => true, :reload => true, :status => true
    action :enable
end

我记得不久前也遇到过类似的事情,而这就是罪魁祸首。如果这对您有用,请告诉我,但出于某种原因,这是我一段时间以来定义服务的方式,此后我再也没有遇到任何问题。

答案3

总的来说,这似乎是资源和通知中一个相当普遍的问题。

我查看了 Opscode JIRA 票务跟踪器,发现有一个讨论了大量关于通知和资源行为的变更和修复,将于 10.14.0 中发布

答案4

不确定 pgbouncer 是否提供了 Upstart 或 Init(从这里看是 Init:http://packages.ubuntu.com/precise/amd64/pgbouncer/filelist)但如果​​您仍然有问题,我会尝试使用您的服务资源:

service "pgbouncer" do
  provider Chef::Provider::Service::Init
  supports :start => true, :stop => true, :restart => true, :reload => true, :status => true
  action [:enable, :start]
end

此外,我还想补充:immediately一下 Gregory Patmore 提出的论点。

相关内容