Ansible 的幂等初探

写在前面

  • Ansible的幂等性是对于模块(或playbook中的步骤)来谈的
  • 大部分Ansible模块可以做到幂等
  • 并不是所有Ansible模块都是幂等的,无法保证幂等性的模块如 shellcommand
  • 本篇有很多说法只是基于作者个人浅薄的经验和思考,并无太多凭据;一家之言若有不妥,欢迎指出

Ansible 与 幂等

因为第一次接触Ansible就被安利说它是“幂等”的,但是一直没有搞清楚它究竟如何做到幂等。这样的“第一印象”反而让我走入了认识误区。

幂等

数学上,如果一个函数多次运算,得到的结果一致,则此函数具有幂等性(idempotent):

f(x)=f(f(x))

工程领域也经常引用此概念,但是并没有数学上那么严谨,一般认为 某项操作如果执行多次,得到的结果一致,则该操作具有幂等性
此处操作可引申为函数、请求、服务等。工程领域对幂等性更多强调其可重复执行[1]。

实现起来也各有不同。比如在交易领域,可以如此实现幂等:每笔交易持有一个全局id号,向服务发起交易请求需要携带此id,后端服务以此判断交易是否执行完成,并返回唯一执行结果[2]。

Ansible 幂等

Ansible 某些模块具有天然幂等性,具体指的是某些模块只是指定服务器将达到的最终状态,如

- tasks:
    - name: remote option in remote config file
      ini_file: 
        path: /some/path/config.ini
        section: t_section
        option:  t_option
        state:   absent

将最终使远端的配置文件中没有 [t_section] t_option 项。而如果用 commandshell 执行 sed 命令,该命令会始终执行[3]。

所以,我们在使用 Ansible 时,应当尽量指定服务器的最终状态,而不是发出执行的指令。面向结果,而不是面向过程

.retry 文件

每次在 Ansible-playbook 执行遇到失败时(部分 inventory 失败),系统会提示:

to retry, use: --limit @/path/to/my_playbook.retry

最初笔者以为这个 .retry 文件和 ansible 的幂等有关。但是打开文件之后,发现其实里面只有一个失败inventory的hostname。事实上,这个文件和幂等无关,只是在提醒用户,可以再次运行 ansible-playbook 并带上 --limit @/path/to/my_playbook.retry 以重试。

具体用法:

# my_playbook.yml
---
- hosts: inventory
  tasks:
    - name: I make you fail
    - fail: msg="just make you fail"
# 第一次运行 playbook
ansible-playbook my_playbook.yml -i my_inventroy

# 抛出提示
fatal: [your_host]: FAILED! => {"changed": false, "msg": "just make you fail"}
       to retry, use: --limit @/{path}/my_playbook.retry

# 重试
ansible-playbook my_playbook.yml -i my_inventroy --limit @/{path}/my_playbook.retry

当然,由于我们的 playbook 只能fail,重试多次还是不会成功滴,否则就有鬼了~

References:

  • [1] 什么是分布式系统中的幂等性
  • [2] 后端接口的幂等性
  • [3] 15 Things You Should Know About Ansible
  • [4] Github-issue: Meaning of --limit @/path/site.retry

你可能感兴趣的:(Ansible 的幂等初探)