ansible inventory及变量提取

Inventory(清单文件) 是 Ansible 用来定义和管理受控主机(被管节点)的配置文件。它告诉 Ansible 哪些服务器需要管理 以及 如何连接这些服务器

1. Inventory 文件格式

Inventory 文件可以使用 INI 格式(常见)或 YAML 格式(更复杂,适用于动态 Inventory)。

(1) INI 格式

# 全局默认变量(可选)
[all:vars]
ansible_user=root
ansible_ssh_private_key_file=/root/.ssh/id_rsa

# 定义主机
[web]
web01 ansible_host=192.168.1.101 ansible_port=22
web02 ansible_host=192.168.1.102 ansible_user=admin

[db]
db01 ansible_host=192.168.1.201

[cache]
cache01 ansible_host=192.168.1.150

# 组嵌套
[app:children]
web
db

(2) YAML 格式

all:
  vars:
    ansible_user: root
    ansible_ssh_private_key_file: /root/.ssh/id_rsa
  children:
    web:
      hosts:
        web01:
          ansible_host: 192.168.1.101
        web02:
          ansible_host: 192.168.1.102
          ansible_user: admin
    db:
      hosts:
        db01:
          ansible_host: 192.168.1.201
    cache:
      hosts:
        cache01:
          ansible_host: 192.168.1.150

yml格式主机清单与组嵌套

[root@master-1 es]# cat inventory.yaml
all:
  # Ansible 习惯使用 children 来定义组,而 all.hosts 一般只包含独立主机,所以这里设置为空 {} 让结构更清晰。
  hosts: {}
  # 这里将下面hosts定义的单独主机用children权保部写到elasticsearch组。
  children:
    elasticsearch:
      hosts:
        es-node1:
          ansible_host: 192.168.43.129
          node_name: es-node1
          # 用于when条件控制,生成证书
          is_ca: true
        es-node2:
          ansible_host: 192.168.43.130
          node_name: es-node2
        es-node3:
          ansible_host: 192.168.43.131
          node_name: es-node3
    application_servers:
      children:
        web_servers:
        db_servers:

host单独主机

all:
  hosts:
    host1:
      ansible_host: 192.168.1.10
      ansible_user: user1
      ansible_ssh_pass: password1
    host2:
      ansible_host: 192.168.1.20
      ansible_user: user2
      ansible_ssh_private_key_file: /path/to/private/key

  children:
    web_servers:
      hosts:
        web1:
          ansible_host: 192.168.1.30
          ansible_user: webuser
        web2:
          ansible_host: 192.168.1.40
          ansible_user: webuser
    db_servers:
      hosts:
        db1:
          ansible_host: 192.168.1.50
          ansible_user: dbuser
        db2:
          ansible_host: 192.168.1.60
          ansible_user: dbuser

2. 关键字段解析

