Salt中的mine用来从minion收集数据,并存放在master上,之后所有的minion都可以通过salt.modules.mine
访问到这些数据。因为我们即将要进行的一个实战会用到mine,所以我们这一节详细说一说mine的用法。
我是T型人小付,一位坚持终身学习的互联网从业者。喜欢我的博客欢迎在csdn上关注我,如果有问题欢迎在底下的评论区交流,谢谢。
前面我们学习了grains,也就是master收集的关于minion的一些静态信息,例如os版本,ip信息,内存硬盘大小等等。而mine是master通过在minion上执行预先定义的salt.modules
中的函数来收集信息。
grains中的数据主要是用来对minion进行筛选用的,而mine中的数据主要是为了方便在minion之间传递数据用的。
mine比grains的数据要更加实时,通过Mine Interval
这个配置项去设置周期。当然两者都可以手动进行实时刷新。
使用mine,只需要在mine_functions
关键字下面规定需要在minion上执行的函数即可,如果函数有参数也要一起带上。可以通过pillar或者是minion的配置文件去将mine下发给minion。我们采用pillar下发的方式来举例,例如,在master的/srv/pillar/mine_test.sls
中创建pillar内容如下
mine_functions:
test.ping: []
network.ip_addrs:
interface: eth1
cidr: 192.168.0.0/16
其中相当于定义了两个mine的条目。注意这里并没有表示list的短横线,虽说经过我自己测试加上短线也是没问题,但是在salt.modules.pillar.items
中显示的有点怪,同时salt.modules.mine.valid
去检查mine定义的时候也会报错。同样的如果没有参数就用空的list来表示。
然后在/srv/pillar/top.sls
中将这个pillar分发给所有的minion
base:
'*':
- mine_test
然后进行下发
root@saltmaster:/srv/pillar# salt '*' saltutil.refresh_pillar
之后就可以看到所有的minion带上了这两个pillar
root@saltmaster:/srv/pillar# salt '*' pillar.items
minion1:
----------
mine_functions:
----------
network.ip_addrs:
----------
cidr:
192.168.0.0/16
interface:
eth1
test.ping:
minion2:
----------
mine_functions:
----------
network.ip_addrs:
----------
cidr:
192.168.0.0/16
interface:
eth1
test.ping:
检查一下定义也没问题
root@saltmaster:/srv/pillar# salt '*' mine.valid
minion2:
----------
network.ip_addrs:
----------
network.ip_addrs:
----------
cidr:
192.168.0.0/16
interface:
eth1
test.ping:
minion1:
----------
network.ip_addrs:
----------
network.ip_addrs:
----------
cidr:
192.168.0.0/16
interface:
eth1
test.ping:
因为默认情况下是每小时刷新一次mine,我们可以在minion的配置文件中通过下述方法去修改,单位是分钟
mine_interval: 10
或者直接跑下面的命令去刷新
salt '*' mine.update
然后就可以指定某个minion去获取mine的值了,例如下面这个命令是让minion1
去获取minion2传递上来的network.ip_addrs
值
root@saltmaster:/srv/pillar# salt 'minion1' mine.get 'minion2' network.ip_addrs
minion1:
----------
minion2:
- 192.168.50.12
mine.get和pillar.get以及grains.get用法差不多,不过因为是minion和minion之间传递数据,所以mine这里还会多一个目的minion的id
注意这里mine返回的结果是一个键值对,key为minion的id,value为mine中定义的函数的返回值。这里的函数network.ip_addrs
返回的是一个list,所以这里可以看到是有短线的。如果我获取另一个mine函数test.ping
的值
root@saltmaster:/srv/pillar# salt 'minion1' mine.get 'minion2' test.ping
minion1:
----------
minion2:
True
可以看到没有表示list的短线了。
上面的基础使用有个很明显的问题,就是因为mine采用的也是salt.modules
中的函数,这样就导致正常远程命令和mine使用相同的函数,但是返回的结果可能不同。例如上面的例子中我们对mine中的network.ip_addrs
函数做了限制,所以比正常情况下的函数返回值少
root@saltmaster:/srv/pillar# salt 'minion1' mine.get 'minion2' network.ip_addrs
minion1:
----------
minion2:
- 192.168.50.12
root@saltmaster:/srv/pillar# salt 'minion2' network.ip_addrs
minion2:
- 10.0.2.15
- 192.168.50.12
为了避免混淆和麻烦,mine允许我们给函数取一个别名,也就是alias。
我们把上面提到的/srv/pillar/mine_test.sls
改成下面这样
mine_functions:
test.ping: []
good_ip_addrs:
mine_function: network.ip_addrs
interface: eth1
cidr: 192.168.0.0/16
可以看到取了一个别名叫good_ip_addrs
,同样是下发pillar并且马上刷新mine
root@saltmaster:/srv/pillar# salt '*' saltutil.refresh_pillar
minion1:
True
minion2:
True
root@saltmaster:/srv/pillar# salt '*' mine.valid
minion2:
----------
good_ip_addrs:
----------
network.ip_addrs:
----------
cidr:
192.168.0.0/16
interface:
eth1
test.ping:
minion1:
----------
good_ip_addrs:
----------
network.ip_addrs:
----------
cidr:
192.168.0.0/16
interface:
eth1
test.ping:
root@saltmaster:/srv/pillar# salt '*' mine.update
minion2:
True
minion1:
True
之后可以看到通过原函数名和别名都可以正常获取到mine的内容
root@saltmaster:/srv/pillar# salt 'minion1' mine.get 'minion2' network.ip_addrs
minion1:
----------
minion2:
- 192.168.50.12
root@saltmaster:/srv/pillar# salt 'minion1' mine.get 'minion2' good_ip_addrs
minion1:
----------
minion2:
- 192.168.50.12
需要注意的是,基本按照官方文档去查找函数的话,每个参数都会有参数名字的,所以按照上面的这种定义mine别名的方式不会有什么问题。对于有些函数习惯是不带参数名字的,例如cmd.run
,可以利用参数名字按照下面的方式去定义
mine_functions:
say_hello:
mine_function: cmd.run
cmd: echo hello
如果省略掉cmd
这个参数名的话,就需要加表示list的短线了,如下
mine_functions:
say_hello:
- mine_function: cmd.run
- echo hello
把上面讲到的别名中的第一个good_ip_addrs
进行一个延申举例。尝试着把所有minion的good_ip_addrs
放到一个文件,然后保存在minion2的某一个文件中。
首先还是按照上面别名那里面在/srv/pillar/mine_test.sls
定义的mine去继续
mine_functions:
test.ping: []
good_ip_addrs:
mine_function: network.ip_addrs
interface: eth1
cidr: 192.168.0.0/16
并且在/srv/pillar/top.sls
中分发到所有的minion
base:
'*':
- mine_test
然后还是按照常规套路去下发pillar,并且马上更新mine到master
root@saltmaster:/srv/pillar# salt '*' saltutil.refresh_pillar
minion2:
True
minion1:
True
root@saltmaster:/srv/pillar# salt '*' mine.update
minion1:
True
minion2:
True
然后在master的salt://files/test_mine.txt
中用jinja创建文件如下
{% for server, addrs in salt['mine.get']('*', 'good_ip_addrs') | dictsort() %}
{{ server }}: {{ addrs[0] }}
{% endfor %}
这里利用了jinja中调用salt函数的方法,格式可以参考官方文档。需要注意的是因为mine返回的值是一个list,所以还要加上中括号和下标。
然后创建一个state文件/srv/salt/example.sls
如下,将master上的文件同步到minion的/home/vagrant
目录。需要注意的是template那个关键字不能省略。
/home/vagrant/test_mine.txt:
file.managed:
- source: salt://files/test_mine.txt
- template: jinja
然后对minion2应用这个state文件
root@saltmaster:/srv/pillar# salt 'minion2' state.apply example
成功同步后可以看到目标文件如下
root@minion2:/home/vagrant# cat test_mine.txt
minion1: 192.168.50.11
minion2: 192.168.50.12
mine的主要作用就是使得minion之间的数据传递和整理变得容易,配合jinja中的循环,可以很容易就获取所有minion的个性化的数据。后面我们会用更具体更详细的例子来进行实例演示。