Ansible-navigator exec
常用选项和解释
ansible-navigator exec
相当于 podman run -it --rm <image> /bin/bash
(默认为 /bin/bash
),ansible-navigator exec
常用于执行 Ansible Ad-Hoc,
可用选项如下:
参数 | 含义 | 示例 | 默认值 |
---|---|---|---|
exec_command |
指定在执行环境(EE)中运行的命令 | ansible --version |
/bin/bash |
--exshell , --exec-shell |
是否使用 shell 来执行命令(如通过 /bin/sh -c )用于控制是否解释重定向、变量等 shell 特性 |
--exec-shell true / false |
true |
这里单独解释一下 --exec-shell false
:
[root@ansible-controller ansible-navigator]# ansible-navigator exec --exec-shell false -- echo $HOSTNAME
ansible-controller
[root@ansible-controller ansible-navigator]# ansible-navigator exec --exec-shell false -- echo \$HOSTNAME
$HOSTNAME
[root@ansible-controller ansible-navigator]# ansible-navigator exec --exec-shell true -- echo \$HOSTNAME
159ceb83da82
[root@ansible-controller ansible-navigator]# ansible-navigator exec --exec-shell true -- echo $HOSTNAME
ansible-controller
[root@ansible-controller ansible-navigator]# ansible-navigator exec --exec-shell false -- sh -c 'echo $HOSTNAME'
0858792b5a5c
可以看到 --exec-shell false
时,后边接的命令不会被 Shell 做解析,所有的命令都会原封不动的执行(类似 ansible.builtin.command
),变量 HOSTNAME
无法正常打印,再看下边的演示:
[root@ansible-controller ansible-navigator]# ansible-navigator exec --exec-shell false -- echo qwez && echo qwer > /home/testfile
qwez
[root@ansible-controller ansible-navigator]# cat /home/testfile
qwer
[root@ansible-controller ansible-navigator]# ansible-navigator exec --exec-shell false -- echo qwez '&& echo qwer > /home/testfile'
qwez && echo qwer > /home/testfile
[root@ansible-controller ansible-navigator]# ansible-navigator exec --exec-shell false -- echo 'qwez && echo qwer > /home/testfile'
qwez && echo qwer > /home/testfile
[root@ansible-controller ansible-navigator]# ansible-navigator exec --exec-shell false -- 'echo qwez && echo qwer > /home/testfile'
[dumb-init] echo qwez && echo qwer > /home/testfile: No such file or directory
这里强调两个东西:
-
在前两个命令中可以看到
&&
和>
好像执行了,但是这个并不是在容器内执行的,在容器内执行的只有echo qwez
,&&
之后的命令全部是在宿主机执行的。通过cat /home/testfile
可以看出来,/home/
目录并没有挂载到容器内,如果命令是在容器内执行的,宿主机应该没有testfile
文件。 -
最后一个命令可以看到
--exec-shell false
的效果,最后一个命令将echo qwez && echo qwer > /home/testfile
放在一个单引号里了,因为--exec-shell false
,所以echo qwez && echo qwer > /home/testfile
作为整体传递给容器执行,所以会有报错(类似在 Shell 中分别执行ls -l
和'ls -l'
的两种情况)。[root@ansible-controller ansible-navigator]# 'ls -l' -bash: ls -l: command not found [root@ansible-controller ansible-navigator]# ls -l total 196 -rw-r--r--. 1 root root 57 May 25 22:18 ansible.cfg -rw-r--r--. 1 root root 174193 May 25 23:23 ansible-navigator.log -rw-r--r--. 1 root root 6462 May 25 22:57 ansible-navigator.yaml drwxr-xr-x. 3 root root 47 May 26 00:05 artifacts -rw-r--r--. 1 root root 205 May 25 22:18 inventory drwxr-xr-x. 2 root root 6 May 25 22:24 runner-artifacts -rw-r--r--. 1 root root 5 May 25 23:26 testfile -rw-r--r--. 1 root root 105 May 25 22:23 test.yml
最后再演示一个:
[root@ansible-controller ansible-navigator]# ansible-navigator \
--eei quay.io/ansible/awx-ee:24.6.1 exec --exec-shell false -- ansible all -m shell -i inventory -a "echo qwe"
worker1 | CHANGED | rc=0 >>
qwe
master1 | CHANGED | rc=0 >>
qwe
[root@ansible-controller ansible-navigator]# ansible-navigator \
--eei quay.io/ansible/awx-ee:24.6.1 exec --exec-shell true -- ansible all -m shell -i inventory -a \"echo qwe\"
master1 | CHANGED | rc=0 >>
qwe
worker1 | CHANGED | rc=0 >>
qwe
[root@ansible-controller ansible-navigator]# ansible-navigator \
--eei quay.io/ansible/awx-ee:24.6.1 exec --exec-shell true -- ansible all -m shell -i inventory -a '"echo qwe"'
worker1 | CHANGED | rc=0 >>
qwe
master1 | CHANGED | rc=0 >>
qwe
[root@ansible-controller ansible-navigator]# ansible-navigator \
--eei quay.io/ansible/awx-ee:24.6.1 exec --exec-shell true -- ansible all -m shell -i inventory -a "'echo qwe'"
master1 | CHANGED | rc=0 >>
qwe
worker1 | CHANGED | rc=0 >>
qwe
# 这个执行会报错
[root@ansible-controller ansible-navigator]# ansible-navigator \
--eei quay.io/ansible/awx-ee:24.6.1 exec --exec-shell true -- ansible all -m shell -i inventory -a "echo qwe"
这里可以看到 --exec-shell
的两种结果:
- 为
false
时,后边命令就会原封不动的传递给容器去执行,且在容器内不会解析变量、管道符或重定向等 Shell 特性 - 为
true
时,后边的命令会做解析,第一组双引号(或单引号)会被展开,所以引号需要做转义或者多套一层 - 最下边那个报错的命令,
ansible all -m shell -i inventory -a "echo qwe"
在--exec-shell true
时传递给容器的命令是ansible all -m shell -i inventory -a echo qwe
--exec-shell true
有点类似bash -c
,命令传递给容器后先被bash -c
解析,然后再执行。[root@ansible-controller ansible-navigator]# bash -c ansible all -m shell -i inventory -a 'echo qwe' [root@ansible-controller ansible-navigator]# ansible-navigator exec --exec-shell true -- bash -c 'echo $HOME' [root@ansible-controller ansible-navigator]# bash -c 'echo $0 $1' dummy1 dummy2 dummy1 dummy2
常用方式
一次性执行 Ad-Hoc
如果只执行一次命令,那可以用下边这个方式执行,注意 --exec-shell
的使用。
[root@ansible-controller ansible-navigator]# ansible-navigator exec -- ansible all -m ping
master1 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/libexec/platform-python"
},
"changed": false,
"ping": "pong"
}
worker1 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/libexec/platform-python"
},
"changed": false,
"ping": "pong"
}
执行多个 Ad-Hoc
如果要执行多条命令,那么可以先用 bash
命令进入到容器,然后就可以执行多条命令了,这个就不需要考虑 --exec-shell
了。
[root@ansible-controller ansible-navigator]# ansible-navigator --eei quay.io/ansible/awx-ee:24.6.1 exec -- bash
[root@630aacbc6226 ansible-navigator]# ansible all -m shell -a 'echo $HOSTNAME'
worker1 | CHANGED | rc=0 >>
worker1.example.com
master1 | CHANGED | rc=0 >>
master1.example.com
[root@630aacbc6226 ansible-navigator]# ansible all -m shell -a 'id'
worker1 | CHANGED | rc=0 >>
uid=10000(ansible) gid=10000(ansible) groups=10000(ansible),10(wheel) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
master1 | CHANGED | rc=0 >>
uid=10000(ansible) gid=10000(ansible) groups=10000(ansible),10(wheel) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
验证几个选项
验证 --penv
和 --senv
[root@ansible-controller ansible-navigator]# export var1=redhat
[root@ansible-controller ansible-navigator]# export var2=fedora
[root@ansible-controller ansible-navigator]# ansible-navigator \
--eei quay.io/ansible/awx-ee:24.6.1 \
--penv=var1 --penv=var2 --senv=var3=debian --senv=var4=ubuntu exec -- bash
[root@7206dce5a2bb ansible-navigator]# env | grep var
var4=ubuntu
var1=redhat
var2=fedora
var3=debian
# 重新开一个命令行来查看容器属性
[root@ansible-controller ~]# podman inspect 7206dce5a2bb | jq .[0].HostConfig.Binds
[
"/root/ansible-navigator:/root/ansible-navigator/:rw,rprivate,rbind",
"/root/.ssh:/home/runner/.ssh/:rw,rprivate,rbind",
"/root/.ssh:/root/.ssh/:rw,rprivate,rbind",
"/tmp/ansible-navigator_loksnc9v/artifacts:/runner/artifacts/:rw,rprivate,rbind",
"/tmp/ansible-navigator_loksnc9v:/runner/:rw,rprivate,rbind",
"/mnt:/mnt:rw,rprivate,rbind"
]
Ansible-navigator run
ansible-navigator run
是通过ansible-runner
接口来调用容器的,ansible-runner
是一套标准的接口,现在不熟,不做过多介绍。
可用选项
ansible-navigator run
用于在容器内执行 Playbook 剧本,可选参数如下:
参数 | 含义 | 示例 | 默认值 |
---|---|---|---|
playbook |
指定要运行的 Playbook 名称 | site.yml |
必填,无默认值 |
-i , --inventory |
指定 inventory 文件路径或以逗号分隔的主机列表 | -i inventory.yml / -i host1,host2 |
inventory (当前目录) |
--ic , --inventory-column |
指定在交互式 inventory 视图中显示的主机属性列 | --ic ansible_host |
空(仅显示主机名) |
--ep , --enable-prompts |
启用密码/交互提示(如 --ask-vault-pass 、pause 、vars_prompt 等),会强制启用 stdout 模式并禁用 artifact 生成 |
--ep |
添加选项为 true ,不加为 false |
--hp , --help-playbook |
显示 ansible-playbook 的命令行帮助 |
--hp |
添加选项为 true ,不加为 false |
--pae , --playbook-artifact-enable |
是否启用 playbook 执行完成后的 artifact 生成;当启用 --ep 或交互提示时,这个选线无效(前置不生成 artifact ) |
--pae false |
true |
--pas , --playbook-artifact-save-as |
自定义 artifact 保存路径模板;支持 playbook_dir 、playbook_name 、time_stamp 、playbook_status 这些占位符 |
--pas ./artifacts/{playbook_name}-{time_stamp}.json |
{playbook_dir}/{playbook_name}-artifact-{time_stamp}.json |
ansible-navigator run
在执行 Playbook 的时候还会将记录保存下来,总共保存在两个位置:
- 一个位置保存 Playbook 执行过程中的运行输出、事件日志、执行状态等,通过
--rad
设置 - 另一个位置保存执行结果,可以用来回放过程,通过
--pas
设置
ansible-navigator
通过replay
子选项进行回放,后边介绍。还要提一下
--ep
选项,这个用于执行 Ansible Playbook 输入密码的情况。
执行一个 Playbook 并检查相关日志
# 需要提前创建 --rad 选项的目录
[root@ansible-controller ansible-navigator]# mkdir ./runner-artifacts
# 执行任务
[root@ansible-controller ansible-navigator]# ansible-navigator \
--eei quay.io/ansible/awx-ee:24.6.1 \
--ll debug --la false --lf ./log/ansible-navigator.log \
-m stdout \
--rwje --rac 2 --rad ./runner-artifacts \
--penv=var1 --penv=var2 --senv=var3=debian --senv=var4=ubuntu \
--eev=/media:/media --eev=/mnt:/mnt:Z \
run test.yml \
--pas ./artifacts/{playbook_name}/{playbook_name}-{time_stamp}.json
# 检查生成的文件
[root@ansible-controller ansible-navigator]# tree log/
log/
└── ansible-navigator.log
0 directories, 1 file
[root@ansible-controller ansible-navigator]# tree artifacts/
artifacts/
└── test
└── test-2025-05-26T16:45:40.328121+00:00.json
1 directory, 1 file
[root@ansible-controller ansible-navigator]# tree runner-artifacts/
runner-artifacts/
├── artifacts
│ └── d1fd6023-1a25-4d93-b6c3-b911e91cd3ec
│ ├── callback
│ │ ├── awx_display.py
│ │ ├── __init__.py
│ │ └── __pycache__
│ │ ├── awx_display.cpython-312.pyc
│ │ ├── awx_display.cpython-39.pyc
│ │ └── __init__.cpython-312.pyc
│ ├── command
│ ├── env.list
│ ├── fact_cache
│ │ ├── master1
│ │ └── worker1
│ ├── job_events
│ │ ├── 1-030ab97d-65bf-4c7e-a5ff-5f04a59c039a.json
│ │ ├── 10-b2e3ded2-60d3-4c17-a572-618b562056d6.json
│ │ ├── 11-93351125-e519-4835-84d8-204838e69d55.json
│ │ ├── 12-96fc4af3-78e3-4f2d-9ee6-b8f55c3b657a.json
│ │ ├── 13-328b306a-e143-429a-9222-6e15651df522.json
│ │ ├── 2-367432dc-2a88-ca5d-1570-000000000003.json
│ │ ├── 3-367432dc-2a88-ca5d-1570-000000000009.json
│ │ ├── 4-3bc02273-8897-436d-818c-aaaf933b3c01.json
│ │ ├── 5-c3048ff9-fa85-4142-8178-b1c97f98570e.json
│ │ ├── 6-a14b6db9-2924-47ff-8f96-969eceb5696f.json
│ │ ├── 7-73a43174-74d3-4a00-b2b0-10fe3361c783.json
│ │ ├── 8-367432dc-2a88-ca5d-1570-000000000005.json
│ │ └── 9-c92f12ed-e5b7-44ca-bae6-101386c52297.json
│ ├── rc
│ ├── status
│ ├── stderr
│ └── stdout
└── project
7 directories, 26 files
这里有多个文件产生,我们挨个来看。
ansible-navigator 日志
通过 --ll debug --la false --lf ./log/ansible-navigator.log
设置了日志等级,日志写入模式和日志文件名,日志文件里记录了执行过程中 ansible-navigator
命令做了什么:
[root@ansible-controller ansible-navigator]# head log/ansible-navigator.log
2025-05-26T16:45:37.880030+00:00 INFO 'ansible_navigator.setup_logger' New ansible-navigator instance, logging initialized
2025-05-26T16:45:37.880246+00:00 INFO 'ansible_navigator.setup_logger' New ansible-runner instance, logging initialized
2025-05-26T16:45:37.880288+00:00 DEBUG 'ansible_navigator.main' Jinja2==3.1.6
2025-05-26T16:45:37.880312+00:00 DEBUG 'ansible_navigator.main' MarkupSafe==3.0.2
2025-05-26T16:45:37.880332+00:00 DEBUG 'ansible_navigator.main' Parsley==1.3
2025-05-26T16:45:37.880349+00:00 DEBUG 'ansible_navigator.main' PyYAML==6.0.2
2025-05-26T16:45:37.880366+00:00 DEBUG 'ansible_navigator.main' ansible-builder==3.1.0
2025-05-26T16:45:37.880380+00:00 DEBUG 'ansible_navigator.main' ansible-compat==25.5.0
2025-05-26T16:45:37.880395+00:00 DEBUG 'ansible_navigator.main' ansible-core==2.18.6
2025-05-26T16:45:37.880409+00:00 DEBUG 'ansible_navigator.main' ansible-lint==25.4.0
[root@ansible-controller ansible-navigator]# tail log/ansible-navigator.log
2025-05-26T16:45:39.837575+00:00 DEBUG 'ansible_navigator.actions.run_playbook._dequeue' Drained 1 events
2025-05-26T16:45:39.839389+00:00 DEBUG 'ansible_navigator.runner.base._event_handler' ansible-runner event handle: {'uuid': '93351125-e519-4835-84d8-204838e69d55', 'counter': 11, 'stdout': '\x1b[0;32mok: [master1] => {\x1b[0m\r\n\x1b[0;32m "msg": "he"\x1b[0m\r\n\x1b[0;32m}\x1b[0m', 'start_line': 8, 'end_line': 11, 'runner_ident': 'd1fd6023-1a25-4d93-b6c3-b911e91cd3ec', 'event': 'runner_on_ok', 'pid': 15, 'created': '2025-05-26T16:45:39.838033+00:00', 'parent_uuid': '367432dc-2a88-ca5d-1570-000000000005', 'event_data': {'playbook': '/root/ansible-navigator/test.yml', 'playbook_uuid': '030ab97d-65bf-4c7e-a5ff-5f04a59c039a', 'play': 'qwe', 'play_uuid': '367432dc-2a88-ca5d-1570-000000000003', 'play_pattern': 'all', 'task': 'debug', 'task_uuid': '367432dc-2a88-ca5d-1570-000000000005', 'task_action': 'debug', 'resolved_action': 'ansible.builtin.debug', 'task_args': '', 'task_path': '/root/ansible-navigator/test.yml:6', 'host': 'master1', 'remote_addr': 'master1', 'res': {'msg': 'he', '_ansible_verbose_always': True, '_ansible_no_log': False, 'changed': False}, 'start': '2025-05-26T16:45:39.823525+00:00', 'end': '2025-05-26T16:45:39.837810+00:00', 'duration': 0.014285, 'event_loop': None, 'uuid': '93351125-e519-4835-84d8-204838e69d55'}}
2025-05-26T16:45:39.847728+00:00 DEBUG 'ansible_navigator.runner.base._event_handler' ansible-runner event handle: {'uuid': '96fc4af3-78e3-4f2d-9ee6-b8f55c3b657a', 'counter': 12, 'stdout': '\x1b[0;32mok: [worker1] => {\x1b[0m\r\n\x1b[0;32m "msg": "he"\x1b[0m\r\n\x1b[0;32m}\x1b[0m', 'start_line': 11, 'end_line': 14, 'runner_ident': 'd1fd6023-1a25-4d93-b6c3-b911e91cd3ec', 'event': 'runner_on_ok', 'pid': 15, 'created': '2025-05-26T16:45:39.847023+00:00', 'parent_uuid': '367432dc-2a88-ca5d-1570-000000000005', 'event_data': {'playbook': '/root/ansible-navigator/test.yml', 'playbook_uuid': '030ab97d-65bf-4c7e-a5ff-5f04a59c039a', 'play': 'qwe', 'play_uuid': '367432dc-2a88-ca5d-1570-000000000003', 'play_pattern': 'all', 'task': 'debug', 'task_uuid': '367432dc-2a88-ca5d-1570-000000000005', 'task_action': 'debug', 'resolved_action': 'ansible.builtin.debug', 'task_args': '', 'task_path': '/root/ansible-navigator/test.yml:6', 'host': 'worker1', 'remote_addr': 'worker1', 'res': {'msg': 'he', '_ansible_verbose_always': True, '_ansible_no_log': False, 'changed': False}, 'start': '2025-05-26T16:45:39.833500+00:00', 'end': '2025-05-26T16:45:39.846936+00:00', 'duration': 0.013436, 'event_loop': None, 'uuid': '96fc4af3-78e3-4f2d-9ee6-b8f55c3b657a'}}
2025-05-26T16:45:39.848193+00:00 DEBUG 'ansible_navigator.actions.run_playbook._dequeue' Drained 2 events
2025-05-26T16:45:39.880018+00:00 DEBUG 'ansible_navigator.runner.base._event_handler' ansible-runner event handle: {'uuid': '328b306a-e143-429a-9222-6e15651df522', 'counter': 13, 'stdout': '\r\nPLAY RECAP *********************************************************************\r\n\x1b[0;32mmaster1\x1b[0m : \x1b[0;32mok=2 \x1b[0m changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 \r\n\x1b[0;32mworker1\x1b[0m : \x1b[0;32mok=2 \x1b[0m changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 ', 'start_line': 14, 'end_line': 19, 'runner_ident': 'd1fd6023-1a25-4d93-b6c3-b911e91cd3ec', 'event': 'playbook_on_stats', 'pid': 15, 'created': '2025-05-26T16:45:39.879084+00:00', 'parent_uuid': '030ab97d-65bf-4c7e-a5ff-5f04a59c039a', 'event_data': {'playbook': '/root/ansible-navigator/test.yml', 'playbook_uuid': '030ab97d-65bf-4c7e-a5ff-5f04a59c039a', 'changed': {}, 'dark': {}, 'failures': {}, 'ignored': {}, 'ok': {'master1': 2, 'worker1': 2}, 'processed': {'master1': 1, 'worker1': 1}, 'rescued': {}, 'skipped': {}, 'artifact_data': {}, 'uuid': '328b306a-e143-429a-9222-6e15651df522'}}
2025-05-26T16:45:39.889901+00:00 DEBUG 'ansible_navigator.actions.run_playbook._dequeue' Drained 1 events
2025-05-26T16:45:40.328152+00:00 DEBUG 'ansible_navigator.actions.run_playbook.write_artifact' Formatted artifact file name set to ./artifacts/test/test-2025-05-26T16:45:40.328121+00:00.json
2025-05-26T16:45:40.328311+00:00 DEBUG 'ansible_navigator.actions.run_playbook.write_artifact' Resolved artifact file name set to /root/ansible-navigator/artifacts/test/test-2025-05-26T16:45:40.328121+00:00.json
2025-05-26T16:45:40.330785+00:00 INFO 'ansible_navigator.actions.run_playbook.write_artifact' Saved artifact as /root/ansible-navigator/artifacts/test/test-2025-05-26T16:45:40.328121+00:00.json
2025-05-26T16:45:40.330831+00:00 DEBUG 'ansible_navigator.actions.run_playbook.run_stdout' runner finished
ansible-navigator 执行的结果
--pas ./artifacts/{playbook_name}/{playbook_name}-{time_stamp}.json
设置 Playbook 执行的结果保存的文件,默认 json
格式:
[root@ansible-controller ansible-navigator]# head -n20 artifacts/test/test-2025-05-26T16\:45\:40.328121+00\:00.json
{
"plays": [
{
"__play_name": "qwe",
"name": "qwe",
"pattern": "all",
"play": "qwe",
"play_pattern": "all",
"play_uuid": "367432dc-2a88-ca5d-1570-000000000003",
"playbook": "/root/ansible-navigator/test.yml",
"playbook_uuid": "030ab97d-65bf-4c7e-a5ff-5f04a59c039a",
"tasks": [
{
"__changed": false,
"__duration": "1s",
"__host": "master1",
"__number": 0,
"__result": "Ok",
"__task": "Gathering Facts",
"__task_action": "gather_facts",
[root@ansible-controller ansible-navigator]# tail artifacts/test/test-2025-05-26T16\:45\:40.328121+00\:00.json
"\u001b[0;32mok: [worker1] => {\u001b[0m",
"\u001b[0;32m \"msg\": \"he\"\u001b[0m",
"\u001b[0;32m}\u001b[0m",
"",
"PLAY RECAP *********************************************************************",
"\u001b[0;32mmaster1\u001b[0m : \u001b[0;32mok=2 \u001b[0m changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 ",
"\u001b[0;32mworker1\u001b[0m : \u001b[0;32mok=2 \u001b[0m changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 "
],
"version": "2.0.0"
}
这个文件可以用于回放,后边介绍。
ansible-navigator 执行过程中事件的记录和任务状态
--rwje --rac 2 --rad ./runner-artifacts
设置了事件和任务状态记录在哪,并且最多保留几个:
# 一个任务的事件目录
[root@ansible-controller ansible-navigator]# ll runner-artifacts/artifacts/
total 0
drwx------. 5 root root 141 May 27 00:45 d1fd6023-1a25-4d93-b6c3-b911e91cd3ec
# 所有任务事件相关文件
[root@ansible-controller ansible-navigator]# ls runner-artifacts/artifacts/d1fd6023-1a25-4d93-b6c3-b911e91cd3ec/
callback command env.list fact_cache job_events rc status stderr stdout
# 查看任务执行是否成功
[root@ansible-controller ansible-navigator]# cat runner-artifacts/artifacts/d1fd6023-1a25-4d93-b6c3-b911e91cd3ec/rc && echo
0
[root@ansible-controller ansible-navigator]# cat runner-artifacts/artifacts/d1fd6023-1a25-4d93-b6c3-b911e91cd3ec/status && echo
successful
# 列出事实变量缓存文件
[root@ansible-controller ansible-navigator]# ls runner-artifacts/artifacts/d1fd6023-1a25-4d93-b6c3-b911e91cd3ec/fact_cache/
master1 worker1
# 所有事件分文件记录
[root@ansible-controller ansible-navigator]# ls runner-artifacts/artifacts/d1fd6023-1a25-4d93-b6c3-b911e91cd3ec/job_events/
1-030ab97d-65bf-4c7e-a5ff-5f04a59c039a.json 13-328b306a-e143-429a-9222-6e15651df522.json 5-c3048ff9-fa85-4142-8178-b1c97f98570e.json 9-c92f12ed-e5b7-44ca-bae6-101386c52297.json
10-b2e3ded2-60d3-4c17-a572-618b562056d6.json 2-367432dc-2a88-ca5d-1570-000000000003.json 6-a14b6db9-2924-47ff-8f96-969eceb5696f.json
11-93351125-e519-4835-84d8-204838e69d55.json 3-367432dc-2a88-ca5d-1570-000000000009.json 7-73a43174-74d3-4a00-b2b0-10fe3361c783.json
12-96fc4af3-78e3-4f2d-9ee6-b8f55c3b657a.json 4-3bc02273-8897-436d-818c-aaaf933b3c01.json 8-367432dc-2a88-ca5d-1570-000000000005.json
# 每一个文件记录一个事件
[root@ansible-controller ansible-navigator]# cat runner-artifacts/artifacts/d1fd6023-1a25-4d93-b6c3-b911e91cd3ec/job_events/8-367432dc-2a88-ca5d-1570-000000000005.json | jq
{
"uuid": "367432dc-2a88-ca5d-1570-000000000005",
"counter": 8,
"stdout": "\r\nTASK [debug] *******************************************************************",
"start_line": 6,
"end_line": 8,
"runner_ident": "d1fd6023-1a25-4d93-b6c3-b911e91cd3ec",
"event": "playbook_on_task_start",
"pid": 15,
"created": "2025-05-26T16:45:39.822701+00:00",
"parent_uuid": "367432dc-2a88-ca5d-1570-000000000003",
"event_data": {
"playbook": "/root/ansible-navigator/test.yml",
"playbook_uuid": "030ab97d-65bf-4c7e-a5ff-5f04a59c039a",
"play": "qwe",
"play_uuid": "367432dc-2a88-ca5d-1570-000000000003",
"play_pattern": "all",
"task": "debug",
"task_uuid": "367432dc-2a88-ca5d-1570-000000000005",
"task_action": "debug",
"resolved_action": "ansible.builtin.debug",
"task_args": "",
"task_path": "/root/ansible-navigator/test.yml:6",
"name": "debug",
"is_conditional": false,
"uuid": "367432dc-2a88-ca5d-1570-000000000005"
}
}
# 变量记录
[root@ansible-controller ansible-navigator]# cat runner-artifacts/artifacts/d1fd6023-1a25-4d93-b6c3-b911e91cd3ec/env.list && echo
ANSIBLE_UNSAFE_WRITES=1
AWX_ISOLATED_DATA_DIR=/runner/artifacts/d1fd6023-1a25-4d93-b6c3-b911e91cd3ec
ANSIBLE_CACHE_PLUGIN_CONNECTION=/runner/artifacts/d1fd6023-1a25-4d93-b6c3-b911e91cd3ec/fact_cache
var3=debian
var4=ubuntu
var1=redhat
var2=fedora
ANSIBLE_CALLBACK_PLUGINS=/runner/artifacts/d1fd6023-1a25-4d93-b6c3-b911e91cd3ec/callback
ANSIBLE_STDOUT_CALLBACK=awx_display
ANSIBLE_RETRY_FILES_ENABLED=False
ANSIBLE_HOST_KEY_CHECKING=False
ANSIBLE_CACHE_PLUGIN=jsonfile
# 执行容器的命令
[root@ansible-controller ansible-navigator]# cat runner-artifacts/artifacts/d1fd6023-1a25-4d93-b6c3-b911e91cd3ec/command | jq
{
"command": [
"podman",
"run",
"--rm",
"--tty",
"--interactive",
"-v",
"/root/ansible-navigator/:/root/ansible-navigator/",
"--workdir",
"/root/ansible-navigator",
"-v",
"/root/.ssh/:/home/runner/.ssh/",
"-v",
"/root/.ssh/:/root/.ssh/",
"--group-add=root",
"--ipc=host",
"-v",
"/root/ansible-navigator/runner-artifacts/artifacts/:/runner/artifacts/:Z",
"-v",
"/root/ansible-navigator/runner-artifacts/:/runner/:Z",
"-v",
"/media:/media",
"-v",
"/mnt:/mnt:Z",
"--env-file",
"/root/ansible-navigator/runner-artifacts/artifacts/d1fd6023-1a25-4d93-b6c3-b911e91cd3ec/env.list",
"--quiet",
"--name",
"ansible_runner_d1fd6023-1a25-4d93-b6c3-b911e91cd3ec",
"--user=root",
"quay.io/ansible/awx-ee:24.6.1",
"ansible-playbook",
"/root/ansible-navigator/test.yml",
"-i",
"/root/ansible-navigator/inventory"
],
"cwd": "/root/ansible-navigator",
"env": {
"ANSIBLE_UNSAFE_WRITES": "1",
"AWX_ISOLATED_DATA_DIR": "/runner/artifacts/d1fd6023-1a25-4d93-b6c3-b911e91cd3ec",
"ANSIBLE_CACHE_PLUGIN_CONNECTION": "/runner/artifacts/d1fd6023-1a25-4d93-b6c3-b911e91cd3ec/fact_cache",
"var3": "debian",
"var4": "ubuntu",
"var1": "redhat",
"var2": "fedora",
"ANSIBLE_CALLBACK_PLUGINS": "/runner/artifacts/d1fd6023-1a25-4d93-b6c3-b911e91cd3ec/callback",
"ANSIBLE_STDOUT_CALLBACK": "awx_display",
"ANSIBLE_RETRY_FILES_ENABLED": "False",
"ANSIBLE_HOST_KEY_CHECKING": "False",
"ANSIBLE_CACHE_PLUGIN": "jsonfile"
}
}
job_events
目录下的文件只有设置--rwje
后才会生成。
fact_cache
需要设置fact_caching=jsonfile
,并且fact_caching_connection=
有设置目录,比方说fact_caching_connection=./cache
才会将事实变量缓存到文件中。
stdout
文件和stderr
文件没有演示,但是看名字也能猜出来了,前者是用来记录标准输出,后者是用来记录错误输出的。可以通过
command
文件的内容可以看到ansible-navigator
是如何启动容器的,同时也可以验证之前的一些容器相关选项,比方说--eev
、--penv
和--senv
。
上边的 d1fd6023-1a25-4d93-b6c3-b911e91cd3ec
是一次任务的事件记录,再次执行任务会出现新的目录记录事件:
[root@ansible-controller ansible-navigator]# ls runner-artifacts/artifacts/
be5683e0-908c-4d66-a149-4ea835921b70 d1fd6023-1a25-4d93-b6c3-b911e91cd3ec
因为设置了 --rac 2
,所以最多保存 2 个事件记录,所以 runner-artifacts/artifacts/
下最多有两个目录,再次执行任务检查这个目录会发现 d1fd6023-1a25-4d93-b6c3-b911e91cd3ec
被删除了:
[root@ansible-controller ansible-navigator]# ls runner-artifacts/artifacts/
0ba4a2ed-ad87-46cc-ab37-b44fa0162058 be5683e0-908c-4d66-a149-4ea835921b70
最后提一个,
ansible-navigator run
执行 Playbook 时,如果想要缓存事实变量的话只支持jsonfile
模式。
在执行 Playbook 时手动输入信息
如果在执行 Playbook 时需要手动输入信息,需要添加 --ep
选项:
[root@ansible-controller ansible-navigator]# ansible-navigator \
--eei quay.io/ansible/awx-ee:24.6.1 \
--ll debug --la false --lf ./log/ansible-navigator.log \
-m stdout \
--rwje --rac 2 --rad ./runner-artifacts \
--penv=var1 --penv=var2 --senv=var3=debian --senv=var4=ubuntu \
--eev=/media:/media --eev=/mnt:/mnt:Z \
run test.yml \
--pas ./artifacts/{playbook_name}/{playbook_name}-{time_stamp}.json \
--ep -- --become --ask-become-pass
BECOME password:
PLAY [qwe] ************************
TASK [Gathering Facts] ************
ok: [worker1]
ok: [master1]
...output omitted...
这里强调两点:
--ep
后,就不会生成.json
结尾的那个可回放的日志文件- 最后边可以看到
-- --become --ask-become-pass
,这里的--
作用是将后边的--become --ask-become-pass
参数传递给容器内的ansible
而不是被ansible-navigator
命令解析