【问题标题】:Ansible: get current target host's IP addressAnsible:获取当前目标主机的 IP 地址
【发布时间】:2017-02-10 16:13:56
【问题描述】:

如何获取角色中当前主机的IP地址?

我知道您可以获取主机所属的组列表和主机的主机名,但我无法找到获取 IP 地址的解决方案。

您可以使用{{inventory_hostname}} 获取主机名,使用{{group_names}} 获取组

我尝试过类似{{ hostvars[{{ inventory_hostname }}]['ansible_ssh_host'] }}ip="{{ hostvars.{{ inventory_hostname }}.ansible_ssh_host }}"

【问题讨论】:

    标签: ansible ansible-facts ansible-template


    【解决方案1】:

    所有地址的列表存储在事实ansible_all_ipv4_addresses 中,ansible_default_ipv4.address 中的默认地址。

    ---
    - hosts: localhost
      connection: local
      tasks:
        - debug: var=ansible_all_ipv4_addresses
        - debug: var=ansible_default_ipv4.address
    

    然后为每个网络接口分配地址......在这种情况下,您可以显示所有事实并找到具有您想要使用的值的那个。

    【讨论】:

    • 你能列出一个任务中的所有标志吗?
    • @SJC 标志?你的意思是事实,对吧?是的,使用register: allfacts 运行setup: 模块并使用- debug: var=allfacts 显示
    • gather_facts 的值必须是true 才能工作。默认情况下为 true,但如果不需要有关主机的信息,则可以将其设置为 false。
    • 错误答案。默认 IP 地址不一定是 ansible 在播放期间使用的地址
    • @poige 如果你问一个新问题可能是不正确的,就像你一样。
    【解决方案2】:

    你可以从hostvars、dictansible_default_ipv4和keyaddress获取IP地址

    hostvars[inventory_hostname]['ansible_default_ipv4']['address']
    

    和IPv6地址分别

    hostvars[inventory_hostname]['ansible_default_ipv6']['address']
    

    一个示例剧本:

    ---
    - hosts: localhost
      tasks:
        - debug: var=hostvars[inventory_hostname]['ansible_default_ipv4']['address']
        - debug: var=hostvars[inventory_hostname]['ansible_default_ipv6']['address']
    

    【讨论】:

    • 这在某些情况下可能会失败,请参阅:medium.com/opsops/…
    • 这不是 ansible 连接的地址。它可能匹配,但不一定要匹配
    【解决方案3】:

    您可以在 template.j2 中使用 {{ ansible_eth0.ipv4.address }},就像使用 {{inventory_hostname}} 一样。

    ps:请参阅以下博文以获取有关HOW TO COLLECT INFORMATION ABOUT REMOTE HOSTS WITH ANSIBLE GATHERS FACTS 的更多信息。

    '希望有一天它会对某人有所帮助 ッ

    【讨论】:

    • 要格外小心。如今,默认网络接口并不总是“eth0”。它有时称为ens3enp2s0 之类的东西。如果你使用ansible_default_ipv4,你有更好的选择,如果它不起作用,那么切换回来寻找一些合理的默认值。
    • 这可能在过去可以工作,但在 Ansible 2.7 中这个变量是未定义的。
    • 这不是 ansible 连接的地址。它可能匹配,但不一定要匹配
    【解决方案4】:

    只需使用ansible_ssh_host 变量

    playbook_example.yml

    - hosts: host1
      tasks:
      - name: Show host's ip
        debug:
          msg: "{{ ansible_ssh_host }}"
    

    hosts.yml

    [hosts]
    host1   ansible_host=1.2.3.4
    

    结果

    TASK [Show host's ip] *********************************************************************************************************************************************************************************************
    ok: [host1] => {
         "msg": "1.2.3.4"
    }
    

    【讨论】:

    • Ansible 2.0 已弃用 ansible_ssh_host 中的“ssh”。如果ansible_host 包含主机名而不是IP,ansible_ssh_host 也可以。
    • 我目前正在使用 2.10 版的 ansible,这段代码在我的情况下很有魅力。
    【解决方案5】:

    简单的调试命令:

    ansible -i inventory/hosts.yaml -m debug -a "var=hostvars[inventory_hostname]" all
    

    输出:

    "hostvars[inventory_hostname]": {
        "ansible_check_mode": false, 
        "ansible_diff_mode": false, 
        "ansible_facts": {}, 
        "ansible_forks": 5, 
        "ansible_host": "192.168.10.125", 
        "ansible_inventory_sources": [
            "/root/workspace/ansible-minicros/inventory/hosts.yaml"
        ], 
        "ansible_playbook_python": "/usr/bin/python2", 
        "ansible_port": 65532, 
        "ansible_verbosity": 0, 
        "ansible_version": {
            "full": "2.8.5", 
            "major": 2, 
            "minor": 8, 
            "revision": 5, 
            "string": "2.8.5"
        }, 
    

    获取主机ip地址:

    ansible -i inventory/hosts.yaml -m debug -a "var=hostvars[inventory_hostname].ansible_host" all
    
    zk01 | SUCCESS => {
        "hostvars[inventory_hostname].ansible_host": "192.168.10.125"
    }
    

    【讨论】:

    • ansible_host 可能包含主机名
    【解决方案6】:

    另一种查找公共 IP 的方法是使用 uri 模块:

        - name: Find my public ip
          uri: 
            url: http://ifconfig.me/ip
            return_content: yes
          register: ip_response
    

    您的 IP 将在ip_response.content

    【讨论】:

    • 另一个返回相同的服务url是:https://ipecho.net/plain
    • @PaulParker ipecho.net/plain 似乎 KO 或询问 api 令牌 ... ifconfig.me 多年来更好更稳定的服务:+1
    • 从未被要求提供 API 令牌。我无法谈论服务的一致性,我没有监控它,但它从未让我失望。
    【解决方案7】:

    如果您想要外部公共 IP,并且您在 AWS 或 Azure 等云环境中,您可以使用ipify_facts module

    # TODO: SECURITY: This requires that we trust ipify to provide the correct public IP. We could run our own ipify server.
    - name: Get my public IP from ipify.org
      ipify_facts:
    

    这会将公共 IP 放入变量 ipify_public_ip

    【讨论】:

    • 这并不总是有效。对我来说ipify_public_ip 变量为空
    • 对于 AWS,inventory_hostname 将是 IP 地址。
    • 这个插件可以在特定的情况下工作,如果你从 NAT 后面访问互联网,它就不能工作。基本上,当服务器可以访问 Internet 并且可以访问 ipify.org 网站以在访问该站点时解析其外部 IP 时,这将起作用。
    • @BerenddeBoer 错了。 inventory_hostname 是库存中设置的任何内容。它可以是.ssh/config 中设置的主机名。
    • @slm 正如我所说,如果您正在寻找外部公共 IP。如果您在 NAT 之后,那么您将没有外部可公开访问的 IP,因此您不会使用此方法。
    【解决方案8】:

    http://docs.ansible.com/ansible/latest/plugins/lookup/dig.html

    所以在模板中,对于 e。 g.:

    {{ lookup('dig', ansible_host) }}
    

    注意事项:

    • 由于不仅可以在清单中使用 DNS 名称,因此最好检查是否已经添加了 IP
    • 显然,此收据无法按预期用于间接主机规范(例如使用跳转主机)

    但它仍然服务于 99%(形象地说)的用例。

    【讨论】:

    • 如果环境中不使用DNS怎么办?
    • (或者,我感觉到你的痛苦。否则你不会问这样幼稚的问题。)——如果清单中没有使用 DNS,只需按照我的回答中所示直接使用 ansible_host。跨度>
    • Abs 如果ansible_host 不是相关主机的 IP 地址怎么办?
    • 这不是“和什么”。这只是“什么”,因为您之前提出的问题没有被计算在内,不要忘记。
    • 我不知道您所说的“真实 IP 地址”是什么。你知道一些不真实的吗?
    【解决方案9】:

    简单的ansible_default_ipv4.address 可能不是您在some cases 中的想法,请使用:

    ansible_default_ipv4.address|default(ansible_all_ipv4_addresses[0])
    

    【讨论】:

      【解决方案10】:

      下面的 sn -p 将返回远程机器的公共 ip 以及默认 ip(即:局域网)

      这也会在引号中打印 ip,以避免在使用配置文件时混淆。

      >> main.yml
      
      ---
      - hosts: localhost
        tasks:
          - name: ipify
            ipify_facts:
          - debug: var=hostvars[inventory_hostname]['ipify_public_ip']
          - debug: var=hostvars[inventory_hostname]['ansible_default_ipv4']['address']
          - name: template
            template:
              src: debug.j2
              dest: /tmp/debug.ansible
      
      >> templates/debug.j2
      
      public_ip={{ hostvars[inventory_hostname]['ipify_public_ip'] }}
      public_ip_in_quotes="{{ hostvars[inventory_hostname]['ipify_public_ip'] }}"
      
      default_ipv4={{ hostvars[inventory_hostname]['ansible_default_ipv4']['address'] }}
      default_ipv4_in_quotes="{{ hostvars[inventory_hostname]['ansible_default_ipv4']['address'] }}"

      【讨论】:

      • 你的一些 cmets 会改进这个答案
      猜你喜欢
      • 1970-01-01
      • 2021-01-18
      • 2012-03-17
      • 2021-02-10
      • 1970-01-01
      • 2012-05-31
      相关资源
      最近更新 更多