ตอบได้: รับที่อยู่ IP ของโฮสต์เป้าหมายปัจจุบัน


103

คุณรับที่อยู่ IP ปัจจุบันของโฮสต์ในบทบาทได้อย่างไร?

ฉันรู้ว่าคุณสามารถรับรายชื่อกลุ่มที่โฮสต์เป็นสมาชิกและชื่อโฮสต์ของโฮสต์ได้ แต่ฉันไม่พบวิธีแก้ปัญหาในการรับที่อยู่ IP

คุณสามารถรับชื่อโฮสต์โดยใช้{{inventory_hostname}}และกลุ่มโดยใช้{{group_names}}

ฉันได้ลองสิ่งต่างๆเช่น{{ hostvars[{{ inventory_hostname }}]['ansible_ssh_host'] }} และip="{{ hostvars.{{ inventory_hostname }}.ansible_ssh_host }}"

คำตอบ:


128

รายการที่อยู่ทั้งหมดจะถูกเก็บไว้ในความเป็นจริง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

1
คุณสามารถแสดงรายการแฟล็กทั้งหมดจากภายในงานได้หรือไม่?
SJC

2
@SJC แฟล็ก? คุณหมายถึงข้อเท็จจริงใช่ไหม? ใช่เรียกใช้setup:โมดูลregister: allfactsและแสดงด้วย- debug: var=allfacts
techraf

4
ค่าของสิ่งนี้gather_factsจะต้องมีtrueเพื่อให้ได้ผล เป็นจริงตามค่าเริ่มต้น แต่อาจเปลี่ยนเป็นเท็จหากไม่จำเป็นต้องใช้ข้อมูลเกี่ยวกับโฮสต์
shshnk

1
@poige อาจไม่ถูกต้องหากคุณถามคำถามใหม่เหมือนที่คุณทำ
techraf

72

คุณสามารถรับที่อยู่ IP จากhostvarsกำหนดansible_default_ipv4และคีย์address

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

และที่อยู่ IPv6 ตามลำดับ

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

Playbook ตัวอย่าง:

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

1
สิ่งนี้อาจล้มเหลวในบางกรณีโปรดดูที่medium.com/opsops/…
RafalS

26

คุณสามารถใช้ใน template.j2 ของคุณแบบเดียวกับที่คุณใช้{{ ansible_eth0.ipv4.address }}{{inventory_hostname}}

ps: โปรดดูที่บล็อกโพสต์ต่อไปนี้เพื่อรับข้อมูลเพิ่มเติมเกี่ยวกับวิธีการรวบรวมข้อมูลเกี่ยวกับโฮสติ้งระยะไกลด้วยข้อเท็จจริงที่ เข้าใจได้

'หวังว่าสักวันมันจะช่วยใครสักคนッ


13
ระมัดระวังเป็นพิเศษ ปัจจุบันอินเทอร์เฟซเครือข่ายเริ่มต้นไม่ใช่ 'eth0' เสมอไป บางครั้งมันก็เรียกens3หรือenp2s0และสิ่งนั้น ๆ คุณมีการเดิมพันที่ดีกว่าหากคุณใช้ansible_default_ipv4และหากมันไม่ได้ผลให้เปลี่ยนกลับไปมองหาค่าเริ่มต้นที่มีเหตุผล
Gabor Garami

4
สิ่งนี้อาจเคยใช้ได้ผลในอดีต แต่ด้วย Ansible 2.7 ตัวแปรนี้ไม่ได้กำหนดไว้
เดิร์ก

5

หากคุณต้องการIP สาธารณะภายนอกและคุณอยู่ในสภาพแวดล้อมระบบคลาวด์เช่น AWS หรือ Azure คุณสามารถใช้โมดูล ipify_facts :

# 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ตัวแปรสำหรับฉันว่างเปล่า
Davide

2
สำหรับ AWS Inventory_hostname จะเป็นที่อยู่ IP
Berend de Boer

