清单文件 ¶
1. Inventory 简介 ¶
1. 什么是 inventory?
-
Ansible 的 Inventory(清单)是 Ansible 用来描述和组织需要管理的主机列表的文件或系统。清单中不仅可以定义哪些主机参与自动化管理,还可以设定主机分组、变量等。详细了解 Ansible Inventory 的各个要点能帮助你更有效地管理和执行自动化任务。
-
Ansible 中,inventory 地址清单文件用于定义管理的主机和主机组。它是 Ansible 操作的基础,包含了所有目标主机的信息。通常,inventory 文件位于 /etc/ansible/hosts,但您也可以在任何地方定义并在运行 Ansible 命令时指定不同的地址清单文件。可以是一个简单的 INI 风格文件,也可以是复杂的 YAML 文件,甚至可以是通过动态处理生成的 JSON 文件
Note
/etc/ansible/hosts
文件格式
-
inventory文件遵循INI文件风格,中括号中的字符为组名
-
可以将同一个主机同时归并到多个不同的组中
-
目标主机使用了非默认的SSH端口,可在主机名称后使用冒号加端口号来标明
Inventory 清单
Inventory 主机清单是 Ansible 的主机清单文件,其中包含了目标主机的 IP 地址、用户名、密码等信息。可以使用脚本或者手工方式来维护这个文件。
-
ansible 的主要功用在于批量主机操作,为了便捷地使用其中的部分主机,可以在 inventory 中将其分组命名
-
默认的 inventory 为/etc/ansible/hosts
-
inventory 可以有多个,且也可以通过 Dynamic Inventory 来动态生成
-
可以在每个主机后面指定用户名+密码+端口:
- ansible_ssh_port: 指定 ssh 端口
- ansible_ssh_user:指定 ssh 用户
- ansible_ssh_pass: 指定 ssh 用户登录是认证密码(明文密码不安全)
- ansible_sudo_pass: 指明 sudo 时候的密码
2. 静态 Inventory ¶
静态 Inventory 是一个静态文件,其中列出了所有的主机及其相关的配置信息。常见格式有 INI 和 YAML 格式。
# 文件名:hosts
# 单个主机
webserver ansible_host=192.168.1.10 ansible_user=root ansible_pass='1' ansible_port='22'
# 定义一个分组的主机
[webservers] # 组内包含多个主机。
web1 ansible_host=192.168.1.11 ansible_user=root
web2 ansible_host=192.168.1.12 ansible_user=root
[dbservers] # 组内包含多个主机。
db1 ansible_host=192.168.1.21 ansible_user=root
db2 ansible_host=192.168.1.22 ansible_user=root
# 组中的子组
[staging:children] # 定义了 staging 组,其中包含 webservers 和 dbservers 子组。
webservers
dbservers
# 附加组级变量
[webservers:vars] # 为组内所有主机指定了 SSH 私钥文件。
ansible_ssh_private_key_file=/path/to/keyfile
# 文件名:hosts.yaml
all:
hosts:
webserver:
ansible_host: 192.168.1.10
ansible_user: root
children:
webservers:
hosts:
web1:
ansible_host: 192.168.1.11
ansible_user: root
web2:
ansible_host: 192.168.1.12
ansible_user: root
vars:
ansible_ssh_private_key_file: /path/to/keyfile
dbservers:
hosts:
db1:
ansible_host: 192.168.1.21
ansible_user: root
db2:
ansible_host: 192.168.1.22
ansible_user: root
staging:
children:
webservers:
dbservers:
使用地址清单文件
- 指定地址清单文件: 您可以在运行 Ansible 命令时指定使用哪个地址清单文件。
ansible-playbook -i /path/to/your/inventory playbook.yml
- 动态地址清单: 除了静态的文件,Ansible 也支持动态地址清单。动态地址清单通过脚本从外部资源(如云提供商的 API)获取主机信息。要启用动态地址清单,只需在 Ansible 命令中指定该脚本即可。
ansible-playbook -i /path/to/your/dynamic_inventory.py playbook.yml
3. 动态 Inventory ¶
1. 什么是动态 Inventory? ¶
- 动态 Inventory 是通过脚本或插件来生成和更新的主机列表。对于有大量变动主机的环境,使用动态 Inventory 更为方便。Ansible 提供了多种动态 Inventory 插件(如 AWS、GCP、Azure 等),也可以编写自定义动态 Inventory 脚本。
- 动态 Inventory 允许您在运行时从外部系统或服务中获取主机信息。这意味着您可以根据当前环境自动获取和更新主机列表,而不需要手动修改 static Inventory 文件。
常见的动态 Inventory 数据源包括:
- 云服务提供商:如 AWS、GCP、Azure
- 容器编排系统:如 Kubernetes
- 定制的配置管理数据库(CMDB)系统
使用动态 Inventory,您可以更高效地管理和操作大规模、快速变化的环境,减轻了手动更新静态 Inventory 文件的负担。
2. 如何实现动态 Inventory? ¶
实现动态 Inventory 通常涉及三个步骤:
- 编写或获取动态 Inventory 脚本: 这个脚本从数据源获取主机信息并输出为 JSON 格式。Ansible 提供了很多现成的动态 Inventory 脚本,也可以自己编写。
- 配置 Ansible 使用动态 Inventory 脚本: 修改 Ansible 配置,让它使用动态 Inventory 脚本。
- 运行 Ansible 命令: 使用动态 Inventory 脚本运行 Ansible 命令。
Inventory 相关使用
#!/usr/bin/env python
import json
inventory = {
"webservers": {
"hosts": ["web1.example.com", "web2.example.com"],
"vars": {
"ansible_user": "webuser"
}
},
"dbservers": {
"hosts": ["db1.example.com", "db2.example.com"],
"vars": {
"ansible_user": "dbuser"
}
},
"_meta": {
"hostvars": {
"web1.example.com": {"ansible_host": "192.168.1.10"},
"web2.example.com": {"ansible_host": "192.168.1.11"},
"db1.example.com": {"ansible_host": "192.168.1.12"},
"db2.example.com": {"ansible_host": "192.168.1.13"},
}
}
}
print(json.dumps(inventory, indent=2))
- 然后,在 Ansible 配置文件 ansible.cfg 中指定这个动态 Inventory 脚本:
# 文件名:ansible.cfg
[defaults]
inventory = ./动态_inventory.py
4. Ansible Inventory 变量 ¶
Ansible 允许在 Inventory 文件中定义变量,可以是主机变量、组变量、甚至是嵌套的组变量。
定义变量
一. 主机变量: 定义某个主机的变量
# INI 格式
host1.example.com ansible_user=someuser ansible_port=2222
# YAML 格式
all:
hosts:
host1.example.com:
ansible_user: someuser
ansible_port: 2222
二. 组变量: 定义某个组所有主机定义的变量
# INI 格式
[webservers:vars]
ansible_user=webuser
ansible_port=2222
# YAML 格式
all:
children:
webservers:
vars:
ansible_user: webuser
ansible_port: 2222
三. 子组和父组的变量继承
- all:包含清单中所有的主机
- ungrouped:未属于任何组的主机
- group_name:children:子组定义,用于更复杂的组结构
# INI 格式
[all:vars]
ansible_user=commonuser
[webservers]
web1.example.com
web2.example.com
[dbservers]
db1.example.com
db2.example.com
# 定义一个 webgroup,包含 webs 和 dbs 两个子组
[webgroup:children]
webservers
dbservers
# YAML 格式
all:
vars:
ansible_user: commonuser
children:
webservers:
hosts:
web1.example.com:
web2.example.com:
dbservers:
hosts:
db1.example.com:
db2.example.com:
webgroup:
children:
webservers:
dbservers:
怎么使用变量
一. 定义变量
# INI 格式
# Web服务器组
[webservers]
web1 ansible_host=192.168.1.101 ansible_user=root
web2 ansible_host=192.168.1.102 ansible_user=root
# DB服务器组
[dbservers]
db1 ansible_host=192.168.1.201 ansible_user=root
db2 ansible_host=192.168.1.202 ansible_user=root
# 定义组变量
[webservers:vars]
ansible_python_interpreter=/usr/bin/python3
[dbservers:vars]
ansible_python_interpreter=/usr/bin/python3
all:
children:
webservers:
hosts:
web1:
ansible_host: 192.168.1.101
ansible_user: root
web2:
ansible_host: 192.168.1.102
ansible_user: root
vars:
ansible_python_interpreter: /usr/bin/python3
dbservers:
hosts:
db1:
ansible_host: 192.168.1.201
ansible_user: root
db2:
ansible_host: 192.168.1.202
ansible_user: root
vars:
ansible_python_interpreter: /usr/bin/python3
二. 在 Playbooks 中使用变量 假设我们有一个简单的 playbook.yaml,需要在远程主机上执行一些任务并使用这些变量。
---
- name: Configure web and db servers
hosts: all
tasks:
- name: Ensure we are using the correct Python interpreter
command: "{{ ansible_python_interpreter }} --version"
register: python_version_output
- name: Display Python version
debug:
msg: "Python version on {{ inventory_hostname }} is {{ python_version_output.stdout }}"
- name: Ensure Apache is installed
yum:
name: httpd
state: present
when: "'webservers' in group_names"
- name: Ensure MySQL is installed
yum:
name: mysql-server
state: present
when: "'dbservers' in group_names"
三、变量的优先级 在 Ansible 中,变量的优先级从低到高依次是:
- Inventory 文件(inventory.ini 或 inventory.yml)。
- 分组变量文件(group_vars)。
- 主机变量文件(host_vars)。
- 播放变量(使用 vars 块定义)。
- 针对特定任务的变量(使用 vars 块定义在任务内部)。
四、定义分组变量文件
---
# Web服务器变量
ansible_python_interpreter: /usr/bin/python3
httpd_port: 80
---
# 数据库服务器变量
ansible_python_interpreter: /usr/bin/python3
mysql_port: 3306
五、定义主机变量文件
---
ansible_host: 192.168.1.101
httpd_site_name: web1.example.com
---
ansible_host: 192.168.1.102
httpd_site_name: web2.example.com
六、在 Playbooks 中使用更多自定义变量
---
- name: Configure web and db servers
hosts: all
vars_files:
- group_vars/webservers.yml
- group_vars/dbservers.yml
tasks:
- name: Ensure we are using the correct Python interpreter
command: "{{ ansible_python_interpreter }} --version"
register: python_version_output
- name: Display Python version
debug:
msg: "Python version on {{ inventory_hostname }} is {{ python_version_output.stdout }}"
- name: Ensure Apache is installed and configured
when: "'webservers' in group_names"
block:
- name: Ensure Apache is installed
yum:
name: httpd
state: present
- name: Ensure Apache is started
service:
name: httpd
state: started
- name: Ensure Apache listens on the correct port
lineinfile:
path: /etc/httpd/conf/httpd.conf
regexp: '^Listen '
line: "Listen {{ httpd_port }}"
- name: Ensure Apache site name is configured
lineinfile:
path: /etc/httpd/conf/httpd.conf
regexp: '^ServerName '
line: "ServerName {{ httpd_site_name }}"
- name: Ensure MySQL is installed and configured
when: "'dbservers' in group_names"
block:
- name: Ensure MySQL is installed
yum:
name: mysql-server
state: present
- name: Ensure MySQL is started
service:
name: mysqld
state: started
- name: Ensure MySQL listens on the correct port
lineinfile:
path: /etc/my.cnf
regexp: '^port '
line: "port={{ mysql_port }}"