Ansible 连接主机方法

默认情况下,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: localdelegate_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: localdelegate_to,而不直接在被委托节点上执行任务?

主要原因在于委托执行时获取了目标节点的上下文环境。正如委托给Ansible端本地执行时,它是可以获取到目标节点信息的,而如果直接通过hosts: localhost指定在本地执行,则除了localhost外没有任何其它目标节点,也就无法获取到这些节点的信息,比如无法获取它们的IP地址。