第四章:主机清单管理
深入了解 Ansible Inventory 主机清单的配置和使用。
最后更新: 2024-01-18
页面目录
Ansible 主机清单管理
主机清单(Inventory)是 Ansible 管理的基础,定义了要管理的主机及其分组信息。
Inventory 概述
┌─────────────────────────────────────────────────────────────────┐
│ Inventory 结构 │
├─────────────────────────────────────────────────────────────────┤
│ │
│ Inventory │
│ ├── Static Inventory (静态清单) │
│ │ ├── INI 格式 │
│ │ └── YAML 格式 │
│ └── Dynamic Inventory (动态清单) │
│ ├── AWS EC2 │
│ ├── VMware │
│ ├── OpenStack │
│ └── Custom Scripts │
│ │
└─────────────────────────────────────────────────────────────────┘
静态 Inventory (INI 格式)
基本结构
# inventory/hosts
# 单个主机
web1 ansible_host=192.168.1.10
# 带端口
web2 ansible_host=192.168.1.11 ansible_port=2222
# 带 SSH 用户和密钥
web3 ansible_host=192.168.1.12 ansible_user=ubuntu ansible_ssh_private_key_file=~/.ssh/id_rsa
# 主机组
[webservers]
web1 ansible_host=192.168.1.10
web2 ansible_host=192.168.1.11
web3 ansible_host=192.168.1.12
# 数据库组
[dbservers]
db1 ansible_host=192.168.2.10
db2 ansible_host=192.168.2.11
# 应用组
[appservers]
app1 ansible_host=192.168.3.10
app2 ansible_host=192.168.3.11
# 负载均衡器
[lb]
lb1 ansible_host=192.168.0.10
lb2 ansible_host=192.168.0.11
主机变量
# 为单个主机定义变量
[webservers]
web1 ansible_host=192.168.1.10 nginx_port=80
web2 ansible_host=192.168.1.11 nginx_port=8080
组变量
# 方式一:直接在组内定义变量
[webservers]
web1 ansible_host=192.168.1.10
web2 ansible_host=192.168.1.11
[webservers:vars]
http_port=80
max_connections=1000
ansible_user=deploy
# 方式二:所有主机通用变量
[all:vars]
ansible_python_interpreter=/usr/bin/python3
ansible_connection=ssh
嵌套组(Children)
# 生产环境
[production:children]
webservers
dbservers
appservers
lb
[production:vars]
environment=production
ntp_server=ntp.production.local
# 测试环境
[staging:children]
web_staging
db_staging
[staging:vars]
environment=staging
ntp_server=ntp.staging.local
静态 Inventory (YAML 格式)
基本结构
# inventory/hosts.yml
all:
hosts:
web1:
ansible_host: 192.168.1.10
web2:
ansible_host: 192.168.1.11
db1:
ansible_host: 192.168.2.10
带主机变量
# inventory/hosts.yml
all:
vars:
ansible_user: deploy
ansible_python_interpreter: /usr/bin/python3
children:
webservers:
hosts:
web1:
ansible_host: 192.168.1.10
nginx_port: 80
web2:
ansible_host: 192.168.1.11
nginx_port: 8080
vars:
http_port: 80
dbservers:
hosts:
db1:
ansible_host: 192.168.2.10
db2:
ansible_host: 192.168.2.11
vars:
db_port: 3306
嵌套组
# inventory/hosts.yml
all:
children:
production:
children:
webservers:
hosts:
web1:
web2:
dbservers:
hosts:
db1:
db2:
vars:
environment: production
staging:
children:
web_staging:
hosts:
web-staging1:
db_staging:
hosts:
db-staging1:
vars:
environment: staging
主机范围(Patterns)
数字范围
# 连续主机
[webservers]
web[1:5].example.com
# 等价于:
# web1.example.com, web2.example.com, web3.example.com, web4.example.com, web5.example.com
字母范围
# 字母主机
[dbservers]
db-[a:d].example.com
# 等价于:
# db-a.example.com, db-b.example.com, db-c.example.com, db-d.example.com
组合使用
# 复杂模式
[webservers]
web[01:10]-v[1:3].example.com
动态 Inventory
动态 Inventory 可以从外部数据源(如云平台、CMDB)获取主机列表。
AWS EC2 动态清单
安装 EC2 插件
# 安装 boto3
pip install boto3 botocore
配置文件
# ec2.ini
[ec2]
regions = us-east-1,us-west-2
vpc_destination_variable = ip_address
destination_format = {0}:{1}
destination_format_tags = name
[credentials]
aws_access_key_id = YOUR_ACCESS_KEY
aws_secret_access_key = YOUR_SECRET_KEY
使用动态清单
# 使用 EC2 动态清单
ansible-playbook -i ec2.py site.yml
# 或者使用插件
ansible-playbook -i aws_ec2.yml site.yml
YAML 配置(推荐)
# aws_ec2.yml
plugin: amazon.aws.aws_ec2
regions:
- us-east-1
- us-west-2
filters:
tag:Environment: production
keyed_groups:
- key: tags.Environment
prefix: env
- key: tags.Role
prefix: role
- key: instance_type
prefix: type
VMware 动态清单
# vmware.yml
plugin: community.vmware.vmware_vm_inventory
strict: False
hostname: vcenter.example.com
username: admin@vsphere.local
password: Secret123
validate_certs: False
properties:
- name
- guest.ipAddress
- config.name
- config.annotation
- summary.runtime.powerState
hostnames:
- config.name
filters:
- summary.runtime.powerState == "poweredOn"
groups:
poweredon: True
自定义动态清单脚本
脚本模板
#!/usr/bin/env python3
# inventory/custom.py
import json
import sys
import os
def get_inventory():
inventory = {
'_meta': {
'hostvars': {}
},
'all': {
'hosts': []
},
'webservers': {
'hosts': []
},
'dbservers': {
'hosts': []
}
}
# 从外部数据源获取主机
# 例如从 API、数据库等
hosts = [
{'name': 'web1', 'ip': '192.168.1.10', 'group': 'webservers'},
{'name': 'web2', 'ip': '192.168.1.11', 'group': 'webservers'},
{'name': 'db1', 'ip': '192.168.2.10', 'group': 'dbservers'},
]
for host in hosts:
inventory['all']['hosts'].append(host['name'])
inventory[host['group']]['hosts'].append(host['name'])
inventory['_meta']['hostvars'][host['name']] = {
'ansible_host': host['ip']
}
return inventory
if __name__ == '__main__':
if len(sys.argv) > 1 and sys.argv[1] == '--list':
print(json.dumps(get_inventory()))
elif len(sys.argv) > 1 and sys.argv[1] == '--host':
print(json.dumps({}))
else:
print(json.dumps({}))
使用自定义脚本
# 添加执行权限
chmod +x inventory/custom.py
# 测试清单
./inventory/custom.py --list
# 使用
ansible-playbook -i inventory/custom.py site.yml
目录式 Inventory
将 Inventory 相关文件分散到目录中,便于管理大量主机。
目录结构
inventory/
├── hosts.ini # 主清单文件
├── group_vars/ # 组变量目录
│ ├── all.yml # 所有主机的通用变量
│ ├── webservers.yml # webservers 组变量
│ └── dbservers.yml # dbservers 组变量
└── host_vars/ # 主机变量目录
├── web1.yml # web1 主机变量
└── web2.yml # web2 主机变量
hosts.ini
# inventory/hosts.ini
[webservers]
web1
web2
[dbservers]
db1
db2
[production:children]
webservers
dbservers
组变量文件
# inventory/group_vars/all.yml
---
ansible_user: deploy
ansible_python_interpreter: /usr/bin/python3
ntp_server: pool.ntp.org
# inventory/group_vars/webservers.yml
---
nginx_version: "1.24.0"
app_port: 8080
max_connections: 1000
# inventory/group_vars/dbservers.yml
---
db_port: 3306
db_version: "8.0"
db_name: myapp_production
主机变量文件
# inventory/host_vars/web1.yml
---
nginx_port: 80
server_name: web1.example.com
# inventory/host_vars/web2.yml
---
nginx_port: 8080
server_name: web2.example.com
Inventory 命令
查看 Inventory
# 列出所有主机
ansible-inventory -i inventory/hosts --list
# 列出所有主机(树形结构)
ansible-inventory -i inventory/hosts --tree
# 列出主机的详细信息
ansible-inventory -i inventory/hosts --host web1
# 列出所有组
ansible-inventory -i inventory/hosts --graph
验证 Inventory
# 验证 Inventory 格式
ansible-inventory -i inventory/hosts --validate
# 测试主机连接
ansible all -i inventory/hosts -m ping
Inventory 变量速查
连接变量
| 变量 | 说明 | 示例 |
|---|---|---|
ansible_host |
SSH 主机名/IP | 192.168.1.10 |
ansible_port |
SSH 端口 | 22 |
ansible_user |
SSH 用户名 | root |
ansible_password |
SSH 密码 | secret |
ansible_ssh_private_key_file |
SSH 私钥路径 | ~/.ssh/id_rsa |
ansible_ssh_common_args |
SSH 额外参数 | -o StrictHostKeyChecking=no |
SSH 连接变量(高级)
| 变量 | 说明 | 示例 |
|---|---|---|
ansible_ssh_pipelining |
启用管道 | True |
ansible_ssh_executable |
SSH 可执行文件路径 | /usr/bin/ssh |
远程执行变量
| 变量 | 说明 | 示例 |
|---|---|---|
ansible_python_interpreter |
Python 解释器路径 | /usr/bin/python3 |
ansible_become |
是否启用提权 | True |
ansible_become_method |
提权方法 | sudo |
ansible_become_user |
提权用户 | root |
ansible_become_password |
提权密码 | secret |
Windows 连接变量
| 变量 | 说明 | 示例 |
|---|---|---|
ansible_connection |
连接类型 | winrm |
ansible_port |
WinRM 端口 | 5986 |
ansible_winrm_transport |
认证方式 | ntlm |
ansible_winrm_server_cert_validation |
证书验证 | ignore |
最佳实践
1. 使用目录结构管理 Inventory
inventory/
├── hosts.ini
├── group_vars/
│ └── all.yml
└── host_vars/
2. 分离不同环境
inventory/
├── development/
├── staging/
└── production/
3. 使用 Vault 加密敏感变量
# 加密敏感文件
ansible-vault encrypt inventory/group_vars/all/vault.yml
# 编辑加密文件
ansible-vault edit inventory/group_vars/all/vault.yml
4. 使用动态 Inventory
# 使用云平台动态清单
ansible-playbook -i ec2.py site.yml
下一步
现在你已经掌握了 Inventory 管理。接下来让我们学习 Playbook 的基础知识。