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 模板 中,groups
和 hostvars
并 不是 内置函数,而是 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
变量会自动包含:
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-1
的 ansible_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 模板中结合
groups
和hostvars
可以 动态生成集群配置,非常适合 Elasticsearch、Kubernetes、Kafka 这种 分布式集群部署。
Inventory 变量提取
elasticsearch.yml.j2
node.name: {{ node_name }}
network.host: {{ ansible_host }}
为什么 node_name
和 ansible_host
可以直接取?
在 Ansible 的 inventory.yaml
中,你为每个主机(es-node1
、es-node2
、es-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_name
和 ansible_host
可以直接取?
你的 inventory.yaml
里面定义了每台 Elasticsearch 节点的变量,例如:
es-node1: ansible_host: 192.168.43.129 node_name: es-node1
- Ansible 会自动把
ansible_host
和node_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 运行时,它会并行处理所有的目标主机:
- 先在
es-node1
上执行任务,并使用es-node1
的变量。 - 然后在
es-node2
上执行任务,并使用es-node2
的变量。 - 最后在
es-node3
上执行任务,并使用es-node3
的变量。
这就是 Ansible 自动区分不同主机变量 的核心机制 🎯。
本文来自博客园,作者:不会跳舞的胖子,转载请注明原文链接:https://www.cnblogs.com/rtnb/p/18719793