ansible 二、inventory文件配置与变量

大番茄 2020年02月08日 5,086次浏览

官方文档: https://docs.ansible.com/ansible/latest/user_guide/intro_inventory.html

inventory(库存)就是指主机列表或主机组,默认是在/etc/ansible/hosts文件中配置,可以通过修改ansible配置文件ansible.cfg或是命令行的-i参数修改文件位置。
文件内容可以定义为两种格式,init与yml。 一般都是使用ini的方式。
下面是根据官网的说明,但也没有按部就班。
没有写yml格式,如果有兴趣请看上面的官方文档。

一、基础格式

1、主机与组

mail.example.com

[webservers]
foo.example.com
bar.example.com

[dbservers]
one.example.com
two.example.com
three.example.com

其中中括号[]里的,表示组名,下面的表示组成员。
主机也可以不包含在组里,如最上面有一个主机并没有在组里。

未分组的主机定义需要写在所有组的上面,因为写在下面就成对应组的成员了。

例子:

[root@lvs ~]# cat /etc/ansible/hosts

172.100.102.92
172.100.102.93

[k8s_master]
172.100.101.190
172.100.101.192

[k8s_node]
172.100.101.193
172.100.101.194

3、默认组

有两个默认的组: all 和 ungrouped, all 包含所有主机, ungrouped只包含没有分组的主机。

例子:

[root@lvs ~]# ansible all --list-hosts
  hosts (6):
    172.100.102.92
    172.100.102.93
    172.100.101.190
    172.100.101.192
    172.100.101.193
    172.100.101.194

[root@lvs ansible]# ansible ungrouped --list-hosts
  hosts (2):
    172.100.102.92
    172.100.102.93

4、主机也可以包含在多个组里

[k8s_master]
172.100.101.190
172.100.101.192

[k8s_node]
172.100.101.190
172.100.101.192
172.100.101.193
172.100.101.194
[root@lvs ansible]# ansible k8s_master --list-hosts
  hosts (2):
    172.100.101.190
    172.100.101.192

[root@lvs ansible]# ansible k8s_node --list-hosts
  hosts (4):
    172.100.101.190
    172.100.101.192
    172.100.101.193
    172.100.101.194

5、嵌套组

children是关键字,固定的。

A、添加嵌套的组已经存在

直接在来一个 组名:children 就成

[k8s_master]
172.100.101.190
172.100.101.192

[k8s_node]
172.100.101.193
172.100.101.194

[k8s_node:children]
k8s_master
[root@lvs ansible]# ansible k8s_master --list-hosts
  hosts (2):
    172.100.101.190
    172.100.101.192
[root@lvs ansible]# ansible k8s_node --list-hosts
  hosts (4):
    172.100.101.193
    172.100.101.194
    172.100.101.190
    172.100.101.192

B、添加嵌套的组不存在

[k8s_master]
172.100.101.190
172.100.101.192

[k8s_node]
172.100.101.193
172.100.101.194

[k8s_all:children]
k8s_master
k8s_node
[root@lvs ansible]# ansible k8s_master --list-hosts
  hosts (2):
    172.100.101.190
    172.100.101.192
[root@lvs ansible]# ansible k8s_node --list-hosts
  hosts (2):
    172.100.101.193
    172.100.101.194
[root@lvs ansible]# ansible k8s_all --list-hosts
  hosts (4):
    172.100.101.190
    172.100.101.192
    172.100.101.193
    172.100.101.194

6、添加范围的主机

主机命名有规律,可以直接添加一个范围

www[01:50].example.com

[databases]
db-[a:f].example.com

例子:

[k8s_node]
172.100.101.19[3:4]
#172.100.101.194
[root@lvs ansible]# ansible k8s_node --list-hosts
  hosts (2):
    172.100.101.193
    172.100.101.194

7、非标准ssh端口

非标准的ssh端口(22),可以直接在主机后面加上端口号,如:

172.100.101.193:2020

或者是添加连接变量,后面介绍。

8、主机别名

ansible在连接目标主机的时候,首先会提取连接信息,主机,端口,协议等等。并且还会存放到ansible的连接变量里, 也可以通过单独定义变量,让ansible以不同的方式连接。
可以先看完变量部分再看这个。

如:先来查看几个连接变量。

[root@lvs ansible]# ansible k8s_node -a 'echo "{{ansible_host}}"'
172.100.101.193 | CHANGED | rc=0 >>
172.100.101.193

172.100.101.194 | CHANGED | rc=0 >>
172.100.101.194

[root@lvs ansible]# ansible k8s_node -a 'echo "{{ansible_connection}}"'
172.100.101.194 | CHANGED | rc=0 >>
ssh

172.100.101.193 | CHANGED | rc=0 >>
ssh

那么别名就好办了。随便起个名字,修改主机地址的变量。

[k8s_node]
node1 ansible_host=172.100.101.194