字段作用
ansible_host 指定远程主机的 IP 地址或域名
ansible_port 指定 SSH 连接端口(默认 22)
ansible_user 指定远程主机的 SSH 登录用户
ansible_ssh_private_key_file 指定私钥文件,用于 SSH 认证
ansible_password SSH 连接密码(不推荐,建议使用密钥)
ansible_become 是否使用 sudo 提升权限(yes/no
ansible_become_user 提升权限后切换的用户(如 root

3. Inventory 相关命令

(1) 查看 Inventory 信息

ansible-inventory -i hosts.ini --list

(2) 只测试 web

ansible web -i hosts.ini -m ping

 hostvars与groups

在 Ansible 的 Jinja2 模板 中,groupshostvars不是 内置函数,而是 Ansible 自动提供的全局变量,它们用于访问 Ansible inventory 中的主机信息。

1. groups 变量

groups 是 Ansible inventory 组的映射,它存储了 所有组及其包含的主机

1.1 示例:inventory.ini

[elasticsearch]
es-node-1 ansible_host=192.168.1.101
es-node-2 ansible_host=192.168.1.102
es-node-3 ansible_host=192.168.1.103

[web]
web-1 ansible_host=192.168.2.101
web-2 ansible_host=192.168.2.102

1.2 在 Playbook 或模板中,groups 变量会自动包含:

groups = {
  "elasticsearch": ["es-node-1", "es-node-2", "es-node-3"],
  "web": ["web-1", "web-2"]
}

1.3 使用示例

列出 elasticsearch 组中的所有主机
{% for host in groups['elasticsearch'] %}
  - "{{ host }}"
{% endfor %}

 结果

- "es-node-1"
- "es-node-2"
- "es-node-3"

2. hostvars 变量

hostvars 变量是 Ansible 自动提供的 所有主机的变量映射,用于获取 特定主机的变量

2.1 示例

hostvars = {
  "es-node-1": { "ansible_host": "192.168.1.101", "node_name": "es-node-1" },
  "es-node-2": { "ansible_host": "192.168.1.102", "node_name": "es-node-2" },
  "es-node-3": { "ansible_host": "192.168.1.103", "node_name": "es-node-3" }
}

2.2 使用示例: 获取 es-node-1ansible_host

{{ hostvars['es-node-1']['ansible_host'] }}

结果

192.168.1.101

2.3 在 Jinja2 模板中遍历所有 elasticsearch 组的主机,获取它们的 IP

discovery.seed_hosts:
  {% for host in groups['elasticsearch'] %}
  - "{{ hostvars[host]['ansible_host'] }}"
  {% endfor %}

最终生成的 elasticsearch.yml

discovery.seed_hosts:
  - "192.168.1.101"
  - "192.168.1.102"
  - "192.168.1.103"

总结

变量作用
groups 获取 inventory 组及其主机列表
hostvars 获取某个主机的变量信息
groups['group_name'] 获取指定组的所有主机
hostvars['host_name'] 获取某个主机的所有变量
hostvars['host_name']['variable'] 获取某个主机的特定变量值
结论
  • groups 用于 获取组中的主机列表
  • hostvars 用于 获取每个主机的详细变量
  • 在 Jinja2 模板中结合 groupshostvars 可以 动态生成集群配置,非常适合 Elasticsearch、Kubernetes、Kafka 这种 分布式集群部署

 Inventory 变量提取

elasticsearch.yml.j2

node.name: {{ node_name }}
network.host: {{ ansible_host }}

 为什么 node_nameansible_host 可以直接取?

在 Ansible 的 inventory.yaml 中,你为每个主机(es-node1es-node2es-node3)都定义了变量:

all:
  hosts: {}
  children:
    elasticsearch:
      hosts:
        es-node1:
          ansible_host: 192.168.43.129
          node_name: es-node1
          # 用于when条件控制,生成证书
          is_ca: true
        es-node2:
          ansible_host: 192.168.43.130
          node_name: es-node2
        es-node3:
          ansible_host: 192.168.43.131
          node_name: es-node3

1.为什么 node_nameansible_host 可以直接取?

你的 inventory.yaml 里面定义了每台 Elasticsearch 节点的变量,例如:

es-node1:
  ansible_host: 192.168.43.129
  node_name: es-node1
  • Ansible 会自动把 ansible_hostnode_name 作为主机的变量存储起来,在任务运行时,这些变量就可以直接使用。
  • 当 Playbook 在某个主机上执行任务时,Ansible 只会加载这个主机的变量

2.具体执行流程(分步解析)

假设你有 3 台服务器:

  • es-node1 (192.168.43.129)
  • es-node2 (192.168.43.130)
  • es-node3 (192.168.43.131)

2.1 Ansible 选中一个目标主机执行任务

比如它现在要在 es-node1 上执行:

  • 它会读取 inventory.yaml 里的 es-node1 变量:
ansible_host: 192.168.43.129
node_name: es-node1

2.2 渲染 Jinja2 模板 elasticsearch.yml.j2

你的 elasticsearch.yml.j2 里有:

node.name: {{ node_name }}
network.host: {{ ansible_host }}

es-node1 上执行时,Ansible 自动替换:

node.name: es-node1
network.host: 192.168.43.129

然后它会把这个文件存到:

/opt/elasticsearch/config/elasticsearch.yml

这个文件是 es-node1 专属的,不会影响其他主机

2.3 Ansible 继续到下一台主机

当 Ansible 轮到 es-node2 时:

  • 读取 inventory.yaml 里的 es-node2 变量:
ansible_host: 192.168.43.130
node_name: es-node2

渲染 elasticsearch.yml.j2

node.name: es-node2
network.host: 192.168.43.130

存到 /opt/elasticsearch/config/elasticsearch.yml

3.为什么 Ansible 不需要手动区分主机?

Ansible 运行时,它会并行处理所有的目标主机

  1. 先在 es-node1 上执行任务,并使用 es-node1 的变量。
  2. 然后在 es-node2 上执行任务,并使用 es-node2 的变量。
  3. 最后在 es-node3 上执行任务,并使用 es-node3 的变量。

这就是 Ansible 自动区分不同主机变量 的核心机制 🎯。

 

posted @ 2025-02-17 13:43  不会跳舞的胖子  阅读(60)  评论(0)    收藏  举报