【问题标题】:Chef - Prevent multiple service restarts or reloads with dnmsasq?Chef - 使用 dnmsasq 防止多个服务重新启动或重新加载?
【发布时间】:2021-02-01 22:32:46
【问题描述】:

如何在一次主厨运行中实现一次重启/重新加载并符合主厨最佳实践?

使用状态文件是一种好习惯还是重写服务 dnsmasq 信息?

这个问题是 7 年前提出的,有人找到更好的方法吗? 此处记录的重写服务 --
Minimize service restarts from chef notifications?

问题:

当前代码已导致 1 次重新启动和 1 次重新加载。这导致了问题。

dnsmasq 有 3 个配置文件,需要使用不同的启动/重启/重新加载方法进行管理。 dnsmasq 在设计上将 no-poll 作为参数,以防止它在每次更改时重新加载 /etc/resolv.conf。我想在这里控制重载。

package "install dnsmasq" do
  name 'dnsmasq'
  action :install
  notifies :create, 'cookbook_file[/etc/dnsmasq.conf]', :delayed
  notifies :create, 'template[/etc/resolv.dnsmasq]', :delayed
  notifies :create, 'template[/etc/resolv.conf]', :delayed
  notifies :restart, 'service[dnsmasq]', :delayed
end

template '/etc/resolv.dnsmasq' do
  ...
  notifies :reload, 'service[dnsmasq]', :delayed
end

file '/etc/dnsmasq.conf' do
  ...
  notifies :restart, 'service[dnsmasq]', :delayed
end

template '/etc/resolv.conf' do
  ...
  notifies :reload, 'service[dnsmasq]', :delayed
end

service 'dnsmasq' do
  supports [:restart, :status, :start, :reload]
  action [ :enable, :start ]
  reload_command "/usr/bin/killall -s SIGHUP dnsmasq"
end

【问题讨论】:

  • 是否需要:reload,因为还需要服务:restart?恕我直言,在更新所有配置文件后最后重启一次就足够了。
  • 在第一次更改或更改 dnsmasq.conf 时更新所有配置将导致重新启动,我们认为这是有风险的。但是,如果我们要更新/更改只需要重新加载的文件,我们希望尽可能避免重新启动服务。

标签: chef-infra dnsmasq


【解决方案1】:

如果你做的不止这些:

package "install dnsmasq" do
  name 'dnsmasq'
  action :install
end

file '/etc/dnsmasq.conf' do
  ...
  notifies :restart, 'service[dnsmasq]', :delayed
end

template '/etc/resolv.dnsmasq' do
  ...
  notifies :reload, 'service[dnsmasq]', :delayed
end

template '/etc/resolv.conf' do
  ...
  notifies :reload, 'service[dnsmasq]', :delayed
end

service 'dnsmasq' do
  supports [:restart, :status, :start, :reload]
  action [ :enable, :start ]
  reload_command "/usr/bin/killall -s SIGHUP dnsmasq"
end

那么您的代码中可能存在逻辑问题,因为您在这些文件中放置了什么,这些资源是幂等的,从包安装通知模板和文件然后通知服务重启在声明性模型上是无稽之谈。

这里不需要使用通知, :delayed 也不是必需的,因为它是默认值,但它在阅读时会很明显。

首先放置 /etc/dnsmasq.conf 文件以确保在需要时在任何重新加载之前首先触发重新启动通知,以避免重新加载需要重新启动的配置更改。重启后重新加载完全没有问题。

【讨论】:

  • 感谢您的反馈。我有点希望重新启动然后重新加载不会“破坏性”。我们遵循 RedHat 的 5 9 的文档。默认情况下,dnsmasq 会删除缓存,并且必须在每次操作后重新加载它。这些被认为对我们的少数应用程序具有“破坏性”。今天,对于这些应用程序,我们必须在维护时更换 resolv.conf 中的名称服务器,即使超时时间为 1 秒。我们发现重新启动/重新加载非常“破坏性”,重新启动是“破坏性”,重新加载不是“破坏性”。我的任务是尽量减少对部署和未来更改的干扰。
  • 我想知道您可能需要真正重新启动 dnsmasq 进行哪些修改,据我所知重新加载足以重新配置所有内容,而 IIRC 您可以阻止缓存清理,但似乎您正在为此重新加载,因此这可能不是更好的方法。
  • 根据 dnsmasq 的维护者,对 dnsmasq.conf 的更改需要重新启动。这是一项安全功能,因为进程切换到用户“nobody”,并且为该配置重新加载更改的唯一方法是重新启动。此外,我们现在包含一个自定义 systemd 单元文件,其中包含 reload 命令和进程终止时的重新启动。要获取新的单元更改,需要 systemctl daemon-reload 并重新启动 dnsmasq。对于 Linux 6 系统,我们必须在旧的监控进程中包含 dnsmasq,并且仍然必须在服务资源中保留 reload_command=。
  • 公平点。我有点明白你来自哪里。
