gy13100892256
作者gy13100892256·2021-05-20 11:41
系统管理员·电信

Saltstack入门到精通教程之mine详解

字数 6006阅读 2411评论 0赞 0

Salt中的mine用来从minion收集数据,并存放在master上,之后所有的minion都可以通过salt.modules.mine访问到这些数据。因为我们即将要进行的一个实战会用到mine,所以我们这一节详细说一说mine的用法。

mine vs grains

前面我们学习了grains,也就是master收集的关于minion的一些静态信息,例如os版本,ip信息,内存硬盘大小等等。而mine是master通过在minion上执行预先定义的salt.modules中的函数来收集信息。

grains中的数据主要是用来对minion进行筛选用的,而mine中的数据主要是为了方便在minion之间传递数据用的。

mine比grains的数据要更加实时,通过Mine Interval这个配置项去设置周期。当然两者都可以手动进行实时刷新。

mine的定义和基本使用

使用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

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函数的别名

上面的基础使用有个很明显的问题,就是因为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/home/vagrant/test_mine.txt:
  file.managed:
    - source: salt://files/test_mine.txt
    - template: jinja/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

成功同步后可以看到目标文件如下

minion2:/home/vagrant# cat test_mine.txt

minion1: 192.168.50.11

minion2: 192.168.50.12

总结

mine的主要作用就是使得minion之间的数据传递和整理变得容易,配合jinja中的循环,可以很容易就获取所有minion的个性化的数据。后面我们会用更具体更详细的例子来进行实例演示。

如果觉得我的文章对您有用,请点赞。您的支持将鼓励我继续创作!

0

添加新评论0 条评论

Ctrl+Enter 发表

作者其他文章

相关文章

相关问题

相关资料

X社区推广