考虑当前目录的以下布局:
.
├── foobar.yml
└── roles
└── foobar
└── tasks
└── main.yml
foobar
假设我们的角色 ( )有以下任务roles/foobar/tasks/main.yml
:
---
- add_host:
name: "baz"
ansible_user: "root"
ansible_become: yes
ansible_ssh_host: "{{container.ip}}"
ansible_ssh_host_key_checking: no
ansible_ssh_private_key_file: "{{container.privkey}}"
ansible_ssh_extra_args: "-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null"
- wait_for:
port: 22
host: "{{container.ip}}"
timeout: 30
search_regex: OpenSSH
- apt:
pkg:
- vim-nox
- lsof
delegate_to: "baz"
become: true
become_user: root
...以及以下剧本:
---
- name: Configuring container and host
hosts: localhost
vars:
container:
ip: "172.17.0.2"
privkey: "/root/root_ssh/id_rsa"
roles:
- foobar
OpenSSH 在剧本中给出的 IPv4 上可用,并且私钥存在于给定路径中(u=rw,go=
即 0600,其父目录为 0700)。在我的测试期间,我已经验证了所有这些事情(例如使用stat
和debug
)。
最后一个任务失败如下:
TASK [foobar : apt] ***********************************************************************************************************************************************************************************************
task path: /home/username/ansible/test/roles/foobar/tasks/main.yml:18
<172.17.0.2> ESTABLISH SSH CONNECTION FOR USER: root
<172.17.0.2> SSH: EXEC ssh -C -o ControlMaster=auto -o ControlPersist=60s -o 'IdentityFile="/root/root_ssh/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 UserKnownHostsFile=/dev/null -o ControlPath=/home/username/.ansible/cp/0689044634 172.17.0.2 '/bin/sh -c '"'"'echo ~root && sleep 0'"'"''
<172.17.0.2> (255, '', "Warning: Permanently added '172.17.0.2' (ECDSA) to the list of known hosts.\r\nno such identity: /root/root_ssh/id_rsa: Permission denied\r\[email protected]: Permission denied (publickey).\r\n")
fatal: [localhost]: UNREACHABLE! => {
"changed": false,
"msg": "Failed to connect to the host via ssh: Warning: Permanently added '172.17.0.2' (ECDSA) to the list of known hosts.\r\nno such identity: /root/root_ssh/id_rsa: Permission denied\r\[email protected]: Permission denied (publickey).",
"unreachable": true
}
的输出ssh
是:
Warning: Permanently added '172.17.0.2' (ECDSA) to the list of known hosts.
no such identity: /root/root_ssh/id_rsa: Permission denied
[email protected]: Permission denied (publickey).
ssh
...当我像我自己一样从命令行运行等效命令时(即没有sudo
),我也会得到这一点。这里的错误原因是/root/root_ssh/id_rsa
运行的用户无法访问ssh
。如果我使用等效命令sudo
来调用ssh
,它就像一个魅力。
但是,为了能够ssh
访问私钥,必须先调用它root
。
问:那么我怎样才能使用 Ansiblebecome
同时建立连接ssh
(即ssh
运行为root
)?
Ansible版本
$ ansible-playbook --version
ansible-playbook 2.9.4
config file = /home/username/ansible/precitec/ansible.cfg
configured module search path = [u'/home/username/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']
ansible python module location = /usr/lib/python2.7/dist-packages/ansible
executable location = /usr/bin/ansible-playbook
python version = 2.7.17 (default, Nov 7 2019, 10:07:09) [GCC 7.4.0]
我尝试过的
- 完成
become
任务add_host
- 设置
ansible_ssh_executable: "/usr/bin/sudo -- /usr/bin/ssh"
(以及sudo -- ssh
它们的组合)以强制 Ansible 使用 sudo 来调用ssh
.唉,结果是 Ansible 最终使用了 Paramiko。 - ...发挥创意并设定
ansible_ssh_executable
(ansible_ssh_args
见下文) - 将任务移动
apt
到任务正在使用的block
位置,但外部块是apt
delegate_to
还使用become
,也无济于事(见下文)
这些都没有帮助。
设置ansible_ssh_executable
和ansible_ssh_args
ansible_ssh_executable: "/usr/bin/sudo"
ansible_ssh_args: "-- /usr/bin/ssh -C -o ControlMaster=auto -o ControlPersist=60s"
Ansible 似乎会检查该值,因此不可能在其中ansible_ssh_executable
给出完整的命令行(例如)。sudo -- ssh
包裹在一个块中...
- name: Install packages
block:
- apt:
pkg:
- vim-nox
- lsof
delegate_to: "baz"
become: true
become: true