S_lion's Studio

(三)主机清单inventory

字数统计: 2.3k阅读时长: 9 min
2021/08/24 Share

上一章在讲ansible基本用法时的几个例子中host都是localhost,是因为在没有对ansible进行任何配置时,ansible只能通过localhost来控制本机。

inventory⽤于定义ansible要管理的主机列表,可以定义单个主机和主机组。/etc/ansible/hosts就是默认的全局inventory,当然我们可以在配置文件中修改此配置项,但通常不会去修改这个配置项,如果在其它地方定义了inventory文件,可以直接在ansible的命令行中使用-i选项去指定自定义的inventory文件。既然ansible的意义就是批量控制远程节点执行任务,该如何配置inventory呢。

配置inventory

ansible inventory文件遵循ini配置格式。

先看下我本地的一些示例:

主机

1
2
3
4
5
192.168.100.10
slions_pc1 ansible_password=123
my_pc1 ansible_host=192.168.100.10
192.168.100.10:22
192.168.100.1[0:2]
  • 第一行通过IP地址定义主机节点。
  • 第二行通过主机名定义,后面添加了一个主机变量ansible_password=xxx,指明连接该节点时的密码,需要注意的时,如果使用密码进行连接,要取消ansible配置文件中host_key_checking = False的注释。
  • 第三行使用了主机变量ansible_host=IP,需要注意的是,如果定义了该主机变量,那么其前⾯的主机名就称为别名。可以命名为任何名称,这里是my_pc1。使用了ansible_host时连接主机会使用其定义的ip地址进行连接,而不会进行dns解析。
  • 第四行定义主机时还指明了端口号
  • 第五行表示192.168.100.10,192.168.100.11,192.168.100.12三台主机

范围展开的方式还支持字母范围。下面都是有效的:

1
2
3
4
5
范围表示      展开结果
--------------------
a[1:3] --> a1,a2,a3
[08:12] --> 08,09,10,11,12
a[a:c] --> aa,ab,ac

上面示例中使用了两个主机变量ansible_password和ansible_host,它们直接定义在主机的后面,这些变量都是连接目标主机时的行为控制变量,通常它们都能见名知意。Ansible支持很多个连接时的行为控制变量,而且不同版本的Ansible的行为控制变量名称可能还不同,比如在以前版本中指定端口号的行为变量是ansible_ssh_password

下面解释几个常见的行为变量。

inventory变量名 变量解释
ansible_host ansible连接节点时的IP地址
ansible_port 连接对方的端口号,ssh连接时默认为22
ansible_user 连接对方主机时使用的主机名。不指定时,将使用执行ansible或ansible-playbook命令的用户
ansible_password 连接时的用户密码
ansible_connection 连接类型,有效值包括smart、ssh、paramiko、local、docker、winrm,默认为smart。smart表示智能选择ssh和paramiko,当SSH支持ControlPersist(即持久连接)时使用ssh,否则使用paramiko。local和docker是非基于ssh连接的方式,winrm是连接windows的插件
ansible_ssh_private_key_file 指定密钥认证ssh连接时的私钥文件
ansible_ssh_common_args 提供给ssh、sftp、scp命令的额外参数
ansible_become 允许进行权限提升
ansible_become_method 指定提升权限的方式,例如可使用sudo/su/runas等方式
ansible_become_user 提升为哪个用户的权限,默认提升为root
ansible_become_password 提升为指定用户权限时的密码

想要了解更多的参数可以查阅官方文档连接行为控制变量

主机组

ansible支持通过定义主机组来管理远程节点,每个组内可以定义多个主机,每个主机都可以定义在任何一个或多个主机组内。

示例如下

1
2
3
4
5
6
7
[mygroup1]
192.168.100.10
192.168.100.11
192.168.100.12

[mygroup2]
192.168.100.1[0:2]

Ansible默认预定义了两个主机组:

  • all分组,包含所有分组内的节点
  • ungrouped分组,包含所有不在分组内的节点

这两个分组都不包含localhost这个特殊的节点。

定义了inventory之后,可以使用ansible --listansible--playbook --list命令来查看主机组的信息,还可以使用更为专业的ansible-inventory命令来查看主机组信息。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
[root@slions_pc1 ~]# ansible mygroup1  --list
hosts (3):
192.168.100.10
192.168.100.11
192.168.100.12
[root@slions_pc1 ~]# ansible-inventory mygroup2 --graph
@mygroup2:
|--192.168.100.10
|--192.168.100.11
|--192.168.100.12
[root@slions_pc1 ~]# ansible-inventory --graph
@all:
|--@mygroup1:
| |--192.168.100.10
| |--192.168.100.11
| |--192.168.100.12
|--@mygroup2:
| |--192.168.100.10
| |--192.168.100.11
| |--192.168.100.12
|--@ungrouped:
| |--my_pc1
| |--slions_pc1
# 使用ansible-inventory以json格式列出所有主机的信息
[root@slions_pc1 ~]# ansible-inventory --list
{
"_meta": {
"hostvars": {
"192.168.100.10": {
"ansible_port": 22
},
"192.168.100.11": {
"ansible_port": 22
},
"192.168.100.12": {
"ansible_port": 22
},
"my_pc1": {
"ansible_host": "192.168.100.10"
},
"slions_pc1": {
"ansible_password": 123,
"ansible_user": "root"
}
}
},
"all": {
"children": [
"mygroup1",
"mygroup2",
"ungrouped"
]
},
"mygroup1": {
"hosts": [
"192.168.100.10",
"192.168.100.11",
"192.168.100.12"
]
},
"mygroup2": {
"hosts": [
"192.168.100.10",
"192.168.100.11",
"192.168.100.12"
]
},
"ungrouped": {
"hosts": [
"my_pc1",
"slions_pc1"
]
}
}

