You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Ansible local_action连接异常:变量定义位置引发的连接方式差异

问题

我编写了两个Ansible角色:

  • 一个通过WinRM在远程服务器安装OpenSSH
  • 另一个通过SSH在同一台服务器安装Windows功能

当前遇到的问题是,角色中使用local_action委派到控制节点的任务出现连接异常,具体情况:

  1. 当变量定义在playbook的vars下时,执行install-openssh.yml会报错,无法通过WinRM连接localhost;
  2. 将变量移至对应角色的defaults/main.yml后,install-openssh.yml执行成功,此时localhost采用本地连接;但install-wfeature.yml仍报错,SSH连接localhost时出现主机密钥验证失败。

非委派任务均可正常执行,疑惑的是变量值完全相同,仅定义位置不同,为何会导致localhost的连接方式产生差异?

相关代码如下:

install-openssh.yml

---
- name: Install and configure OpenSSH
  hosts: all
  vars:
    ansible_user: ansible
    ansible_password: "{{ server_password }}"
    ansible_connection: winrm
    ansible_port: 5985
  roles:
    - install-openssh

install-wfeature.yml

---
- name: Install Windows features
  hosts: all
  vars:
    ansible_user: ansible
    ansible_connection: ssh
    ansible_port: 22
  roles:
    - install-wfeature

报错信息示例

移动变量前install-openssh.yml报错:

<localhost> ESTABLISH WINRM CONNECTION FOR USER: ansible on PORT 5985 to localhost
fatal: [target_server -> localhost]: UNREACHABLE! => {
    "changed": false,
    "msg": "plaintext: HTTPConnectionPool(host='localhost', port=5985): Max retries exceeded with url: /wsman (Caused by NewConnectionError('<urllib3.connection.HTTPConnection object at 0x7fdb8b10bb20>: Failed to establish a new connection: [Errno 111] Connection refused'))",
    "unreachable": true
}

移动变量后install-wfeature.yml报错:

<localhost> ESTABLISH SSH CONNECTION FOR USER: ansible
[...]
fatal: [target_server -> localhost]: UNREACHABLE! => {
    "changed": false,
    "msg": "Data could not be sent to remote host \"localhost\". Make sure this host can be reached over ssh: Host key verification failed.\r\n",
    "unreachable": true
}
解决方案

问题根源:变量作用域与委派任务的连接参数继承

  1. Playbook级vars的作用范围:在playbook的vars中定义ansible_connection这类连接参数时,参数会被所有任务继承,包括local_action委派到localhost的任务。这导致原本应使用本地连接(local)的localhost任务,被强制套用playbook指定的winrm或ssh连接方式——而你的控制节点(localhost)并未开启WinRM服务(第一个报错的原因),或未配置SSH密钥验证(第二个报错的原因)。

  2. 角色defaults的作用范围:角色的defaults变量优先级更低,且仅在角色内部生效,不会覆盖Ansible对localhost的默认连接配置(默认使用local连接,无需走WinRM/SSH)。因此将变量移至角色defaults后,委派到localhost的任务会使用默认本地连接,执行成功;但install-wfeature.yml仍在playbook的vars中定义了ansible_connection: ssh,委派任务依然继承该参数,尝试用SSH连接localhost,导致密钥验证失败。

解决步骤

  1. 分离远程节点与localhost的连接参数:不要在playbook的vars中定义全局连接参数,将ansible_connection、ansible_port等参数放到inventory文件中,针对远程目标主机单独配置,示例:

    [windows_servers]
    target_server ansible_user=ansible ansible_password={{ server_password }} ansible_connection=winrm ansible_port=5985
    

    这样只有远程主机使用WinRM/SSH连接,localhost的委派任务保持默认本地连接。

  2. 处理install-wfeature.yml的SSH密钥问题:若确实需要用SSH连接localhost(不建议,优先用本地连接),可在控制节点执行ssh-keygen生成密钥,将公钥添加到~/.ssh/authorized_keys;或在委派任务中临时跳过密钥验证(仅限测试环境):

    - name: 示例委派任务
      local_action:
        module: command
        cmd: echo "test"
      vars:
        ansible_ssh_common_args: "-o StrictHostKeyChecking=no"
    

    更合理的做法是避免在playbook全局设置SSH连接参数,确保委派任务使用本地连接。

  3. 角色内变量规范:将针对远程节点的配置变量放在角色的defaults或vars中,主机级的连接参数统一在inventory中管理,避免作用域混淆。

内容的提问来源于stack exchange,提问作者C. Güzelhan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 07:18:10