考虑以下代码:
file { '/etc/systemd/system/docker.service.d/http-proxy.conf':
ensure => 'present',
owner => 'root',
group => 'root',
mode => '644',
content => '[Service]
Environment="HTTP_PROXY=http://10.0.2.2:3128"
Environment="HTTPS_PROXY=http://10.0.2.2:3128"
',
notify => Exec['daemon-reload'],
require => Package['docker-ce'],
}
exec { 'daemon-reload':
command => 'systemctl daemon-reload',
path => '/sbin',
refreshonly => true,
}
service { 'docker':
ensure => 'running',
subscribe => File['/etc/systemd/system/docker.service.d/http-proxy.conf'],
require => Exec['daemon-reload'],
}
我想编辑一些systemd服务。在这种情况下,这是docker的环境,但是可能还有其他需求。
由于已更改systemd单位文件,因此systemctl daemon-reload
must be run将用于选择新配置。
运行puppet apply
失败:
Notice: Compiled catalog for puppet-docker-test.<redacted> in environment production in 0.18 seconds
Notice: /Stage[main]/Main/File[/etc/systemd/system/docker.service.d/http-proxy.conf]/ensure: defined content as '{md5}dace796a9904d2c5e2c438e6faba2332'
Error: /Stage[main]/Main/Exec[daemon-reload]: Failed to call refresh: Could not find command 'systemctl'
Error: /Stage[main]/Main/Exec[daemon-reload]: Could not find command 'systemctl'
Notice: /Stage[main]/Main/Service[docker]: Dependency Exec[daemon-reload] has failures: false
Warning: /Stage[main]/Main/Service[docker]: Skipping because of failed dependencies
Notice: Applied catalog in 0.15 seconds
原因很明显:systemctl
生活在/bin
中,而不是配置的/sbin
中。但是,解决此问题,然后再次运行puppet apply
既不会导致服务重启,也不会导致systemctl daemon-reload
运行:
Notice: Compiled catalog for puppet-docker-test.<redacted> in environment production in 0.19 seconds
Notice: Applied catalog in 0.16 seconds
显然,发生这种情况是因为文件资源没有更改(因为该文件资源已应用于失败的运行),这会刷新后台驻留程序重新加载,然后触发服务重新启动。
为了强制人偶重新加载服务并重新启动它,我可以更改磁盘上文件的内容,也可以更改人偶代码上的内容,但是感觉像我错过了一些更好的方法。
如何更好地从这种情况下恢复?或者,如何编写没有此问题的木偶代码?
答案 0 :(得分:0)
Puppet不提供恢复失败运行的机制。这样做对我来说没有多大意义,因为人们希望恢复操作后获得不同的结果将取决于发生故障后更改的计算机状态,并且Puppet以外的计算机状态更改可能会使正在使用的目录无效已应用。
默认情况下,代理程序确实会将运行报告发送给主服务器,因此,如果运行失败,您应该能够从中确定出了什么问题。假设您不想搜寻报告以找出如何从失败的运行中恢复,但是,您可以考虑编译恢复脚本。
例如,您知道所有 故障都可能导致后台驻留程序重新加载丢失,并且在不需要时执行该操作是无害的,因此只需将其放入脚本中即可。您还可以重新启动受管理的每个服务。基本上,您正在寻找具有非平凡刷新行为的东西(Exec
和Service
是我想到的主要对象)。
在我看来,如果您非常聪明,则可以将其以一个或多个Puppet类的形式放置,并在主节点上确定上一次针对目标节点的运行是否失败,因此应用恢复。
关于首先要避免该问题,我只能建议进行测试,测试以及更多测试。为此,如果您没有用于测试Puppet更新的专用计算机,则至少选择少数先获取更新的普通计算机,这样就可以将所有出现的问题都严格控制住。
答案 1 :(得分:0)
由于您的http-haproxy.conf在第一次执行puppet时已被更新,因此下次将不会再次更新,并且不会通知systemctl daemon-reload
如果您需要一直在运行systemctl daemon-reload(无论是否有通知),那么您需要更多refreshonly => true从exec'daemon-reload'