【解决方案2】:

这种“累加器”解决方案会导致一次启动、重新启动或重新加载,具体取决于传递的内容。该过程以前被称为倒带。这可能不是非常有效的编码或在 Chef 中执行此类活动的正确方法,但该解决方案目前对我有用。

配方:dnsmasq.rb

dnsmasq_service 'dnsmasq' do
  action :nothing
end

package 'dnsmasq' do
  action :install
end

# This has to come first, as it requires a restart
cookbook_file '/etc/dnsmasq.conf' do
  delayed_action :create
  notifies :restart, 'dnsmasq_service[dnsmasq]'
end

# This comes second
template '/etc/resolv.dnsmasq' do
  delayed_action :create
  notifies :reload, 'dnsmasq_service[dnsmasq]'
end

# This comes third.  Do not create until the other configs are down.
template '/etc/resolv.conf' do
  delayed_action :create
  notifies :reload, 'dnsmasq_service[dnsmasq]'
end

# This comes fourth
# Make sure the service is always started and enabled.
service 'dnsmasq' do
  action [ :enable, :start ]
  delayed_action :start
end

资源:dnsmasq_service.rb

#https://github.com/chef/chef/issues/5454
# Be aware of the cookbook name being lost
#https://github.com/chef/chef/issues/5438
# Could not get this to work without the log notifications.

#https://coderanger.net/rewind/
#https://docs.chef.io/infra_language/

provides :dnsmasq_service
resource_name :dnsmasq_service

default_action :start

action :start do
  # Find resource, if it does not exist create with this action
  with_run_context :root do
    find_resource(:service, 'dnsmasq') do
      action [ :enable, :start ]
    end
  end
  log "force :start dnsmasq notification" do
    notifies :start, 'service[dnsmasq]', :delayed
  end
end

action :reload do
  r = with_run_context :root do
    find_resource(:service, 'dnsmasq') do
      action [ :enable, :reload ]
      reload_command "/usr/bin/killall -s SIGHUP dnsmasq"
    end
  end

  a = Array.new(r.action)
  f_act = :reload
  if a.include?(:restart)
    f_act = :restart
    with_run_context :root do
      edit_resource!(:service, 'dnsmasq') do
        action [ :enable, :restart ]
      end
    end
  else
    with_run_context :root do
      edit_resource!(:service, 'dnsmasq') do
        action [ :enable, :reload ]
        reload_command "/usr/bin/killall -s SIGHUP dnsmasq"
      end
    end
  end
  log "force #{f_act} dnsmasq notification" do
    notifies f_act, 'service[dnsmasq]', :delayed
  end
end

action :restart do
  r = with_run_context :root do
    find_resource(:service, 'dnsmasq') do
      action [ :enable, :reload ]
    end
  end

  with_run_context :root do
    edit_resource!(:service, 'dnsmasq') do
      action [ :enable, :restart ]
    end
  end
  log "force :restart dnsmasq notification" do
    notifies :restart, 'service[dnsmasq]', :delayed
  end
end

【讨论】:

  • 没有理由用他们已经拥有的相同操作通知资源。如果您为文件设置了创建通知,它自己的操作应该是 create_if_missing 或什么都没有,但这里包资源中的通知没有意义。此外,尝试从自定义资源编辑服务资源只是一个可怕的复杂性自定义资源不是为了。它们在这里是为了将资源抽象在一起,如果你创建一个,移动它里面的所有位(文件、模板和服务)并在你的配方中只声明这个资源。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-04-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多