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

如何从目标主机获取Ansible控制节点的IP地址?

隔离网络中Ansible控制节点文件分发:无需硬编码IP的实现方案

场景与问题

在无公网的隔离网络中,使用Ansible控制节点(示例IP:192.168.0.5)管理多台目标主机(示例IP:192.168.0.10/11/12),需要让目标主机通过HTTP/HTTPS从控制节点下载文件,但存在以下限制:

  • 控制节点通过DHCP获取IP,地址不固定;
  • 控制节点有多块网卡,ansible_all_ipv4_addresses包含目标主机无法访问的IP,无法直接通过控制节点的facts确定可用地址;
  • 不想通过循环尝试IP的方式测试可用性,希望直接获取目标主机能访问的控制节点IP。

为什么选择HTTP/HTTPS下载而非直接传输

部分目标主机为Windows系统,win_copy模块基于WinRM传输大文件速度极慢,Ansible文档明确提示:

由于win_copy通过WinRM运行,并非高效的传输机制。若传输大文件,建议将其托管在Web服务上,改用ansible.windows.win_get_url模块。

解决方案:从目标主机侧获取控制节点的连接源IP

核心思路:目标主机与控制节点已通过WinRM/SSH建立了管理连接,从目标主机视角查看该连接的远程IP(即控制节点的源IP),这个IP就是目标主机能直接访问的控制节点地址。

实现步骤与Playbook示例

以下是跨Linux/Windows目标主机的通用实现:

- name: 从控制节点分发文件至目标主机(自动获取控制节点IP)
  hosts: all
  gather_facts: yes
  vars:
    target_file: "large_data.iso"  # 要分发的文件(需放在控制节点执行Playbook的目录)
    web_port: 8000  # 临时Web服务端口
  tasks:
    # 1. 在控制节点启动临时HTTP服务(后台运行)
    - name: 启动临时HTTP服务器
      delegate_to: localhost
      command: python3 -m http.server {{ web_port }} --bind 0.0.0.0
      async: 3600  # 后台运行1小时
      poll: 0
      changed_when: false
      when: ansible_connection != 'local'

    # 2. 针对Linux目标主机获取控制节点IP
    - name: 获取控制节点源IP(Linux)
      shell: |
        ss -tunap | grep "{{ ansible_port }}" | grep ESTAB | awk '{print $5}' | cut -d: -f1 | head -n1
      register: ctrl_ip_linux
      when: ansible_os_family in ['Debian', 'RedHat']

    # 3. 针对Windows目标主机获取控制节点IP
    - name: 获取控制节点源IP(Windows)
      win_shell: |
        Get-NetTCPConnection -LocalPort {{ ansible_port }} -State Established | Select-Object -ExpandProperty RemoteAddress
      register: ctrl_ip_windows
      when: ansible_os_family == 'Windows'

    # 4. 统一设置控制节点IP变量
    - name: 定义controller_source_ip变量
      set_fact:
        controller_source_ip: "{{ ctrl_ip_linux.stdout if ansible_os_family != 'Windows' else ctrl_ip_windows.stdout_lines[0] }}"

    # 5. Linux目标主机下载文件
    - name: 下载文件到Linux主机
      get_url:
        url: "http://{{ controller_source_ip }}:{{ web_port }}/{{ target_file }}"
        dest: "/tmp/{{ target_file }}"
      when: ansible_os_family in ['Debian', 'RedHat']

    # 6. Windows目标主机下载文件
    - name: 下载文件到Windows主机
      win_get_url:
        url: "http://{{ controller_source_ip }}:{{ web_port }}/{{ target_file }}"
        dest: "C:\\Temp\\{{ target_file }}"
      when: ansible_os_family == 'Windows'

    # 7. 停止控制节点的临时HTTP服务
    - name: 停止临时HTTP服务器
      delegate_to: localhost
      command: pkill -f "python3 -m http.server {{ web_port }}"
      changed_when: false
      when: ansible_connection != 'local'

关键说明

  • 临时Web服务:使用Python内置的HTTP服务器,无需额外安装;若控制节点已有常驻Web服务,可跳过启动/停止步骤,直接使用对应端口。
  • 连接端口匹配:ansible_port变量会自动获取当前Ansible连接使用的端口(SSH默认22,WinRM默认5985/5986),确保准确匹配当前管理连接。
  • 跨平台兼容:分别针对Linux和Windows系统执行不同的命令获取IP,保证兼容性。

内容的提问来源于stack exchange,提问作者gratz

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 01:47:03