[root@lvs ansible]# ansible k8s_node --list-hosts
  hosts (1):
    node1

[root@lvs ansible]# ansible k8s_node -a 'echo "{{ansible_host}}"'
node1 | CHANGED | rc=0 >>
172.100.101.194

二、变量

可以给主机和组添加变量,可以直接在主机清单文件里添加,也可以在单独的变量文件里添加。
变量一般主要用于playbook中。

1、在inventory文件里定义变量

A、定义主机变量

直接在主机后面添加即可:

[atlanta]
host1 http_port=80 maxRequestsPerChild=808
host2 http_port=303 maxRequestsPerChild=909

例子:

[k8s_master]
172.100.101.190 http_port=443
172.100.101.192 http_port=80

可以使用{{变量}}的方式解析出来。

[root@lvs ansible]# ansible k8s_master -a 'echo "{{http_port}}"'
172.100.101.192 | CHANGED | rc=0 >>
80

172.100.101.190 | CHANGED | rc=0 >>
443

上面这个在给目标机器执行之前就变成, echo 80, echo 443了。

加些字符再试试。目标及机器执行的分别是 , echo "80 hello", echo "443 hello"。


[root@lvs ansible]# ansible k8s_master -a 'echo "{{http_port}} hello"'
172.100.101.192 | CHANGED | rc=0 >>
80 hello

172.100.101.190 | CHANGED | rc=0 >>
443 hello

[root@lvs ansible]#

B、定义组变量

使用关键字: vars

[atlanta]
host1
host2

[atlanta:vars]
ntp_server=ntp.atlanta.example.com
proxy=proxy.atlanta.example.com

如:下面把k8s_master的其中一台机器的变量去掉了。添加了组变量。

[k8s_master]
172.100.101.190
172.100.101.192 http_port=80

[k8s_node]
172.100.101.19[3:4]
#172.100.101.194

[k8s_master:vars]
http_port=443

可以看到下面的190主机的变量就是继承的组变量,但是192变量不变。 这是优先级的问题,范围越小优先级越高。主机变量与组变量重复,以主机变量为准。

[root@lvs ansible]# ansible k8s_master -a 'echo "{{http_port}}"'
172.100.101.192 | CHANGED | rc=0 >>
80

172.100.101.190 | CHANGED | rc=0 >>
443

再来个, k8s_master组添加变量server_name, 但是父组k8s_all也有相同变量。

[k8s_master]
172.100.101.190 
172.100.101.192  http_port=80

[k8s_node]
172.100.101.19[3:4] 

[k8s_master:vars]
http_port=443
server_name=www.atest.pub

[k8s_all:children]
k8s_master
k8s_node

[k8s_all:vars]
http_port=4343
server_name=www.yxingxing.net

k8s_all的优先级没有子组k8s_master的优先级高。

[root@lvs ansible]# ansible k8s_master -a 'echo "{{server_name}}"'
172.100.101.192 | CHANGED | rc=0 >>
www.atest.pub

172.100.101.190 | CHANGED | rc=0 >>
www.atest.pub

[root@lvs ansible]# ansible k8s_node -a 'echo "{{server_name}}"'
172.100.101.194 | CHANGED | rc=0 >>
www.yxingxing.net

172.100.101.193 | CHANGED | rc=0 >>
www.yxingxing.net

子组的变量将具有较高的优先级(覆盖)父组的变量。

C、如果同一主机在不同组,并且变量也不同。

相同主机的相同变量全局只有一个变量值,不会再不同组拥有不同变量。 后边的覆盖前面的。
如:

172.100.101.190 http_port=4343

[k8s_node]
172.100.101.190 http_port=443

[k8s_master]
172.100.101.190 http_port=80
[root@lvs ansible]# ansible k8s_master -a 'echo "{{http_port}}"'
172.100.101.190 | CHANGED | rc=0 >>
80

[root@lvs ansible]# ansible k8s_node -a 'echo "{{http_port}}"'
172.100.101.190 | CHANGED | rc=0 >>
80

[root@lvs ansible]# ansible all -a 'echo "{{http_port}}"'
172.100.101.190 | CHANGED | rc=0 >>
80

[root@lvs ansible]# ansible ungrouped -a 'echo "{{http_port}}"'
[WARNING]: No hosts matched, nothing to do

可以看到都是80端口,后面的ungrouped报错是因为这个主机有所属组。

2、在变量文件中定义变量

文件需要使用yaml语法,文件扩展名可以使用: yaml, yml, json或没有扩展名。

Ansible通过搜索相对于inventory文件或playbook文件的路径来加载主机和组变量文件。

如果相对于inventory,大家都可以使用。如果只是相对与playbook文件的,就只有运行playbook的时候可以使用了,毕竟playbook文件的位置不是固定的。

