如何使用 Chef 确保服务正在运行?

如何使用 Chef 确保服务正在运行?

我遇到的情况是 Chef 可能会启动一项服务 (postgres),但随后可能会在带外停止。我希望随后运行 Chef 以使该服务运行。我尝试过以下方法:

service "postgresql" do
    action :start
end

但它没有效果,(up to date)大概是因为 Chef 知道它已经启动,但无法判断它已经停止了。(可能是因为service ... status这项服务的行为方式?)如果我这样写:

# anti-pattern warning!
execute "force-start-postgresql" do
  command "service postgresql start || /etc/init.d/postgresql start"
  action :run
end

我得到了想要的行为。还action :restart让它运行起来。然而,由于可移植性(并且在后一种情况下可能会在重新启动之前停止它),这些看起来像是反模式。

那么,我怎样才能告诉 Chef 强制启动该服务,即使它认为该服务已经在运行?

这是使用 OpsCode 托管的 Chef 11.6 和默认的 postgresql 配方。(请注意,这与以下类似,但我认为不太一样:如何强制对 Chef 中的“最新”资源采取行动?

---编辑(根据 jtimberland 帖子进行澄清)---

这里-l debug显示:

DEBUG: service[postgresql] supports status, running
DEBUG: service[postgresql] is running

即使它没有运行。这听起来像是一个错误,我对此很感兴趣。但是我主要感兴趣的是是否有办法告诉 Chef“始终调用服务启动命令,跳过状态检查”。这就是这里的问题。

(我不是专家,但我认为确保服务正在运行的最便携的方法是启动服务,而且这几乎总是幂等的。另一方面检查服务是否正在运行不太一致,我不明白我们为什么要关心!)

答案1

默认情况下,Chef 将检查服务是否正在运行,如果服务未运行,则启动它。

如何确定服务正在运行取决于。

postgresql默认情况下,Chef 将尝试使用 在流程表中匹配服务的名称(此处) ps

ps -ef | grep postgresql

本质上。检查进程表时,服务名称将用于模式匹配。这可能是也可能不是您想要/需要的,尤其是取决于平台及其如何命名“postgresql”服务。

但是,你可以告诉 Chef 该服务支持“状态”命令,这意味着 Chef 通常会执行类似以下操作:

/etc/init.d/postgresql status

并使用返回代码来确定它是否正在运行(非零表示未运行)。

Chef 默认不这样做,因为并非所有服务脚本都支持状态命令(令人沮丧),而且 Chef 天生不知道该怎么做。它会尝试做明智的默认操作,但有时很幼稚。因此,您可以告诉 Chef 该资源有一个状态命令,而不要那么幼稚。

service "postgresql" do
  supports :status => true
  action :start
end

现在,如果服务实际上不是名为“postgresql”,而是“postgresql-92”或类似的,您可以这样做:

service "postgresql-92" do
  supports :status => true
  action :start
end

或者

service "postgresql" do
  service_name "postgresql-92"
  supports :status => true
  action :start
end

您也可以通过运行带有调试输出的 chef 来更详细地了解正在发生的事情:

chef-client -l debug

相关内容