如何显示长期 运行 Ansible 任务的进度?
How can I show progress for a long-running Ansible task?
我有一些 Ansible 任务需要执行很长的操作,比如 运行 与 S3 文件夹的同步操作。并不总是很清楚他们是在进步,还是只是卡住了(或者 ssh 连接已经中断),所以显示某种进度输出会很好。如果直接显示命令的 stdout/stderr,我会看到,但 Ansible 会捕获输出。
管道输出返回 is a difficult problem for Ansible to solve in its current form。但是,我可以使用任何 Ansible 技巧来提供某种指示,表明事情仍在发生变化吗?
您可以做几件事,但正如您正确指出的那样,当前形式的 Ansible 并不能真正提供好的解决方案。
官方解决方案:
一个想法是将任务标记为异步并对其进行轮询。显然,这仅适用于能够以这种方式 运行 而不会导致剧本其他地方失败的情况。异步文档是 here,下面是从中提取的示例:
- hosts: all
remote_user: root
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
这至少可以让您 'ping' 知道任务没有挂起。
官方认可的唯一其他方法是 Ansible Tower,它有任务进度条,但不是免费的。
hacky-ish 解决方案:
除上述内容外,您几乎还需要自己动手。您同步 S3 存储桶的具体示例可以通过定期调用 AWS CLI 并计算存储桶中的项目数量的脚本相当容易地进行监控,但这并不是一个好的通用解决方案。
我唯一能想到的有点有效的是从您的一个节点监视传入的 ssh 会话。
为此,您可以将该机器上的 ansible 用户配置为通过屏幕连接并主动观看。或者,也许在该用户的 sudoers 条目中使用 log_output
选项,允许您跟踪文件。 log_output 的详细信息可以在 sudoers man page
上找到
我今天在 OSX 上遇到了这个问题,我当时 运行 一个 docker shell 命令花了很长时间构建而且没有输出虽然它建立。不明白命令是挂起还是进展缓慢,这让人非常沮丧。
我决定将 shell 命令的输出(和错误)通过管道传输到一个端口,然后可以在单独的终端中通过 netcat 收听。
myplaybook.yml
- name: run some long-running task and pipe to a port
shell: myLongRunningApp > /dev/tcp/localhost/4000 2>&1
并在单独的终端中 window:
$ nc -lk 4000
Output from my
long
running
app will appear here
请注意,我将错误输出通过管道传输到同一端口;我可以很容易地通过管道连接到不同的端口。
此外,我最终设置了一个名为 nc_port
的变量,它允许在端口正在使用的情况下更改端口。然后 ansible 任务看起来像:
shell: myLongRunningApp > /dev/tcp/localhost/{{nc_port}} 2>&1
请注意,命令 myLongRunningApp
正在本地主机(即清单中设置的主机)上执行,这就是我使用 nc
.
收听本地主机的原因
如果您使用 Linux,您可以使用 systemd-run
创建瞬态单元并使用 journalctl
检查输出,例如:
sudo systemd-run --unit foo \
bash -c 'for i in {0..10}; do
echo "$((i * 10))%"; sleep 1;
done;
echo "Complete"'
并且在另一个会话中
sudo journalctl -xf --unit foo
它会输出如下内容:
Apr 07 02:10:34 localhost.localdomain systemd[1]: Started /bin/bash -c for i in {0..10}; do echo "$((i * 10))%"; sleep 1; done; echo "Complete".
-- Subject: Unit foo.service has finished start-up
-- Defined-By: systemd
-- Support: https://lists.freedesktop.org/mailman/listinfo/systemd-devel
--
-- Unit foo.service has finished starting up.
--
-- The start-up result is done.
Apr 07 02:10:34 localhost.localdomain bash[10083]: 0%
Apr 07 02:10:35 localhost.localdomain bash[10083]: 10%
Apr 07 02:10:36 localhost.localdomain bash[10083]: 20%
Apr 07 02:10:37 localhost.localdomain bash[10083]: 30%
Apr 07 02:10:38 localhost.localdomain bash[10083]: 40%
Apr 07 02:10:39 localhost.localdomain bash[10083]: 50%
Apr 07 02:10:40 localhost.localdomain bash[10083]: 60%
Apr 07 02:10:41 localhost.localdomain bash[10083]: 70%
Apr 07 02:10:42 localhost.localdomain bash[10083]: 80%
Apr 07 02:10:43 localhost.localdomain bash[10083]: 90%
Apr 07 02:10:44 localhost.localdomain bash[10083]: 100%
Apr 07 02:10:45 localhost.localdomain bash[10083]: Complete
Ansible 此后实现了以下内容:
---
# Requires ansible 1.8+
- name: 'YUM - async task'
yum:
name: docker-io
state: installed
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
有关详细信息,请参阅有关该主题的 official documentation(确保您选择的是 Ansible 版本)。
我有一些 Ansible 任务需要执行很长的操作,比如 运行 与 S3 文件夹的同步操作。并不总是很清楚他们是在进步,还是只是卡住了(或者 ssh 连接已经中断),所以显示某种进度输出会很好。如果直接显示命令的 stdout/stderr,我会看到,但 Ansible 会捕获输出。
管道输出返回 is a difficult problem for Ansible to solve in its current form。但是,我可以使用任何 Ansible 技巧来提供某种指示,表明事情仍在发生变化吗?
您可以做几件事,但正如您正确指出的那样,当前形式的 Ansible 并不能真正提供好的解决方案。
官方解决方案:
一个想法是将任务标记为异步并对其进行轮询。显然,这仅适用于能够以这种方式 运行 而不会导致剧本其他地方失败的情况。异步文档是 here,下面是从中提取的示例:
- hosts: all
remote_user: root
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
这至少可以让您 'ping' 知道任务没有挂起。
官方认可的唯一其他方法是 Ansible Tower,它有任务进度条,但不是免费的。
hacky-ish 解决方案:
除上述内容外,您几乎还需要自己动手。您同步 S3 存储桶的具体示例可以通过定期调用 AWS CLI 并计算存储桶中的项目数量的脚本相当容易地进行监控,但这并不是一个好的通用解决方案。
我唯一能想到的有点有效的是从您的一个节点监视传入的 ssh 会话。
为此,您可以将该机器上的 ansible 用户配置为通过屏幕连接并主动观看。或者,也许在该用户的 sudoers 条目中使用 log_output
选项,允许您跟踪文件。 log_output 的详细信息可以在 sudoers man page
我今天在 OSX 上遇到了这个问题,我当时 运行 一个 docker shell 命令花了很长时间构建而且没有输出虽然它建立。不明白命令是挂起还是进展缓慢,这让人非常沮丧。
我决定将 shell 命令的输出(和错误)通过管道传输到一个端口,然后可以在单独的终端中通过 netcat 收听。
myplaybook.yml
- name: run some long-running task and pipe to a port
shell: myLongRunningApp > /dev/tcp/localhost/4000 2>&1
并在单独的终端中 window:
$ nc -lk 4000
Output from my
long
running
app will appear here
请注意,我将错误输出通过管道传输到同一端口;我可以很容易地通过管道连接到不同的端口。
此外,我最终设置了一个名为 nc_port
的变量,它允许在端口正在使用的情况下更改端口。然后 ansible 任务看起来像:
shell: myLongRunningApp > /dev/tcp/localhost/{{nc_port}} 2>&1
请注意,命令 myLongRunningApp
正在本地主机(即清单中设置的主机)上执行,这就是我使用 nc
.
如果您使用 Linux,您可以使用 systemd-run
创建瞬态单元并使用 journalctl
检查输出,例如:
sudo systemd-run --unit foo \
bash -c 'for i in {0..10}; do
echo "$((i * 10))%"; sleep 1;
done;
echo "Complete"'
并且在另一个会话中
sudo journalctl -xf --unit foo
它会输出如下内容:
Apr 07 02:10:34 localhost.localdomain systemd[1]: Started /bin/bash -c for i in {0..10}; do echo "$((i * 10))%"; sleep 1; done; echo "Complete".
-- Subject: Unit foo.service has finished start-up
-- Defined-By: systemd
-- Support: https://lists.freedesktop.org/mailman/listinfo/systemd-devel
--
-- Unit foo.service has finished starting up.
--
-- The start-up result is done.
Apr 07 02:10:34 localhost.localdomain bash[10083]: 0%
Apr 07 02:10:35 localhost.localdomain bash[10083]: 10%
Apr 07 02:10:36 localhost.localdomain bash[10083]: 20%
Apr 07 02:10:37 localhost.localdomain bash[10083]: 30%
Apr 07 02:10:38 localhost.localdomain bash[10083]: 40%
Apr 07 02:10:39 localhost.localdomain bash[10083]: 50%
Apr 07 02:10:40 localhost.localdomain bash[10083]: 60%
Apr 07 02:10:41 localhost.localdomain bash[10083]: 70%
Apr 07 02:10:42 localhost.localdomain bash[10083]: 80%
Apr 07 02:10:43 localhost.localdomain bash[10083]: 90%
Apr 07 02:10:44 localhost.localdomain bash[10083]: 100%
Apr 07 02:10:45 localhost.localdomain bash[10083]: Complete
Ansible 此后实现了以下内容:
---
# Requires ansible 1.8+
- name: 'YUM - async task'
yum:
name: docker-io
state: installed
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
有关详细信息,请参阅有关该主题的 official documentation(确保您选择的是 Ansible 版本)。