管理的DB系统版本不统一,使用Ansible管理的时候发现有的连得上、有的连不上,发现连不上的机器都比较老旧--SUSE Enterprise Server 10,环境列举如下(本地机器是运行Ansible的机器、远端机器是要用Ansible管理的机器):
本地机器:OpenSSH_5.3p1
远端机器:SSH Secure Shell 3.2.9.1 & Python2.4
运行:
ansible oldserver -i hosts -m ping
报错:
testserver2 | FAILED => FAILED: ('Bad authentication type', [u'publickey', u'keyboard-interactive']) (allowed_types=[u'publickey', u'keyboard-interactive'])
这错误之前我用Fabric也遇到过,表现为终端一直提示输入密码,但明明密码正确就是登陆不上,看来是paramiko库对SSH Secure Shell验证出现问题,想到令ansible使用本地native ssh客户端而不是paramiko库来连接远端机器(其实1.3后的ansible检测到本地openssh是较新版本的话会自动调用native ssh的):
ansible -c ssh oldserver -i hosts -m ping
但接下来报错:
oldserver | FAILED => using -c ssh on certain older ssh versions may not support ControlPersist, set ANSIBLE_SSH_ARGS="" (or ssh_args in [ssh_connection] section of the config file) before running again
原来是本地机器的openssh客户端太旧不支持ControlPersist,只要在ansible.cfg里修改ssh_args选项就行了:
[ssh_connection]
ssh_args = ""
但接下又有报错:
oldserver | FAILED >> {
"failed": true,
"msg": "Error: ansible requires a json module, none found!OpenSSH_5.3p1, OpenSSL 1.0.0-fips 29 Mar 2010\ndebug1: Reading configuration data /etc/ssh/ssh_config\r\ndebug1: Applying options for *\r\ndebug1: Connecting to 10.177.149.109 [10.177.149.109] port 36000.\r\ndebug1: fd 4 clearing O_NONBLOCK\r\ndebug1: Connection established.\r\ndebug1: permanently_set_uid: 0/0\r\ndebug1: identity file /root/.ssh/identity type -1\r\ndebug1: identity file /root/.ssh/id_rsa type -1\r\ndebug1: identity file /root/.ssh/id_dsa type -1\r\ndebug1: Remote protocol version 2.0, remote software version 3.2.9.1 SSH Secure Shell (non-commercial)\r\ndebug1: no match: 3.2.9.1 SSH Secure Shell (non-commercial)\r\ndebug1: Enabling compatibility mode for protocol 2.0\r\ndebug1: Local version string SSH-2.0-OpenSSH_5.3\r\ndebug1: SSH2_MSG_KEXINIT sent\r\ndebug1: SSH2_MSG_KEXINIT received\r\ndebug1: kex: server->client aes128-cbc hmac-md5 zlib\r\ndebug1: kex: client->server aes128-cbc hmac-md5 zlib\r\ndebug1: sending SSH2_MSG_KEXDH_INIT\r\ndebug1: expecting SSH2_MSG_KEXDH_REPLY\r\ndebug1: Host '[10.177.149.109]:36000' is known and matches the DSA host key.\r\ndebug1: Found key in /root/.ssh/known_hosts:3\r\ndebug1: ssh_dss_verify: signature correct\r\ndebug1: Enabling compression at level 6.\r\ndebug1: SSH2_MSG_NEWKEYS sent\r\ndebug1: expecting SSH2_MSG_NEWKEYS\r\ndebug1: SSH2_MSG_NEWKEYS received\r\ndebug1: SSH2_MSG_SERVICE_REQUEST sent\r\ndebug1: SSH2_MSG_SERVICE_ACCEPT received\r\ndebug1: Authentications that can continue: publickey,keyboard-interactive\r\ndebug1: Next authentication method: keyboard-interactive\r\nPAM authentication\r\ndebug1: Authentication succeeded (keyboard-interactive).\r\ndebug1: channel 0: new [client-session]\r\ndebug1: Entering interactive session.\r\ndebug1: Sending environment.\r\ndebug1: Sending env LANG = zh_CN.GB2312\r\ndebug1: Sending env LC_ALL = C\r\ndebug1: Sending command: /bin/sh -c 'LANG=en_US.UTF-8 LC_CTYPE=en_US.UTF-8 /usr/bin/python /root/.ansible/tmp/ansible-tmp-1437362428.06-151513297984504/ping; rm -rf /root/.ansible/tmp/ansible-tmp-1437362428.06-151513297984504/ >/dev/null 2>&1'\r\ndebug1: client_input_channel_req: channel 0 rtype exit-status reply 0\r\ndebug1: channel 0: free: client-session, nchannels 1\r\ndebug1: fd 1 clearing O_NONBLOCK\r\ndebug1: fd 2 clearing O_NONBLOCK\r\nConnection to 10.177.149.109 closed.\r\nTransferred: sent 1656, received 5288 bytes, in 0.1 seconds\r\nBytes per second: sent 32518.4, received 103838.9\r\ndebug1: Exit status 0\r\ndebug1: compress outgoing: raw data 793, compressed 499, factor 0.63\r\ndebug1: compress incoming: raw data 3255, compressed 3333, factor 1.02\r\n",
"parsed": false
}
虽然报错信息一大堆,核心的就是ansible requires a json module, none found!,原因是远端机器Python 2.4版本太低,不包含JSON模块了,解决很简单:
- 使用raw模式:
ansible -c ssh oldserver -i hosts -m raw -m ping
- 升级python到2.6+
- 在远端机器安装个simplejson模块就行了,不过注意的是simplejson早就不支持Python 2.4了,可以在pypi里选择个旧版本,譬如2.1.0~