使用 ansible 通常依赖于一种称为“幂等性”的属性。如果您第二次应用某个角色,预计会得到相同的结果。例如,它不会在配置文件中添加同一行的第二个副本。
还有另一个属性您可以称之为“可恢复”。如果控制器和目标之间出现网络分区,中断的播放可以在分区解决后重新运行吗?
安西布尔提示通过列出失败的目标并允许重新尝试来实现此属性。
但是,如果您查看实际示例,就会发现它们似乎不具备此属性。建议一种方法,以确保我能够识别我的剧本无法正确恢复的任何情况。
- name: Create Mysql configuration file
template: src=my.cnf.j2 dest=/etc/my.cnf
notify:
- restart mysql
- name: Start Mysql Service
service: name=mysqld state=started enabled=yes
例如,上面来自 ansible-examples 的代码片段未能实现“可恢复”属性。如果在创建配置文件之后但在运行处理程序“restart mysql”之前播放被中断,则处理程序“restart mysql”将永远不会触发。
答案1
原则上,可以通过在重新启动服务后触摸时间戳文件来实现可恢复播放。那么重启服务的条件就是重启时间戳是否早于配置文件的修改时间。 (灵感来自make
)。
对于配置文件,也可以使用本机 ansible 模块:
- name: Create Mysql configuration file
template: src=my.cnf.j2 dest=/etc/my.cnf
- name: query | mysql has been restarted with new config file
template: src=my.cnf.j2 dest=/ansible-managed/mysql/restarted/my.cnf
check_mode: yes
register: mysql_restarted
- name: ensure | mysql has been restarted with new config file
service: name=mysqld state=restarted
when: mysql_restarted|changed
- name: record | mysql has been restarted with new config file
template: src=my.cnf.j2 dest=/ansible-managed/mysql/restarted/my.cnf
(或者例如
- name: query | mysql has been restarted with new config file
copy: remote_src=yes src=/etc/my.cnf dest=/ansible-managed/mysql/restarted/my.cnf
check_mode: yes
register: mysql_restarted
虽然remote_src
会仅有的使用单独的配置文件,而不是目录)
答案2
Ansible 文档提到但这只是顺便说一下。 “某些错误仍然可能阻止处理程序运行,例如主机无法访问。”没有关于在这种情况下该怎么做的建议。
它提到--force-handlers
.这里有些混乱。问题第4777章请求一个--force-handlers
选项,该选项将运行所有处理程序,无论是否通知它们,以允许在这种情况下进行恢复。该问题以“现已实施”评论结束。旁白:没有实施。我已经开了一个新问题请求这样的功能。
不幸的是,我相信这个评论已经引起一些人建议--force-handlers
在 stackexchange 或其他地方解决这个问题,但事实并非如此。
完整的解决方案将修改 ansible 以记录待处理处理程序的数据库。 (当任务检测到即将进行更改时,将立即记录处理程序)。
除此之外,您会希望避免此类中断。因为您需要仔细检查两个处理程序以及任何以 为条件的任务|changed
,并确保在重试的目标上运行所有这些任务。
寓意:使用处理程序可能很有用,并避免|changed
在整个剧本中散布。
一个不太优雅但同样正确的解决方案将涉及修改 ansible,并提供强制运行所有处理程序的选项。或者也许将所有未跳过的任务视为已更改。如果原始运行需要重新启动服务,则安排第二次运行来重新启动服务并非完全不合理。缺点是如果原来运行只需要重新启动一些服务。
您还可以使用 ansible“拉模式”来避免播放中断。或者,如果主要问题是因为 ansible 是远程运行的,您可以使用带有screen
/ 的持久会话在同一站点的服务器上运行 ansible tmux
。