Ansible 主机清单
主机清单用来定义哪些主机在 Ansible 的管理范围。主机清单支持以下写法:
- IP 地址
- 主机名
- 范围(
server[b:c]
) - 主机组(
webserver
) - 组的子组(
lnmp:children
)
主机清单
172.25.250.10
[webserver]
server[b:c]
[mysql]
172.25.250.1[3:4]
[lnmp:children]
webserver
mysql
- 直接定义主机名或地址,当前
172.25.250.10
不属于任何组。
172.25.250.10
- 定义主机组,
webserver
主机组包含serverb
到serverc
[webserver]
server[b:c]
- 组和组之间可以嵌套
[lnmp:children]
webserver
mysql
- 使用范围来匹配主机
server[b:c]
172.25.250.1[3:4]
选择主机和主机组
匹配所有主机
ansible all --list-hosts
hosts (5):
172.25.250.10
serverb
serverc
172.25.250.13
172.25.250.14
匹配指定的主机或主机组
ansible serverc --list-hosts
hosts (1):
serverc
ansible lnmp --list-hosts
hosts (4):
serverb
serverc
172.25.250.13
172.25.250.14
匹配多个主机和主机组
ansible serverb,serverc --list-hosts
hosts (2):
serverb
serverc
ansible webserver,mysql --list-hosts
hosts (4):
serverb
serverc
172.25.250.13
172.25.250.14
匹配没有组的主机
ansible ungrouped --list-hosts
hosts (1):
172.25.250.10
使用通配符选择主机
ansible server* --list-hosts
hosts (2):
serverb
serverc
ansible *25.* --list-hosts
hosts (3):
172.25.250.10
172.25.250.13
172.25.250.14
通配符逻辑组合
&
:取交集!
:去反,
:取并集
# 匹配所有以 server 开头的主机,排除 serverc
ansible 'server*,!serverc' --list-hosts
hosts (1):
serverb
# 匹配组 webserver 和组 lnmp 两个组内相同的主机
ansible 'webserver,&lnmp' --list-hosts
hosts (2):
serverb
serverc
# 在上一个例子在排除 serverc
ansible 'webserver,&lnmp,!serverc' --list-hosts
hosts (1):
serverb
使用正则匹配
# '~'后接正则表达式,下边例子表示匹配以 se 开头的主机
ansible '~^se' --list-hosts
hosts (2):
serverb
serverc
通过 limit 匹配主机
ansible all --limit serverb,172.25.250.13 --list-hosts
hosts (2):
serverb
172.25.250.13
# 使用文件匹配
cat <<EOF > ip.txt
serverb
serverc
172.25.250.14
EOF
ansible all --limit @/home/student/ansible/ip.txt --list-hosts
hosts (3):
serverb
serverc
172.25.250.14
特殊的主机 localhost
最后说一个特殊的主机 localhost
,这是一个特殊的主机,它不需要在主机清单里声明就可以使用。
localhost
表示本地主机,未在主机清单中声明时,Ansible 会使用 local
方式连接,相当于在本地执行命令,以下是它和 SSH 连接的区别:
项目 | local | ssh |
---|---|---|
执行位置 | 控制节点本地执行 | 远程通过 ssh 执行 |
是否走网络 | 否 | 是 |
权限控制 | 当前用户 | 可指定远程用户 |
常见用途 | 控制节点配置、本地调试 | 正式环境、管理多台主机 |
可以通过在主机清单内明确指定 localhost
来设置连接方式为 ssh
。
local
和 ssh
连接有个最大的区别就是 local
会忽略 remote_user
选项,可以看以下例子:
# 配置文件
[test@awx-1 ansible]$ cat ansible.cfg
[defaults]
inventory = ./inventory
fork = 20
ask_pass = False
remote_user = remote-manager
host_key_checking = False
ansible_python_interpreter = /usr/bin/python3.9
[privilege_escalation]
become = True
become_method = sudo
become_user = root
become_ask_pass = False
# 当前用户
[test@awx-1 ansible]$ id
uid=1000(test) gid=1000(test) groups=1000(test) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
# 查看主机清单,当前 localhost 已被注释
[test@awx-1 ansible]$ cat inventory
#localhost ansible_ssh_password=redhat
# 测试
[test@awx-1 ansible]$ ansible localhost -b -m command -a 'id'
localhost | CHANGED | rc=0 >>
uid=0(root) gid=0(root) groups=0(root) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
# 可以看到可以执行成功
# 删除主机清单的注释
[test@awx-1 ansible]$ cat inventory
localhost ansible_ssh_password=redhat
# 再次测试
[test@awx-1 ansible]$ ansible localhost -b -m command -a 'id'
localhost | UNREACHABLE! => {
"changed": false,
"msg": "Failed to connect to the host via ssh: remote-manager@localhost: Permission denied (publickey,gssapi-keyex,gssapi-with-mic,password,keyboard-interactive).",
"unreachable": true
}
# 可以看到报错了,因为 test 不能直接 ssh remote-manager 用户
可以看到 local
方式会忽略 remote_user
选项,而 ssh
不会忽略。