1、控制每次同时更新的主机数量

im test_serial.yml
---
- hosts: all
  serial: 2  #每次只同时处理2个主机
  max_fail_percentage : 50  #当两台机器中有一台执行失败,既终止task
  gather_facts: False

  tasks:
    - name: task one
      comand: hostname
    - name: task two
      command: hostname
#也可以使用百分比进行控制
name: test serail
  hosts: all
  serial: "20%"   #每次只同时处理20%的主机

 2、Ansible-Playbook之异步执行

异步功能不作为单独的模块出现,而是作为任务参数使用,因此,大多数模块都可以异步执行;

异步执行功能通常是用来解决执行任务时间过长导致SSH连接超时。

示例:

---
- hosts: "ansible-server"
  tasks:
 
  - name: simulate long running op (15 sec), wait for up to 45 sec, poll every 5 sec
    command: /bin/sleep 15
    async: 45
    poll: 5

参数讲解:

 

 

 

async

任务最大执行时间

 

poll

轮询间隔

 

> POLL:

当 poll > 0 的时候,任务本身依然会阻塞运行,但是,实际上ansible任务与内部执行的shell脚本之间是异步执行,在脚本执行过程中,ansible任务会根据poll设置的轮询时间间隔取获取脚本执行的状态,并根据async判断是否超时了;举个例子:

这是剧本,超时时间设置的很大,轮询间隔是20s,即每20秒获取一次执行状态;

---
- hosts: "ansible-server"
  tasks:
  - name: test for sync job
    shell: |
      cd ~/scripts
      sh sleep.sh
    async: 999
    poll: 20

这是sleep.sh脚本,睡眠5s;

sleep 5s

执行结果是整个任务依然需要等待大约20s才能执行完成(虽然实际上有效工作时间只有5s);

当 poll = 0 的时候,任务本身实现了非阻塞的异步执行,由于没有轮询间隔,代表着该任务本身并不会主动获取任务执行状态和结果;此时异步任务会一直执行,直到完成、失败或超时;

我们举个例子:

这是剧本,这次设置poll参数为0,这意味着这个任务是异步执行的,也就是,一旦开启了这个任务,剧本就会退出;

---
- hosts: "ansible-server"
  tasks:
  - name: test for sync job
    shell: |
      cd ~/scripts
      sh sleep.sh
    async: 999
    poll: 0

这是sleep.sh脚本,在睡眠20s后,会创建一个时间戳文件;

  1. sleep 20s
  2. mkdir `date +%H%M%S`.txt

我们运行剧本,发现几乎在启动的同时剧本就执行完成了,而等待20s左右,在sleep.sh同级目录下生成了一个.txt文件;这说明异步执行的任务即使剧本退出,也会继续执行下去;

3、获取异步任务执行状态

异步功能本身无法自身向用户反馈执行状态和结果,如果要异步执行任务并稍后进行检查,可以使用async_status模块进行监控与反馈;

示例:

---
# Requires ansible 1.8+
- name: 'YUM - async task'
  yum:
    name: docker-io
    state: present
  async: 1000
  poll: 0
  register: yum_sleeper
 
- name: 'YUM - check on async task'
  async_status:
    jid: "{{ yum_sleeper.ansible_job_id }}"
  register: job_result
  until: job_result.finished
  retries: 30
  delay: 5

 

3.1. 参数

参数名

 

jid 

作业或任务标识符

mode

如果为status,则获取状态

如果是cleanup,清理指定的作业jid异步作业缓存(~/.ansible_async/)

 

3.2. 返回值

返回值名

 

ansible_job_id

异步任务的id

finished

异步任务是否完成(1:已完成;0:未完成)

started

异步任务是否开始(1:已开始;0:未开始)

获取异步任务执行状态通常可以与until参数配置使用,在可控制的次数内,不断地取查询任务执行状态,直到任务执行结束、失败或超时;

 

3.3. Until条件循环

简单介绍一下until循环参数:

 

 

until

条件终止表达式

retries

最大循环次数

delay

每次循环时间间隔(秒)

循环终止有两个条件,任意满足其一就可以:

1. 循环次数超过最大次数;

2. 满足until条件,直接跳出循环;

综合举个例子:

剧本如下:

---
- hosts: "ansible-server"
  tasks:
  - name: test for sync job
    shell: |
      sleep 15
    async: 999
    poll: 0
    register: sleeper
 
  - name: Monitor and feedback
    async_status:
      jid: "{{ sleeper.ansible_job_id }}"
    register: backer
    until: backer.finished
    retries: 20
    delay: 1

一个睡眠15秒的异步任务,为任务本身注册一个变量sleeper;

一个监控任务,输入jid为监控对象的id,利用Until循环,条件为输出数据的finished字段,设置的最大循环次数为20,循环间隔时间为1秒;

输出日志打印:

[WARNING]: Invalid characters were found in group names but not replaced, use -vvvv to see details PLAY [ansible-server] *************************************************************************************** TASK [Gathering Facts] ************************************************************************************** ok: [localhost] TASK [test for sync job] ************************************************************************************ changed: [localhost] TASK [Monitor and feedback] ********************************************************************************* FAILED - RETRYING: Monitor and feedback (20 retries left). FAILED - RETRYING: Monitor and feedback (19 retries left). FAILED - RETRYING: Monitor and feedback (18 retries left). FAILED - RETRYING: Monitor and feedback (17 retries left). FAILED - RETRYING: Monitor and feedback (16 retries left). FAILED - RETRYING: Monitor and feedback (15 retries left). FAILED - RETRYING: Monitor and feedback (14 retries left). FAILED - RETRYING: Monitor and feedback (13 retries left). FAILED - RETRYING: Monitor and feedback (12 retries left). FAILED - RETRYING: Monitor and feedback (11 retries left). FAILED - RETRYING: Monitor and feedback (10 retries left). FAILED - RETRYING: Monitor and feedback (9 retries left). changed: [localhost] PLAY RECAP ************************************************************************************************** localhost : ok=3 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0

如上所示,大概在循环11次的时候满足Until条件(任务之间有时间间隔造成的误差),跳出循环,结束执行;

4、不断返回日志的案例

设workflow.sh脚本执行时间久,为了保持jenkins服务器与部署服务器保持连接(设置未通信状态下超时时间为15分钟),则希望不断返回日志;

方式一:使用异步任务执行+async_status模块

- name: 执行脚本
  shell: |
    . ~/.profile && sh workflow.sh > workflow.log
  args: 
    chdir: ~/
  async: 1
  poll: 0
  register: work_stat
 
- name: 监控状态
  async_status: jid={{ work_stat.ansible_job_id }}
  register: task_result
  until: task_result.finished
  retries: 20
  delay: 10

注意:某些脚本如果没有显式退出程序,则永远不会执行完成;

方式二:使用nohup异步+Until轮询进程

剧本如下:

- name: 执行脚本
  shell: |
    . ~/.profile && nohup sh workflow.sh > workflow.log 2>&1 &
  args: 
    chdir: ~/
  ignore_errors:True
 
- name: 监控进程
  shell: |
    ps -ef | grep workflow | grep -v grep | wc -l
  register: processStatus
  until: processStatus.stdout|int < 1
  retries:20
  delay: 10
  ignore_errors: True