我们正在使用Ansible来配置多个节点作为群集。这些机器是在类似于自定义AWS的基础设施上创建的实例。我们有大约一百个任务分布在不同的playbook上,并在每个节点上执行。问题是,我们遇到了偶发的主机不可达错误,导致playbook执行停止并出现以下失败信息:
这里是我们的ansible.cfg文件:
请看下面的注释:
TASK [common : install basic packages] *************************
fatal: [fqdn.for.a.node]: UNREACHABLE! => {"changed": false, "msg": "Failed to connect to the host via ssh.", "unreachable": true}
使用-vvv输出:
TASK [common : install basic packages] *******************************
task path: /jenkins/workspace/Cluster-Deployment/91/roles/common/tasks/install-basic-packages.yml:1
<fqdn.for.a.node> ESTABLISH SSH CONNECTION FOR USER: root
<fqdn.for.a.node> SSH: EXEC ssh -C -q -o ControlMaster=auto -o ControlPersist=60s -o StrictHostKeyChecking=no -o 'IdentityFile="id_rsa"' -o KbdInteractiveAuthentication=no -o PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey -o PasswordAuthentication=no -o User=root -o ConnectTimeout=600 -o ControlPath=/home/turkenh/.ansible/cp/ansible-ssh-%h-%p-%r fqdn.for.a.node '/bin/sh -c '"'"'( umask 77 && mkdir -p "` echo $HOME/.ansible/tmp/ansible-tmp-1466523588.96-210828884892875 `" && echo ansible-tmp-1466523588.96-210828884892875="` echo $HOME/.ansible/tmp/ansible-tmp-1466523588.96-210828884892875 `" ) && sleep 0'"'"''
failed: [fqdn.for.a.node] (item=[u'unzip']) => {"item": ["unzip"], "msg": "Failed to connect to the host via ssh.", "unreachable": true}
这里是我们的ansible.cfg文件:
[defaults]
forks = 50
sudo_flags=-i
nocows=1
# do not check host key while doing ssh
host_key_checking = False
# use openssh not paramiko
transport = ssh
private_key_file = id_rsa
remote_user = root
请看下面的注释:
我们使用 ansible ping 模块(而不是 ping shell 命令)尝试在故障后立即对该主机进行ping测试,它会抛出相同的错误,但如果我们等待一分钟左右,就可以ping通。
关于我们基于AWS的自定义基础设施,我们可以说,有时可能会出现零星的连接问题,但这不会超过1-2分钟。
尝试在ansible.cfg中将timeout参数设置为一个大数字(如600),但没有帮助。
我们正在配置ubuntu、redhat和suse节点,但无论操作系统如何,我们都有约20%的概率遇到此错误。
故障并不是发生在我的playbook中的相同或类似任务,而是在随机的任务中失败(有时候是在setup模块中,有时候是在package模块中,...)
我们的ansible版本是2.1(通过pip安装),工作站的操作系统是Ubuntu 14.04
因此,我们需要告诉ansible如果您看到一个节点不可用,请不要放弃并且失败。在放弃不可达之前,请等待一段时间或重试n次。我们应该如何做到这一点?
wait_for
。我们在启动新的云服务器后使用它来等待ssh可用,然后继续执行此新服务器的任务。 - Konstantin Suvorov