Ansible: lấy địa chỉ IP của máy chủ mục tiêu hiện tại


100

Làm cách nào để bạn có được địa chỉ IP của máy chủ lưu trữ hiện tại với vai trò?

Tôi biết bạn có thể lấy danh sách các nhóm mà máy chủ lưu trữ là thành viên và tên máy chủ của máy chủ lưu trữ nhưng tôi không thể tìm thấy giải pháp để lấy địa chỉ IP.

Bạn có thể lấy tên máy chủ bằng cách sử dụng {{inventory_hostname}}và nhóm bằng cách sử dụng{{group_names}}

Tôi đã thử những thứ như {{ hostvars[{{ inventory_hostname }}]['ansible_ssh_host'] }}ip="{{ hostvars.{{ inventory_hostname }}.ansible_ssh_host }}"

Câu trả lời:


124

Một danh sách tất cả các địa chỉ được lưu trữ trên thực tế ansible_all_ipv4_addresses, một địa chỉ mặc định trong ansible_default_ipv4.address.

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

Sau đó, có các địa chỉ được gán cho mỗi giao diện mạng ... Trong những trường hợp như vậy, bạn có thể hiển thị tất cả các dữ kiện và tìm một địa chỉ có giá trị bạn muốn sử dụng.


Làm thế nào để bạn hiển thị tất cả các cờ?
SJC

1
Bạn có thể liệt kê tất cả các cờ trong một nhiệm vụ không?
SJC

2
@SJC Cờ? Ý bạn là sự thật, phải không? Vâng, chạy setup:mô-đun với register: allfactsvà hiển thị với- debug: var=allfacts
techraf

4
giá trị của gather_factsphải là trueđể điều này hoạt động. nó đúng theo mặc định nhưng người ta có thể chuyển nó thành sai nếu thông tin về máy chủ không được yêu cầu.
shshnk

1
@poige Có thể không chính xác nếu bạn hỏi một câu hỏi mới, giống như bạn.
techraf

69

Bạn có thể lấy địa chỉ IP từ hostvars, dict ansible_default_ipv4và khóaaddress

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

và địa chỉ IPv6 tương ứng

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

Một playbook mẫu:

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

Điều này có thể không thành công trong một số trường hợp, hãy xem điều này: medium.com/opsops/…
RafalS

25

Bạn có thể sử dụng trong template.j2 của mình {{ ansible_eth0.ipv4.address }}giống như cách bạn sử dụng {{inventory_hostname}}.

ps: Vui lòng tham khảo blogpost sau đây để có thêm thông tin về CÁCH THU THẬP THÔNG TIN VỀ CÁC TRANG WEB TỪ XA VỚI SỰ THẬT CÓ TRÁCH NHIỆM .

'hy vọng một ngày nào đó nó sẽ giúp ích cho ai đó ッ


13
Hãy hết sức cẩn thận. Ngày nay, giao diện mạng mặc định không phải lúc nào cũng là 'eth0'. Đôi khi nó được gọi là ens3hoặc enp2s0và những thứ như vậy. Bạn chỉ có thể đặt cược tốt hơn nếu bạn sử dụng ansible_default_ipv4và nếu nó không hoạt động, sau đó quay lại tìm kiếm một số mặc định lành mạnh.
Gabor Garami

4
Điều này có thể đã từng hoạt động trong quá khứ nhưng với Ansible 2.7, biến này không được xác định.
Dirk

5

Nếu bạn muốn có IP công cộng bên ngoài và bạn đang ở trong môi trường đám mây như AWS hoặc Azure, bạn có thể sử dụng mô-đun 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:

Điều này sẽ đặt IP công cộng vào biến ipify_public_ip.


Điều này không phải lúc nào cũng hoạt động. Đối với tôi ipify_public_ipbiến trống
Davide

2
Đối với AWS, kho_hostname sẽ là địa chỉ ip.
Berend de Boer