主机组中的主机也可以使用之前提到的连接行为控制变量。

组嵌套

ansible还支持主机组嵌套,可以通过[GROUP:children]的方式定义一个主机组,并在其中包含子组。

示例如下:

1
2
3
4
5
6
7
8
9
10
11
[mygroup1]
192.168.100.10
192.168.100.11
192.168.100.12

[mygroup2]
192.168.100.1[0:2]

[mygroup:children]
mygroup1
mygroup2

当然还可以递归嵌套。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
[mygroup1]
192.168.100.10
192.168.100.11
192.168.100.12

[mygroup2]
192.168.100.1[0:2]

[mygroup3]
192.168.100.13

[mygroup:children]
mygroup1
mygroup2

[recursive:children]
mygroup
mygroup3

主机普通变量

在定义inventory时,除了可以指定连接的行为控制变量,也可以指定Ansible的普通变量,以便在ansible执行任务时使用。

示例:

1
slions_pc1 ansible_password=123 ansible_user=root myvar="hello slions_pc1"

执行命令使用debug模块来查看变量。

1
2
3
4
[root@slions_pc1 ~]# ansible slions_pc1 -m debug -a 'var=myvar'
slions_pc1 | SUCCESS => {
"myvar": "hello slions_pc1"
}

主机组变量

顾名思义,肯定也有主机组变量。

示例:

1
2
3
4
5
6
7
[mygroup1]
192.168.100.10
192.168.100.11
192.168.100.12

[mygroup1:vars]
mygroupvar="hi"

上面[mygroup1:vars]表示为mygroup1组内所有主机定义变量mygroupvar=”hi”。而[all:vars][ungrouped:vars]分别表示为all和ungrouped这两个特殊的主机组内的所有主机定义变量。

多个inventory文件

ansible支持定义多个inventory文件并放在一个目录下。

例如,创建一个名为/etc/ansible/inventorys的目录,在其中定义a和b两个inventory文件:

1
2
3
/etc/ansible/inventorys/
├── a
└── b

现在要使用多个inventory的功能,需要将inventory指定为目录路径。

可以通过修改Ansible配置文件,将inventory指令设置为对应的目录:

1
inventory      = /etc/ansible/inventorys

或者,执行ansible或ansible-playbook命令使用-i /etc/ansible/inventorys选项指定的路径。

执行下面的命令将列出所有主机:

1
ansible-inventory -i /etc/ansible/inventorys --graph all

inventory指定为目录时,inventory文件最好不要带有后缀,就像示例中的a和b文件。因为Ansible当使用目录作为inventory时,默认将忽略一些后缀的文件不去解析。需要修改配置文件中的inventory_ignore_extensions项来禁止忽略指定后缀(如ini后缀)的文件。

1
2
#inventory_ignore_extensions = ~, .orig, .bak, .ini, .cfg, .retry, .pyc, .pyo
inventory_ignore_extensions = ~, .orig, .bak, .cfg, .retry, .pyc, .pyo

inventory变量文件

之前看到的都是在inventory文件直接定义主机变量或主机组变量。主机变量除了可以直接定义在inventory文件中,还可以定义在和inventory文件同目录的host_vars和group_vars目录中,其中host_vars目录中定义主机变量,group_vars目录中定义主机组变量。

如下示例,我在本地新建一个ansible_poc的目录作为后续ansible的工作目录,在ansible.cfg中指明读取当前目录中的inventory清单,在该目录下创建host_vars和group_vars目录,并在其中创建一些主机/主机组的变量文件或变量目录:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
[root@slions_pc1 ansible_poc]# tree
.
├── ansible.cfg
├── group_vars
│   ├── all.yaml # all主机组变量文件
│   └── mygroup1 # mygroup1主机组变量文件,其内的所有文件都会被读取
│   └── mygroup1.yml
├── host_vars
│   └── 192.168.100.10.yml # 192.168.100.10节点的变量文件
│   └── 192.168.100.11.yml # 192.168.100.11节点的变量文件
│   └── 192.168.100.12.yml # 192.168.100.12节点的变量文件
├── inventory
│   └── hosts

定义在group_vars/目录中的变量文件可以是普通文件(比如all.yml),也可以是变量目录(比如mygroup1目录)。

需要注意的是如果是目录,则目录名必须和主机组名相同,目录中的所有文件都会在解析inventory的时候被读取。如果是普通文件,则文件名可带可不带后缀,不带后缀时,文件名和主机组名相同,带后缀时,前缀和主机组名相同,后缀只允许.yml .yaml .json

host_vars/目录只能为每个节点都单独定义属于它们的变量文件。

CATALOG
  1. 1. 配置inventory
    1. 1.1. 主机
    2. 1.2. 主机组
    3. 1.3. 组嵌套
    4. 1.4. 主机普通变量
    5. 1.5. 主机组变量
    6. 1.6. 多个inventory文件
    7. 1.7. inventory变量文件