虚拟化容器,大数据,DBA,中间件,监控。

Ansible playbook 处理器(notify与handlers)

20 12月
作者:admin|分类:系统运维

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服务。

  

浏览430 评论0
返回
目录
返回
首页
Ansible 任务控制(循环loop、条件when) Ansible Ansible的灵魂∶playbook