Plugin này có thể hoạt động trong một số trường hợp nhất định, nếu bạn đang truy cập Internet từ sau NAT, nó sẽ không hoạt động. Về cơ bản, điều này hoạt động khi các máy chủ có thể truy cập internet và có thể truy cập trang web ipify.org để phân giải IP bên ngoài của chúng khi truy cập trang web.
slm

1
@BerenddeBoer Sai. inventory_hostnamelà bất cứ thứ gì được đặt trong khoảng không quảng cáo. Nó có thể là một tên máy chủ lưu trữ như đã đặt .ssh/config.
Teresa e Junior

@slm như tôi đã nói, nếu bạn đang tìm IP công cộng bên ngoài. Nếu bạn đứng sau NAT, thì bạn sẽ không có IP bên ngoài có thể truy cập công khai nên bạn sẽ không sử dụng phương pháp này.
Simon Woodside

4

Một cách khác để tìm IP công cộng sẽ là sử dụng urimô-đun:

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

IP của bạn sẽ ở ip_response.content


Một url dịch vụ khác cũng trả về như vậy là:https://ipecho.net/plain
Paul Parker,

@PaulParker ipecho.net/plain dường như KO hoặc yêu cầu mã thông báo api ... ifconfig.me dịch vụ ổn định và tốt hơn kể từ nhiều năm: +1
bastien

Chưa bao giờ được yêu cầu mã thông báo API. Tôi không thể nói về tính nhất quán của dịch vụ, tôi chưa giám sát nó, nhưng nó chưa bao giờ khiến tôi thất vọng.
Paul Parker

2

Lệnh gỡ lỗi đơn giản:

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

đầu ra:

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

lấy địa chỉ ip máy chủ:

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

1

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

như vậy trong mẫu, ví dụ:

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

Ghi chú:

  • Vì không chỉ tên DNS có thể được sử dụng trong khoảng không quảng cáo, hãy kiểm tra nếu nó không phải là IP thì tốt hơn hãy thêm vào
  • Rõ ràng, biên nhận này sẽ không hoạt động như dự định đối với các thông số kỹ thuật của máy chủ gián tiếp (ví dụ như sử dụng máy chủ nhảy)

Nhưng nó vẫn phục vụ 99% (nói theo nghĩa bóng) các trường hợp sử dụng.


1
Và điều gì sẽ xảy ra nếu DNS không được sử dụng trong môi trường?
techraf

(Hoặc, tôi cảm thấy nỗi đau của bạn. Nếu không, bạn sẽ không hỏi những câu hỏi ngây ngô như thế.) - Nếu DNS không được sử dụng trong kho, người ta chỉ cần sử dụng trực tiếp ansible_host như được chỉ ra trong câu trả lời của tôi.
màu be,

1
Áp dụng điều gì nếu ansible_hostkhông phải là địa chỉ IP của máy chủ được đề cập?
techraf

đây không phải là "và cái gì". Đó chỉ là "điều gì" khiến câu hỏi trước đây của bạn không được tính, đừng quên.
màu be,

1
Tôi không có manh mối nào bạn đang gọi là "địa chỉ IP thực". Bạn có biết một số cái không có thật không?
màu be,

1

Thông thường ansible_default_ipv4.addresscó thể không phải như bạn nghĩ trong một số trường hợp , hãy sử dụng:

ansible_default_ipv4.address|default(ansible_all_ipv4_addresses[0])

0

Đoạn mã sau sẽ trả về ip công cộng của máy từ xa và cũng là ip mặc định (ví dụ: LAN)

Điều này cũng sẽ in ip trong dấu ngoặc kép để tránh nhầm lẫn trong việc sử dụng các tệp cấu hình.

>> 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
Một số nhận xét của bạn sẽ cải thiện câu trả lời này
Đánh dấu vào

0

Chỉ cần sử dụng ansible_ssh_hostbiến

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

Kết quả

TASK [Show host's ip] *********************************************************************************************************************************************************************************************
ok: [host1] => {
     "msg": "1.2.3.4"
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.