我遇到了以下问题。我使用 Ansible 在远程服务器上运行安装脚本,该脚本最终重新启动了服务器。结果,任务以“无法通过 ssh 连接到主机:连接已关闭”失败结束。我使用它来ignore_unreachable: true
防止任务失败,但我的主要问题是我希望能够看到任务的标准输出。出于某种原因,对于以服务器关闭连接结束的任务,stderr 和 stdout 似乎都不存在。
更糟糕的是,安装脚本以非特权用户身份运行,但在某些时候会要求输入 sudo 密码,出于各种原因,我无法NOPASSWD
在 sudoers 配置中为该用户使用选项。为了解决这个问题,我最终决定使用expect
模块运行脚本:
- name: Launch installer script
expect:
command: "./install.sh"
chdir: "{{ installer_directory }}"
creates: "{{ product_base_directory }}/uninstall.sh"
responses: "{{ sudo_password_prompt | items2dict}}"
timeout: 1200 # 20 minutes
ignore_errors: true
ignore_unreachable: true
register: install_script_output
- name: "Display installer script output"
debug:
msg:
stdout: "{{ install_script_output.stdout_lines | default([]) }}"
stderr: "{{ install_script_output.stderr_lines | default([]) }}"
failed_when: "{{ not install_script_output.msg.startswith('Failed to connect') }}"
如果安装脚本失败,下一个任务完全可以访问已注册变量的stdout_lines
和stderr_lines
字段。但是,如果脚本成功并且远程服务器离线,则变量只包含两个字段:failed
和msg
。
{
"failed": true,
"msg": "Failed to connect to the host via ssh: System is going down. Unprivileged users are not permitted to log in anymore. For technical details, see pam_nologin(8).\n\nConnection closed by 10.10.10.10 port 22"
}
有没有办法查看stdout
导致关闭与远程主机的连接的任务?
答案1
...对于以服务器关闭连接而结束的任务,这两者
stderr
似乎stdout
都不存在。
这是正确的,也是预期的行为。显然,这是因为 Ansible 无法将信息从远程节点传输回控制节点,因为触发了重启,因此执行的远程代码被外部终止。
有没有办法查看
stdout
导致关闭与远程主机的连接的任务?
这取决于人们如何看待这个问题。开箱即用且不实施变通方法,不行。这是因为该信息stdout
仅保存在远程节点的内存中,并未记录。
类似问答
进一步阅读
... 在开发和调试脚本或自定义模块的情况下。
下一步该如何进行?
由于您似乎有权访问安装程序脚本,因此处理用例的最简单方法似乎是更改安装程序脚本本身的行为。在此期间,如果尚未实现日志记录,也可能实现日志记录。从脚本角度来看,将本地日志记录到示例中/var/log/script.stdout.log
,如果需要script.stderr.log
,可以在控制节点上进行fetch
编辑或编辑。slurp
也可以简单地将重启移出脚本,让脚本在重启之前运行结束。这样,请求的信息将被收集。之后只需要执行一个额外的 Ansible 任务来重启远程节点。