Ansible playbook 处理器(notify与handlers)
notify和handlers
此前曾提到过,Ansible绝大多数的模块都具备幂等性,它能保证多次执行不会改变结果,这使得Ansible执行任务时更为安全。
Ansible的模块如何去保证幂等性呢?以shell模块为例∶
shell:
cmd: echo haha >/tmp/only_once.txt
creates: /tmp/only_once.txt
这里使用了shel模块中的creates参数,它表示如果其指定的文件/tmp/only_once.txt存在,则不执行shell命令,只有该文件不存在时才执行。这就是保证幂等性的一种体现∶既然不能保证多次执行shell命令的结果不变,那就保证只执行一次。
在此有一个重要的概念,叫做 changed,其实在Ansible的执行结果中经常会看到这个字跟。从广义的角度上理解,changed用于表示目标状态是否发生了改变,通俗而不严格地讲,就是本次任务是否执行了或执行了是否影响结果。
例如,第一次执行上面的shell任务时,由于/tmp/only_once.txt文件不存在,所以会执行shell命令,执行完之后创建了这个文件,于是它关注的目标文件存在性状态发生了改变,这时会设置changed=1。如果再次执行该任务,因其关注的文件已存在,所以它不会执行shell命令,其关注的目标存在性状态未改变,这时会设置 chaged=0。
再比如,从Ansible端拷贝nginx的配置文件到目标主机上,如果所拷贝配置文件的内容和原有的配置文件内容不同,则表示其关注的状态(即文件内容,其实是比较md5值)发生了改变,如果内容相同,则表示其关注的状态未发生改变。而配置文件内容发生改变,往往伴随着重启nginx服务的操作。
Ansible会监控changed的状态,如果 changed=1,则表示关注的状态发生了改变,即本次任务的执行不具备幂等性,如果 changed=0,则表示本次任务要么没执行,要么执行了也没有影响,即本次任务具备幂等性。
Ansible提供了notify指令和handlers功能。如果在某个task中定义了notify指令,当Ansible在监控到该任务 changed=1时,会触发该notify指令所定义的handler,然后去执行handler。所谓handler,其实就是task,无论在写法上还是作用上它和task都没有区别,唯一的区别在于hander是被触发而被动执行的,不像普通task一样会按流程正常执行。
下面我们先看一个例子
[root@localhost ~]# cat httpd.yml
---
- name: play1
hosts: all
remote_user: root
gather_facts: false
tasks:
- name: install httpd
yum: name=httpd state=installed
- name: copy httpd config
copy: src=/etc/httpd/conf/httpd.conf dest=/etc/httpd/conf/httpd.conf
- name: start httpd
service: name=httpd state=started enabled=true
[root@localhost ~]# vim /etc/httpd/conf/httpd.conf
Listen 8888
#把本地的httpd配置文件复制到其他节点上。配置文件唯一的修改就是端口从80端口改为了8888端口
[root@www ~]# lsof -i:8080
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
httpd 14697 root 4u IPv6 799818 0t0 TCP *:webcache (LISTEN)
httpd 14698 apache 4u IPv6 799818 0t0 TCP *:webcache (LISTEN)
httpd 14699 apache 4u IPv6 799818 0t0 TCP *:webcache (LISTEN)
httpd 14700 apache 4u IPv6 799818 0t0 TCP *:webcache (LISTEN)
httpd 14701 apache 4u IPv6 799818 0t0 TCP *:webcache (LISTEN)
httpd 14702 apache 4u IPv6 799818 0t0 TCP *:webcache (LISTEN)
[root@localhost ~]# ansible-playbook httpd.yml
PLAY [play1] ******************************************************************************************************************************
TASK [install httpd] **********************************************************************************************************************
ok: [192.168.179.100]
TASK [copy httpd config] ******************************************************************************************************************
changed: [192.168.179.100]
TASK [start httpd] ************************************************************************************************************************
ok: [192.168.179.100]
PLAY RECAP ********************************************************************************************************************************
192.168.179.100 : ok=3 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
#执行完成之后我们到节点上使用lsof -i:8888端口,会发现服务并没有重启
[root@www ~]# lsof -i:8888
[root@www ~]#
处理器是根据对应Task的返回状态来进行判断的。当Task(任务)状态为changed时,处理器就会执行你写好的handlers(处理器)操作。例如下面这个例子:
[root@localhost ~]# vim /etc/httpd/conf/httpd.conf
Listen 6666
[root@localhost ~]# cat httpd.yml
---
- name: play1
hosts: all
remote_user: root
gather_facts: false
tasks:
- name: install httpd
yum: name=httpd state=installed
- name: copy httpd config
copy: src=/etc/httpd/conf/httpd.conf dest=/etc/httpd/conf/httpd.conf
notify:
- restart httpd
- name: start httpd
service: name=httpd state=started enabled=true
handlers:
- name: restart httpd
service: name=httpd state=restarted
#这里只要对httpd.conf配置文件作出了修改,修改后需要重启生效,在tasks中定义了restart httpd这个action,然后在handlers中引用上面tasks中定义的notify。
[root@localhost ~]# ansible-playbook httpd.yml
PLAY [play1] ******************************************************************************************************************************
TASK [install httpd] **********************************************************************************************************************
ok: [192.168.179.100]
TASK [copy httpd config] ******************************************************************************************************************
changed: [192.168.179.100]
#这里的状态是changed,处理器的触发条件就是change 所以这里独发了处理器。
TASK [start httpd] ************************************************************************************************************************
ok: [192.168.179.100]
RUNNING HANDLER [restart httpd] ***********************************************************************************************************
changed: [192.168.179.100]
#触发器触发了
PLAY RECAP ********************************************************************************************************************************
192.168.179.100 : ok=4 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
[root@www ~]# lsof -i:6666
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
httpd 15395 root 4u IPv6 803733 0t0 TCP *:ircu-2 (LISTEN)
httpd 15398 apache 4u IPv6 803733 0t0 TCP *:ircu-2 (LISTEN)
httpd 15399 apache 4u IPv6 803733 0t0 TCP *:ircu-2 (LISTEN)
httpd 15400 apache 4u IPv6 803733 0t0 TCP *:ircu-2 (LISTEN)
httpd 15401 apache 4u IPv6 803733 0t0 TCP *:ircu-2 (LISTEN)
httpd 15402 apache 4u IPv6 803733 0t0 TCP *:ircu-2 (LISTEN)
这个就是一个使用了处理器的例子。
handlers是处理器,他的使用方法和tasks(任务)一样。定义一个名称以及要执行的操作就行了
notify:则是在该Task中调用handlers里写好的操作,通过上图我们可以清楚的看到,在copy httpd config这个Task中我们就调用了处理器,而这个处理器要执行的命令则是重启httpd服务。这就很清楚了,当配置文件发生改变就重启httpd服务。
目录 返回
首页