默认情况下,Ansible使用ssh去连接远程主机,但实际上它提供了多种插件来丰富连接方式:smart、ssh、paramiko、local、docker、winrm,默认为smart。
smart表示智能选择ssh和paramiko(paramiko是Python的一个ssh协议模块),当Ansible端安装的ssh支持ControlPersist(即持久连接)时自动使用ssh,否则使用paramiko。local和docker是非基于ssh连接的方式,winrm是连接Windows的插件。
可以在命令行选项中使用-c或--connection选项来指定连接方式:
$ ansible nginx -c smart -m XXX -a ‘YYY’
$ ansible-playbook nginx -c smart -m XXX -a ‘YYY’
或者在playbook的play级别或task级别上指定连接方式,定义在task上时表示该task使用所指定的连接方式:
---
- hosts: nginx
connection: smart
...
tasks:
- copy: src=/etc/passwd dest=/tmp
connection: local
此外,inventory中也可以通过连接的行为变量ansible_connection指定连接类型:
192.168.200.29 ansible_connection="smart"
通常,我们不需要关注连接类型,但是一种特殊的连接方式是local,它表示在Ansible端本地执行任务。例如:
---
- name: exec task at local
hosts: new
gather_facts: false
connection: local
tasks:
- name: task1
debug:
msg: "{{inventory_hostname}} is executing task"
- name: task2
shell: touch /tmp/task1.txt
args:
creates: /tmp/task1.txt
connection和delegate_to指令
Ansible提供了另外一个指令:delegate_to,它表示将任务委托给谁去执行。显然connection: local和delegate_to: localhost在功能上是等价的。当然,connection可以定义在play级别或task级别上,而delegate_to只能定义在task级别上。
---
- name: play1
hosts: new
gather_facts: false
tasks:
- name: task1
debug:
msg: "{{inventory_hostname}} is executing task"
delegate_to: 192.168.200.35
也许我们更深的疑惑是,为什么要使用connection: local或delegate_to,而不直接在被委托节点上执行任务?
主要原因在于委托执行时获取了目标节点的上下文环境。正如委托给Ansible端本地执行时,它是可以获取到目标节点信息的,而如果直接通过hosts: localhost指定在本地执行,则除了localhost外没有任何其它目标节点,也就无法获取到这些节点的信息,比如无法获取它们的IP地址。