我是 ansible 的新手,正在尝试自动化一些步骤。
此任务第一次运行良好。
# Copy Root ssh keys within all devices
- hosts: etall
tasks:
- name: ssh keygen
command: ssh-keygen -t rsa -f /root/.ssh/id_rsa -q -P ""
第二次它只是在收集事实后挂起。设置ANSIBLE_DEBUG=1
显示挂在的步骤:
16584 1554867575.39541: _low_level_execute_command(): executing: /bin/sh -c '/usr/bin/python /root/.ansible/tmp/ansible-tmp-1554867574.524454-229535370546451/AnsiballZ_command.py && sleep 0'
在客户端机器上跟踪时:
/usr/bin/python -m trace --trace /root/.ansible/tmp/ansible-tmp-1554873279.0459487-106888464136363/AnsiballZ_command.py
<---output snippet---->
AnsiballZ_command.py(16): import base64
--- modulename: trace, funcname: _unsettrace
trace.py(80): sys.settrace(None)
Traceback (most recent call last):
File "/usr/lib64/python2.7/runpy.py", line 162, in _run_module_as_main
"__main__", fname, loader, pkg_name)
File "/usr/lib64/python2.7/runpy.py", line 72, in _run_code
exec code in run_globals
File "/usr/lib64/python2.7/trace.py", line 819, in <module>
main()
File "/usr/lib64/python2.7/trace.py", line 807, in main
t.runctx(code, globs, globs)
File "/usr/lib64/python2.7/trace.py", line 513, in runctx
exec cmd in globals, locals
File "/root/.ansible/tmp/ansible-tmp-1554873279.0459487-106888464136363/AnsiballZ_command.py", line 113, in <module>
_ansiballz_main()
File "/root/.ansible/tmp/ansible-tmp-1554873279.0459487-106888464136363/AnsiballZ_command.py", line 16, in _ansiballz_main
import base64
ImportError: No module named base64
我可以import base64
之后/usr/bin/python
这在第一次运行时不是问题。在客户端计算机上重新安装操作系统后也可以使用。
版本:
ansible 2.7.6
config file = /user/user1/plays/ansible.cfg
configured module search path = ['/user/user1/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
ansible python module location = /user/user1/p363/lib/python3.6/site-packages/ansible-2.7.6-py3.6.egg/ansible
executable location = /user/user1/p363/bin/ansible
python version = 3.6.3 (default, Jul 8 2018, 21:13:48) [GCC 4.8.5 20150623 (Red Hat 4.8.5-28)]
客户端机器中的 Python 版本是 2.7.5
配置ansible-config dump --only-changed
DEFAULT_FORKS(/user/user1/plays/ansible.cfg) = 1
DEFAULT_HOST_LIST(/user/user1/plays/ansible.cfg) = ['/user/user1/plays/hosts.ini']
DEFAULT_LOG_PATH(/user/user1/plays/ansible.cfg) = /user/user1/plays/ansible.log
DEFAULT_ROLES_PATH(/user/user1/plays/ansible.cfg) = ['/user/user1/plays/hosts']
RETRY_FILES_ENABLED(/user/user1/plays/ansible.cfg) = False
环境: ansible master
$ cat /etc/os-release
NAME="Red Hat Enterprise Linux Workstation"
VERSION="7.5 (Maipo)"
ID="rhel"
ID_LIKE="fedora"
VARIANT="Workstation"
VARIANT_ID="workstation"
VERSION_ID="7.5"
PRETTY_NAME="Red Hat Enterprise Linux"
ANSI_COLOR="0;31"
CPE_NAME="cpe:/o:redhat:enterprise_linux:7.5:GA:workstation"
HOME_URL="https://www.redhat.com/"
BUG_REPORT_URL="https://bugzilla.redhat.com/"
REDHAT_BUGZILLA_PRODUCT="Red Hat Enterprise Linux 7"
REDHAT_BUGZILLA_PRODUCT_VERSION=7.5
REDHAT_SUPPORT_PRODUCT="Red Hat Enterprise Linux"
REDHAT_SUPPORT_PRODUCT_VERSION="7.5"
可靠的客户端
# cat /etc/os-release
NAME="CentOS Linux"
VERSION="7 (Core)"
ID="centos"
ID_LIKE="rhel fedora"
VERSION_ID="7"
PRETTY_NAME="CentOS Linux 7 (Core)"
ANSI_COLOR="0;31"
CPE_NAME="cpe:/o:centos:centos:7"
HOME_URL="https://www.centos.org/"
BUG_REPORT_URL="https://bugs.centos.org/"
CENTOS_MANTISBT_PROJECT="CentOS-7"
CENTOS_MANTISBT_PROJECT_VERSION="7"
REDHAT_SUPPORT_PRODUCT="centos"
REDHAT_SUPPORT_PRODUCT_VERSION="7"
剧本:
# Copy Root ssh keys within all machines
- hosts: etall
tasks:
- name: ssh keygen
command: ssh-keygen -t rsa -f /root/.ssh/id_rsa -q -P ""
- name: Fetch keyfile
fetch:
src: "~/.ssh/id_rsa.pub"
dest: "buffer/{{ ansible_hostname }}-id_rsa.pub"
flat: yes
- name: Copy keyfile to destination
authorized_key:
user: root
state: present
key: "{{ lookup('file','buffer/{{ item }}-id_rsa.pub') }}"
when: item != ansible_hostname
with_items:
- "{{ groups['etall'] }}"
- name: ssh keyscan
shell: ssh-keyscan {{ item }} >> /root/.ssh/known_hosts
when: item != ansible_hostname
with_items:
- "{{ groups['etall'] }}"
收集事实后的详细输出片段:
TASK [ssh keygen] *************************************************************************************************************************************************************************************************
task path: /user/user1/plays/auth_keys.yml:4
<linux-user5> ESTABLISH SSH CONNECTION FOR USER: root
<linux-user5> SSH: EXEC sshpass -d11 ssh -C -o ControlMaster=auto -o ControlPersist=60s -o User=root -o ConnectTimeout=10 -o ControlPath=/user/user1/.ansible/cp/0969431db6 linux-user5 '/bin/sh -c '"'"'echo ~root && sleep 0'"'"''
<linux-user5> (0, b'/root\n', b'')
<linux-user5> ESTABLISH SSH CONNECTION FOR USER: root
<linux-user5> SSH: EXEC sshpass -d11 ssh -C -o ControlMaster=auto -o ControlPersist=60s -o User=root -o ConnectTimeout=10 -o ControlPath=/user/user1/.ansible/cp/0969431db6 linux-user5 '/bin/sh -c '"'"'( umask 77 && mkdir -p "` echo /root/.ansible/tmp/ansible-tmp-1554878730.6050982-46540706020890 `" && echo ansible-tmp-1554878730.6050982-46540706020890="` echo /root/.ansible/tmp/ansible-tmp-1554878730.6050982-46540706020890 `" ) && sleep 0'"'"''
<linux-user5> (0, b'ansible-tmp-1554878730.6050982-46540706020890=/root/.ansible/tmp/ansible-tmp-1554878730.6050982-46540706020890\n', b'')
Using module file /user/user1/p363/lib/python3.6/site-packages/ansible-2.7.6-py3.6.egg/ansible/modules/commands/command.py
<linux-user5> PUT /user/user1/.ansible/tmp/ansible-local-312468ua784d6/tmp9l2vw34v TO /root/.ansible/tmp/ansible-tmp-1554878730.6050982-46540706020890/AnsiballZ_command.py
<linux-user5> SSH: EXEC sshpass -d11 sftp -o BatchMode=no -b - -C -o ControlMaster=auto -o ControlPersist=60s -o User=root -o ConnectTimeout=10 -o ControlPath=/user/user1/.ansible/cp/0969431db6 '[linux-user5]'
<linux-user5> (0, b'sftp> put /user/user1/.ansible/tmp/ansible-local-312468ua784d6/tmp9l2vw34v /root/.ansible/tmp/ansible-tmp-1554878730.6050982-46540706020890/AnsiballZ_command.py\n', b'')
<linux-user5> ESTABLISH SSH CONNECTION FOR USER: root
<linux-user5> SSH: EXEC sshpass -d11 ssh -C -o ControlMaster=auto -o ControlPersist=60s -o User=root -o ConnectTimeout=10 -o ControlPath=/user/user1/.ansible/cp/0969431db6 linux-user5 '/bin/sh -c '"'"'chmod u+x /root/.ansible/tmp/ansible-tmp-1554878730.6050982-46540706020890/ /root/.ansible/tmp/ansible-tmp-1554878730.6050982-46540706020890/AnsiballZ_command.py && sleep 0'"'"''
<linux-user5> (0, b'', b'')
<linux-user5> ESTABLISH SSH CONNECTION FOR USER: root
<linux-user5> SSH: EXEC sshpass -d11 ssh -C -o ControlMaster=auto -o ControlPersist=60s -o User=root -o ConnectTimeout=10 -o ControlPath=/user/user1/.ansible/cp/0969431db6 -tt linux-user5 '/bin/sh -c '"'"'/usr/bin/python /root/.ansible/tmp/ansible-tmp-1554878730.6050982-46540706020890/AnsiballZ_command.py && sleep 0'"'"''
收集事实后挂起。
这在第一次运行时完成得很好。在客户机上重新安装操作系统后也能正常工作。
您是否尝试
ssh-keygen
过手动运行命令两次?第一次运行:
第二次运行:
你的命令只是永远等待一个永远不会到来的答案。
解决方案 1:回答问题
expect
如果您事先知道,您可以使用该模块来回答交互式提示虽然这对每次运行都有效,但它不是一个好的解决方案,因为它不是幂等的:每次运行你的剧本时,你的服务器都会发生变化,尽管你的库存或变量没有发生变化
解决方案2:仅在需要时生成。
更好的方法是仅在密钥不存在或需要刷新时才创建密钥。有几种方法可以做到这一点,这在很大程度上取决于您的需求、您的愿望、您的服务器园区的大小......
对于相对较小的公园,您可以在本地生成密钥并将它们存储在您的清单中(使用ansible-vault来混淆私钥)。然后,您只需将文件复制到服务器即可。如果文件已经存在并且内容相同,则不会进行任何更改。
如果公园更大,钥匙可以存放在 Cyberark 的 Hashicorp Vault 中……
如果您仍想在每台服务器上创建密钥,这是我的做法:
现在,如果您正常运行您的剧本,则只有当密钥不存在时才会创建它们。如果你想刷新已经有一个服务器上的密钥,你可以将一个额外的 var 传递给剧本