Anisble 异步执行任务

任务异步执行

通过 asyncpoll 可以设置异步操作和轮询。

Ansible Ad-Hoc 的异步、并发和查询

启动异步任务

[root@awx-1 ansible]# ansible localhost -B 3600 -P 5 -a "sleep 30"
localhost | CHANGED => {
    "ansible_job_id": "j445703768934.50473",
    "changed": true,
    "cmd": [
        "sleep",
        "30"
    ],
    "delta": "0:00:30.003839",
    "end": "2025-04-21 23:31:02.617454",
    "finished": 1,
    "msg": "",
    "rc": 0,
    "results_file": "/root/.ansible_async/j445703768934.50473",
    "start": "2025-04-21 23:30:32.613615",
    "started": 1,
    "stderr": "",
    "stderr_lines": [],
    "stdout": "",
    "stdout_lines": []
}
  • -B:设置超时时间
  • -P:轮询间隔,用于设置任务后台执行
    • 当值不为 0 时,任务后台跑,但是前台不会退出,定期检查结果
    • 当值为 0 时,前台也会推出,后续可以用 ansible.builtin.async_status 模块查询

Ansible 默认同步执行,下表是和异步执行的对比:

特性 默认(前台连接) async 模式(后台运行)
SSH 连接是否保持 ✅ 一直保持 ❌ 执行命令后立即断开
控制节点是否阻塞 ✅ 是 ❌ 不阻塞,立即返回
是否占用连接资源 ✅ 是 ❌ 否
是否适合长任务 ❌ 容易超时、失败 ✅ 非常适合
是否能中途查询状态 ❌ 不行 ✅ 可以用 async_status 查询

使用异步执行任务时,可以通过 --forks 增大并发执行的主机数量

启动并发任务

-p 设置为 0 时,任务为并发任务。

[root@awx-1 ansible]# ansible localhost -B 3600 -P 0 -a "sleep 30"
localhost | CHANGED => {
    "ansible_job_id": "j100035338039.50544",
    "changed": true,
    "finished": 0,
    "results_file": "/root/.ansible_async/j100035338039.50544",
    "started": 1
}

查询异步任务信息

-P 参数为 0 时,任务的完全后台执行,此时需要通过 ansible.builtin.async_status 模块查询:

ansible.builtin.async_status 的介绍在后边。

# 启动一个异步任务
[root@awx-1 ansible]# ansible localhost -B 3600 -P 0 -a "sleep 30"
localhost | CHANGED => {
    "ansible_job_id": "j594674720907.50900",
    "changed": true,
    "finished": 0,
    "results_file": "/root/.ansible_async/j594674720907.50900",
    "started": 1
}

# 查询结果
[root@awx-1 ansible]# ansible localhost -m ansible.builtin.async_status -a "jid=j594674720907.50900"
localhost | CHANGED => {
    "ansible_job_id": "j594674720907.50900",
    "changed": true,
    "cmd": [
        "sleep",
        "30"
    ],
    "delta": "0:00:30.004651",
    "end": "2025-04-21 23:54:24.838790",
    "finished": 1,
    "msg": "",
    "rc": 0,
    "results_file": "/root/.ansible_async/j594674720907.50900",
    "start": "2025-04-21 23:53:54.834139",
    "started": 1,
    "stderr": "",
    "stderr_lines": [],
    "stdout": "",
    "stdout_lines": []
}

# 清理缓存文件
[root@awx-1 ansible]# ansible localhost -m ansible.builtin.async_status -a "jid=j594674720907.50900 mode=cleanup"
localhost | SUCCESS => {
    "ansible_job_id": "j594674720907.50900",
    "changed": false,
    "erased": "/root/.ansible_async/j594674720907.50900",
    "finished": 0,
    "started": 0,
    "stderr": "",
    "stderr_lines": [],
    "stdout": "",
    "stdout_lines": []
}

Playbook 的异步、并发和轮询

异步 Playbook 任务

