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后,会创建一个时间戳文件;
sleep 20s
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