ปลั๊กอินนี้สามารถทำงานได้ในบางสถานการณ์หากคุณกำลังเข้าถึงอินเทอร์เน็ตจากหลัง NAT มันจะไม่ทำงาน โดยทั่วไปจะใช้งานได้เมื่อเซิร์ฟเวอร์สามารถเข้าถึงอินเทอร์เน็ตได้และสามารถเข้าสู่เว็บไซต์ ipify.org เพื่อแก้ไข IP ภายนอกเมื่อเข้าถึงไซต์
slm

1
@BerenddeBoer ผิด. inventory_hostnameคืออะไรก็ได้ที่กำหนดไว้ในสินค้าคงคลัง .ssh/configมันอาจจะเป็นชื่อโฮสต์ตามที่กำหนดใน
Teresa e Junior

@slm อย่างที่บอกถ้าคุณกำลังมองหา IP สาธารณะภายนอก หากคุณอยู่เบื้องหลัง NAT คุณจะไม่มี IP ที่สามารถเข้าถึงได้จากภายนอกดังนั้นคุณจะไม่ใช้วิธีนี้
Simon Woodside

4

อีกวิธีหนึ่งในการค้นหา 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
Paul Parker

@PaulParker ipecho.net/plainดูเหมือนว่า KO หรือขอโทเค็น api ... ifconfig.me บริการที่ดีขึ้นและมีเสถียรภาพตั้งแต่ปี: +1
bastien

ไม่เคยถูกขอโทเค็น API ฉันไม่สามารถพูดถึงความสม่ำเสมอของการบริการฉันไม่ได้ตรวจสอบ แต่ก็ไม่เคยทำให้ฉันล้มเหลว
Paul Parker

3

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

ดังนั้นในเทมเพลตเช่น:

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

หมายเหตุ:

  • เนื่องจากไม่เพียง แต่สามารถใช้ชื่อ DNS ในสินค้าคงคลังได้จึงควรตรวจสอบว่ายังไม่ได้เพิ่ม IP หรือไม่
  • เห็นได้ชัดว่าใบเสร็จนี้ไม่สามารถใช้งานได้ตามที่ตั้งใจไว้สำหรับข้อกำหนดของโฮสต์ทางอ้อม (เช่นการใช้โฮสต์กระโดดเป็นต้น)

แต่ยังคงให้บริการกรณีการใช้งาน 99% (เปรียบเปรย)


1
และจะเกิดอะไรขึ้นถ้า DNS ไม่ได้ใช้ในสภาพแวดล้อม?
techraf

(หรือฉันรู้สึกเจ็บปวดของคุณมิฉะนั้นคุณจะไม่ถามคำถามไร้เดียงสาแบบนั้น) - หาก DNS ไม่ได้ใช้ในพื้นที่โฆษณาเพียงแค่ใช้ ansible_host โดยตรงตามที่ระบุในคำตอบของฉัน
poige

1
Abs จะเกิดอะไรขึ้นถ้าansible_hostไม่ใช่ที่อยู่ IP ของโฮสต์ที่เป็นปัญหา
techraf

นี่ไม่ใช่ "และอะไร" มันเป็นเพียง "อะไร" ทำให้คำถามที่ถามก่อนหน้านี้ไม่นับอย่าลืม
poige

1
ฉันไม่รู้ว่าคุณเรียกว่า "ที่อยู่ IP จริง" คุณรู้จักคนที่ไม่จริงบ้างไหม?
poige

3

คำสั่งแก้จุดบกพร่องอย่างง่าย:

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"
}

3

เพียงแค่ใช้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"
}


0

ตัวอย่างต่อไปนี้จะส่งคืน IP สาธารณะของเครื่องระยะไกลและ ip เริ่มต้นด้วย (เช่น: LAN)

สิ่งนี้จะพิมพ์ ip ในเครื่องหมายคำพูดเพื่อหลีกเลี่ยงความสับสนในการใช้ไฟล์ config

>> 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'] }}"


2
ความคิดเห็นบางส่วนโดยที่คุณจะปรับปรุงคำตอบนี้
Marged
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.