在对应的 Play 中添加 asyncpoll 就可以设置任务异步执行(注意超时时间)

- name: sleep 30
  ansible.builtin.command: sleep 30
  poll: 5
  async: 300

部分执行结果:

TASK [sleep 30] **********************************************************************
ASYNC POLL on localhost: jid=j503432663133.51123 started=1 finished=0
ASYNC POLL on localhost: jid=j503432663133.51123 started=1 finished=0
ASYNC POLL on localhost: jid=j503432663133.51123 started=1 finished=0
ASYNC POLL on localhost: jid=j503432663133.51123 started=1 finished=0
ASYNC POLL on localhost: jid=j503432663133.51123 started=1 finished=0
ASYNC OK on localhost: jid=j503432663133.51123
changed: [localhost]

async 没有默认值,poll 默认 15s。

并发 Playbook 任务

poll 为 0 时,任务为并发任务:

- name: sleep 30
  ansible.builtin.command: sleep 30
  poll: 0
  async: 300

下边是个例子:

root@awx-1 ansible]# ansible-playbook test.yml

PLAY [test] *******************************************************************************************************************

TASK [sleep 30] ***************************************************************************************************************
changed: [localhost]

PLAY RECAP ********************************************************************************************************************
localhost                  : ok=1    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

[root@awx-1 ansible]# ps -ef | grep sleep
root       51246   51245  0 00:02 ?        00:00:00 sleep 30
root       51248   46905  0 00:02 pts/2    00:00:00 grep --color=auto sleep

可以看到 Playbook 已经结束了,但是 sleep 30 进程还在。

并发任务的轮询

ansible.builtin.async_status

说到并发任务的轮询就要说一下 ansible.builtin.async_status 模块,这个模块用于查询任务的状态。

参数名 类型 默认值 说明
jid str 必须参数。要查询的异步任务的 job ID(任务标识),由前面的任务结果 .ansible_async 中获取。
mode str status 可选值:statuscleanup
- status:默认,查询任务状态;
- cleanup:用于清理任务状态文件。
- name: Asynchronous yum task
  ansible.builtin.yum:
    name: docker-io
    state: present
  async: 1000
  poll: 0
  register: yum_sleeper

- name: Wait for asynchronous job to end
  ansible.builtin.async_status:
    jid: '{{ yum_sleeper.ansible_job_id }}'
  register: job_result
  until: job_result.finished
  retries: 100
  delay: 10

- name: Clean up async file
  ansible.builtin.async_status:
    jid: '{{ yum_sleeper.ansible_job_id }}'
    mode: cleanup
  • async:异步超时时间
  • poll:查询任务结果的间隔,为 0 时不查询任务结果,即任务后台执行,前台结果直接结束
  • register:当前 Play 结果注册成一个变量供后续 Play 使用
  • until:当满足判断时,任务结束
  • delay:任务重试间隔
  • retries:任务重试次数

说一下这个模块的使用逻辑:

  1. Asynchronous yum task Play 用于执行 docker-io 软件包的安装,超时时间为 1000s,并发执行。最后任务注册一个变量名为 yum_sleeper,这个变量有一个子变量名为 ansible_job_id,是任务的 ID;
  2. Wait for asynchronous job to end Play 通过上一个任务注册的变量获取任务 ID,每 10s 进行一次查询,最多重试 100 次。自己注册一个变量名为 job_result,这个变量有一个子变量为 finished,当 finished 为 1 时,任务执行完成;
  3. Clean up async file Play 用于清理缓存文件。

注意 async 的值,如果值不够高,可能会造成任务超时退出。

如果想为任务设置 changed_whencreates 等选项时,需要针对 ansible.builtin.async_status 设置。

Anisble 异步执行任务
https://www.linuxstudynotes.com/2025/06/30/ansible/anisble-%e5%bc%82%e6%ad%a5%e6%89%a7%e8%a1%8c%e4%bb%bb%e5%8a%a1/
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