Ansible ssh 连接在为其他任务工作时为其中一项任务丢弃 [失败]

Ansible ssh connection drops [fails] for one of the task while works for other tasks

这是我的剧本,包含三个任务:

- name: Play 2- Configure Source nodes
  hosts: all_hosts

  vars:
    ansible_ssh_extra_args: -o StrictHostKeyChecking=no -o ConnectTimeout=8 -o ServerAliveInterval=50
    ansible_ssh_private_key_file: /app/misc_automation/ssh_keys/id_rsa

  gather_facts: false
  tasks:

   - name: Get Process Dump for tomcat on non-Solaris
     ignore_errors: yes
     block:
       - raw: ps -ef | grep java | grep -i tomcat | grep -v grep
         ignore_errors: yes
         register: tomjavadump

       - raw: ps -ef | grep java | grep -i tomcat | grep -v grep | wc -l
         ignore_errors: yes
         register: tomjavadumpcount

       - raw: "echo <tr><td>{{ inventory_hostname }}</td><</tr>"
         delegate_to: localhost
         when: tomjavadump.rc == 0 and patchthistomcat is undefined

我 运行 上面的剧本处于调试模式,完全相同的 ssh 连接适用于这两个任务,但第一个任务失败,如下面的调试输出所示:

TASK [raw] *************************************************************************************************************************************************************
task path: /app/Ansible/playbook/check.yml:1260
<10.0.0.211> ESTABLISH SSH CONNECTION FOR USER: root
<10.0.0.211> SSH: EXEC ssh -o 'IdentityFile="/app/misc_automation/ssh_keys/id_rsa"' -o KbdInteractiveAuthentication=no -o PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey -o PasswordAuthentication=no -o 'User="root"' -o ConnectTimeout=10 -o StrictHostKeyChecking=no -o ConnectTimeout=8 -o ServerAliveInterval=50 10.0.0.211 'ps -ef | grep java | grep -i tomcat | grep -v grep'
<10.0.0.211> (1, '', '')
<10.0.0.211> Failed to connect to the host via ssh:
fatal: [10.0.0.211]: FAILED! => {
    "changed": true,
    "msg": "non-zero return code",
    "rc": 1,
    "stderr": "",
    "stderr_lines": [],
    "stdout": "",
    "stdout_lines": []
}
...ignoring

TASK [raw] *************************************************************************************************************************************************************
task path: /app/Ansible/playbook/check.yml:1267
<10.0.0.211> ESTABLISH SSH CONNECTION FOR USER: root
<10.0.0.211> SSH: EXEC ssh -o 'IdentityFile="/app/misc_automation/ssh_keys/id_rsa"' -o KbdInteractiveAuthentication=no -o PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey -o PasswordAuthentication=no -o 'User="root"' -o ConnectTimeout=10 -o StrictHostKeyChecking=no -o ConnectTimeout=8 -o ServerAliveInterval=50 10.0.0.211 'ps -ef | grep java | grep -i tomcat | grep -v grep | wc -l'
<10.0.0.211> (0, '0\n', '')
changed: [10.0.0.211] => {
    "changed": true,
    "rc": 0,
    "stderr": "",
    "stderr_lines": [],
    "stdout": "0\n",
    "stdout_lines": [
        "0"
    ]
}

TASK [raw] *************************************************************************************************************************************************************
task path: /app/Ansible/playbook/check.yml:1270
skipping: [10.0.0.211] => {
    "changed": false,
    "skipped": true,

我不知道,但如果我将目标服务器从 10.0.0.211 更改为其他服务器,同样的代码可以正常工作。

为什么完全相同的 ssh 连接对其他任务有效而对第一个任务失败?

我该如何解决这个问题?

这是失败和通过任务的 ssh 失败和通过连接的最大调试 https://filebin.net/8v5xy28edtaz0bhh/ansible_ssh_issue.txt?t=o4l9o4d1

这里的问题是 raw 模块,它是 运行 你在远程节点中的 shell 命令,它可能没有安装 python。

这意味着ansible是运行你的命令如下:

ssh user@ip "commands"

你的情况:

<10.0.0.211> SSH: EXEC ssh -o 'IdentityFile="/app/misc_automation/ssh_keys/id_rsa"' -o KbdInteractiveAuthentication=no -o PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey -o PasswordAuthentication=no -o 'User="root"' -o ConnectTimeout=10 -o StrictHostKeyChecking=no -o ConnectTimeout=8 -o ServerAliveInterval=50 10.0.0.211 'ps -ef | grep java | grep -i tomcat | grep -v grep'

如果 ssh 失败或 commands 的 rc 是 non-zero,则抛出错误。

要保留命令的 return 代码并防止 rc 转向 non-zero,您应该使用

-raw: ps -ef | grep java | grep -i tomcat | grep -v grep; awk -vrc=$? 'BEGIN{print "rc="rc}'

通过这样做,您将捕获最后一个 grep 命令的 rc 并通过 awk 命令打印它。这里 awk 总是 return zero-rc.

捕获标准输出后,您可以根据需要在 var.stdout.

中搜索 rc=0rc=1

如果您不关心 rc 那么只需在您的命令中添加 ||true 的后缀。