在inventory文件或playbook文件所在目录的group_vars目录下创建以组名命名的文件,就是组变量文件。

在inventory文件或playbook文件所在目录的host_vars目录下创建以主机清单名称命名的文件,就是主机变量文件。
比如: 组变量

[root@lvs ~]# ls /etc/ansible/group_vars/
k8s_master  k8s_node
[root@lvs ~]# cat /etc/ansible/group_vars/k8s_master
http_port: 80
server_name: www.atest.pub

主机变量:

[root@lvs ~]# ls /etc/ansible/host_vars
172.100.101.190  172.100.101.193  node1

[root@lvs ~]# cat /etc/ansible/host_vars/172.100.101.190
http_port: 8080
[root@lvs ~]# cat /etc/ansible/host_vars/node1
http_port: 8088

还可以以组名或主机名为目录的方式,暂时不多说了,有需要还是查看官方网站。

https://docs.ansible.com/ansible/latest/user_guide/intro_inventory.html#organizing-host-and-group-variables


3、变量合并与覆盖

默认情况下,在执行操作之前,变量会合并附加到主机。
而合并过程中遇到重复的,就会被覆盖。

不同级别的覆盖优先级

覆盖过程中的优先级,依次是:
all(最低优先级)--父组--子组--host(最高优先级)

  • all
  • 父组
  • 子组
  • host

all 可以直接在inventory文件里定义变量[all:vars]。

同级别的组

同级别的(注意是组,不是主机),按字母顺序合并,后边的覆盖前面的。比如:

[k8s_master]
172.100.101.190

[k8s_node]
172.100.101.190

[k8s_node:vars]
server_name=www.yxingxing.net

[k8s_master:vars]
server_name=www.atest.pub

上面的k8s_node与k8s_master都是172.100.101.190的组,级别相同。按字母顺序 k8s_node中的n在k8s_master中的m之后。
所以:

[root@lvs ansible]# ansible all -a 'echo "{{server_name}}"'
172.100.101.190 | CHANGED | rc=0 >>
www.yxingxing.net

同级别按字母顺序覆盖只是默认方式,可以使用组变量ansible_group_priority 定义覆盖的顺序。数字越大,所在的组合并顺序越靠后,合并时间也就越晚,也就覆盖了前面已经合并的。

所有组其实都有这个变量,在没有设置的情况下,默认值为1。如果改成2,就表示向后移了一位。
如:

[k8s_node:vars]
server_name=www.yxingxing.net

[k8s_master:vars]
ansible_group_priority=2
server_name=www.atest.pub
[root@lvs ansible]# ansible all -a 'echo "{{server_name}}"'
172.100.101.190 | CHANGED | rc=0 >>
www.atest.pub

那么,如果设置成1呢, 就成了之前的结果了。


命令行变量

命令行指定的变量优先级最高,就算命令行指定的是组, 也比inventory文件里的主机变量优先级高。

172.100.102.90 http_port=888

[root@lvs ansible]# ansible ungrouped -a 'echo {{http_port}}' -e http_port=777
172.100.102.90 | CHANGED | rc=0 >>
777


至于在Inventory中的主机变量与host_vars目录的主机变量冲突的话,我测试的是host_vars覆盖inventory里的,可能是host_vars是后加载。 真要有这种情况还需详细测试。


三、连接变量

连接变量就是设置这些变量可以控制连接远程主机的方式。
比如,没有设置秘钥登录,使用用户名与密码登录,还不想交互式输入密码。添加俩变量就成。

172.100.102.92 ansible_user=root ansible_password=abcdefg
172.100.102.93 ansible_user=root ansible_password=abcdefg

[k8s_master]
172.100.101.190 ansible_user=root ansible_password=abcdefg

或者是直接加到组变量里。

[all:vars]
ansible_user=root
ansible_password=abcdefg

[ungrouped:vars]
ansible_user=root
ansible_password=123456

[k8s_master]
ansible_user=root
ansible_password=abcdefg123123

ansible_connection

连接类型,如ssh。 ansible连接插件的名称。

所有常规的连接

ansible_host

连接的远程主机

ansible_port

连接远程主机的端口

ansible_user

连接到远程主机时使用的用户名
有的版本可能是 ansible_ssh_user。 我这个版本都可以使用。

ansible_password

有的版本可能是 ansible_ssh_pass。 我这个版本都可以使用。

特定于SSH的连接

ansible_ssh_private_key_file

ssh使用的私钥文件。

ansible_python_interpreter

目标主机的python路径。

.........

提权

ansible_become

等同于ansible_sudoansible_su

ansible_become_method

提权方法,如 sudo, su

ansible_become_user

提权的用户,如: root

ansible_become_password

提权需要输入的密码

。。。。。。。。。

https://docs.ansible.com/ansible/latest/user_guide/intro_inventory.html#connecting-to-hosts-behavioral-inventory-parameters