- 本文涵盖了文档的两大核心内容:
-
异步任务相关模块(
async
配置、wait_for
、async_status
)的用法与示例; -
内容重用机制(
import
/include
关键字在 Playbook 级别和 Task 级别的应用)。 整体概括了文档中关于 Ansible 任务异步执行、依赖控制及模块化管理的核心知识点。
配置 async
1. 示例一:超时中断的异步异步任务(sleep 10,async:5,poll:2)
---
- name: connection
hosts: node1
tasks:
- name: conneciton
shell: sleep 10
async: 5
poll: 2
--任务执行sleep 10(需要 10 秒),但async:5限制任务最长运行 5 秒。
--poll:2表示 Ansible 会每 2 秒主动检查任务是否完成。
--当 5 秒超时后,Ansible 会强制终止未完成的sleep 10任务。
2. 示例二:完全后台的异步下载任务(get_url,async:100,poll:0)
---
- name: connection
hosts: node1
tasks:
- name: download
get_url:
url: http://192.168.48.100/ISOS/openEuler-24.03-LTS-x86_64-dvd.iso
dest: /home/lyk
async: 100
poll: 0
--get_url用于下载 ISO 文件,async:100允许任务最多运行 100 秒。
--poll:0表示 Ansible 提交任务后立即返回,不等待结果(完全异步)。
--任务在后台执行,100 秒内未完成会被终止;若 100 秒内完成则正常生成文件。
--总结:任务在后台异步执行,Ansible 不实时等待,需手动检查结果(如文件是否生成)。
3. 示例三:变相同步的异步任务(sleep 10,async:0,poll:2)
---
- name: connection
hosts: node1
tasks:
- name: conneciton
shell: sleep 10
async: 0
poll: 2
--async:0是特殊值,表示不设置超时(任务可一直运行直到完成)。
--poll:2表示 Ansible 会每 2 秒检查一次任务状态,直到任务结束。
--实际效果等同于同步执行(Ansible 会等待sleep 10完成后再继续)。
wait_for 模块
示例一:等待文件创建的 wait_for 任务
---
- name: test wait for
hosts: node1
tasks:
- shell: sleep 10 && touch /tmp/hello
# async时间要大于sleep的时间
async: 20
poll: 0
register: out
- name: wait for create /tmp/hello
wait_for:
path: /tmp/hello
state: present
delay: 5
timeout: 30
sleep: 2
分析:
第一个任务通过 async:20 和 poll:0 在后台执行 sleep 10 && touch /tmp/hello(10 秒后创建 /tmp/hello 文件),并将结果注册到 out。
第二个任务使用 wait_for 模块等待 /tmp/hello 出现:
path: /tmp/hello 指定目标文件路径;
state: present 表示等待文件存在;
delay:5 延迟 5 秒后开始检查(避免过早检查);
timeout:30 最长等待 30 秒(超过则失败);
sleep:2 每 2 秒检查一次文件状态。
作用:确保后续任务在 /tmp/hello 文件创建后再执行,解决异步任务的依赖问题。
示例二:等待主机重启后恢复连接的 wait_for 任务
---
- name: test wait_for
hosts: node1,node2
tasks:
- name: reboot node1
shell: shutdown -r now "Ansible updates triggered"
async: 1
poll: 0
when: inventory_hostname == "node1"
- name: wait for node1 come back
wait_for:
host: node1
port: 22
state: started
delay: 10
sleep: 2
timeout: 300
when: inventory_hostname == "node2"
第一个任务仅在 node1 上执行 shutdown -r now 重启,并通过 async:1 和 poll:0 立即返回(避免被重启中断)。
第二个任务在 node2 上执行,使用 wait_for 等待 node1 重启后恢复 SSH 连接:
host: node1 指定目标主机;
port:22 检查 SSH 端口(22);
state: started 表示等待端口处于可连接状态;
delay:10 延迟 10 秒开始检查(给重启留出时间);
sleep:2 每 2 秒检查一次端口状态;
timeout:300 最长等待 300 秒(5 分钟)。
作用:在多主机场景中,确保 node1 重启并恢复连接后,再执行后续依赖于 node1 的任务。
async_status 模块
示例:用 async_status 跟踪异步任务状态
---
- name: test async_status
hosts: node1
tasks:
- shell: sleep 10
async: 20
poll: 0
register: out
- name: wait for
async_status:
# 通过任务的 ansible_job_id 属性跟踪任务
jid: "{{ out.ansible_job_id }}"
register: job_result
# 根据当前任务执行结果的finished值,判断跟踪任务是否执行完成
until: job_result.finished
retries: 30
delay: 2
[lyk@controller web 10:13:44]$ ansible-playbook playbook.yml
PLAY [test async_status] ***************************************************************************************
TASK [Gathering Facts] *****************************************************************************************
ok: [node1]
TASK [shell] ***************************************************************************************************
changed: [node1]
TASK [wait for] ************************************************************************************************
FAILED - RETRYING: wait for (30 retries left).
FAILED - RETRYING: wait for (29 retries left).
FAILED - RETRYING: wait for (28 retries left).##显示等待
FAILED - RETRYING: wait for (27 retries left).
分析:
第一个任务执行 sleep 10(需 10 秒完成),通过 async:20(允许最长 20 秒)和 poll:0(完全后台运行)设置为异步任务,并将结果注册到 out(包含任务 ID ansible_job_id)。
第二个任务使用 async_status 模块跟踪上述异步任务:
jid: "{{ out.ansible_job_id }}" 通过任务 ID 关联到异步任务;
register: job_result 记录跟踪结果;
until: job_result.finished 表示持续等待,直到异步任务完成(finished 为 true);
retries:30 和 delay:2 表示每 2 秒检查一次状态,最多重试 30 次(总等待 60 秒,远超过 sleep 10 的耗时)。
执行输出中 “FAILED - RETRYING” 是正常提示,表明 async_status 正在循环检查任务状态,直到异步任务完成。
作用:通过任务 ID 主动跟踪异步任务的执行进度,确保后续操作在异步任务完成后再执行,解决纯异步任务的依赖问题。
Including 和 importing 文件
1. 场景背景:Playbook 的模块化拆分需求
当 Playbook 内容冗长或逻辑复杂时,可拆分为多个独立文件,通过模块化方式组合,便于维护和跨项目重用。Ansible 提供了 include
(动态)和 import
(静态)两类关键字实现内容重用,其中旧版 include
功能将在 2.12 版本移除。
[lyk@controller web 10:15:02]$ ansible-doc -l|grep -e ^import -e ^include
import_playbook Import a playbook
include_vars Load variables from files, dynamically within...
import_role Import a role into a play
include_role Load and execute a role
include_tasks Dynamically include a task list
include Include a play or task list
import_tasks Import a task list
2. 可用的重用关键字
通过 ansible-doc
可查看相关关键字:
import_playbook # 导入外部 Playbook
include_vars # 动态加载变量文件
import_role # 静态导入角色到 Play 中
include_role # 动态加载并执行角色
include_tasks # 动态包含任务列表
include # 包含 Play 或任务列表(旧版,即将移除)
import_tasks # 静态导入任务列表
3. Playbook 级别重用:import_playbook
用法
import_playbook
用于在主 Playbook 中导入完整的外部 Playbook,仅能在 Play 级别使用,导入的多个 Playbook 按顺序执行。
4. 示例:通过 import_playbook
组合多服务部署
主 Playbook:按顺序导入子 Playbook
- name: prepare the web server
import_playbook: pre_web.yml
- name: prepare the vsftpd server
import_playbook: pre_vsftpd.yml
- name: prepare the databse server
import_playbook: pre_db.yml
子 Playbook 1:pre_web.yml
(部署 Web 服务)
cat > pre_web.yml << EOF
- name: Play web
hosts: node1
tasks:
- name: install httpd
yum:
name: httpd
state: present
EOF
子 Playbook 2:pre_vsftpd.yml
(部署 FTP 服务)
cat > pre_vsftpd.yml << EOF
- name: Play vsftpd
hosts: node1
tasks:
- name: install vsftpd
yum:
name: vsftpd
state: present
EOF
子 Playbook 3:pre_db.yml
(部署数据库服务)
cat > pre_db.yml << EOF
- name: Play db
hosts: node1
tasks:
- name: install mariadb-server
yum:
name: mariadb-server
state: present
EOF
5. 执行逻辑:按导入顺序依次运行
- 执行主 Playbook 时,Ansible 会按照
pre_web.yml
→pre_vsftpd.yml
→pre_db.yml
的顺序,依次在node1
上执行各子 Playbook 中的任务,实现 Web、FTP、数据库服务的分步部署。这种方式将不同服务的部署逻辑拆分到独立文件,提升了 Playbook 的可读性和可维护性。
task 级别
示例:
-
主剧本内容如下:
--- - name: Install web server # 剧本名称:安装Web服务器 hosts: node1 # 目标主机:仅在node1上执行 tasks: - name: import a task file # 任务名称:导入任务文件 import_tasks: tasks.yaml # 静态导入tasks.yaml中的任务 #include: tasks.yaml # 旧版动态包含(即将废弃) #include_tasks: tasks.yaml
-
tasks.yaml 内容如下:
- name: Install the httpd # 子任务1:安装httpd软件 yum: name: httpd state: present # 确保httpd已安装 - name: Starts httpd # 子任务2:启动httpd服务 service: name: httpd state: started # 确保httpd处于运行状态