pillar和grains




参考

    pillar:http://docs.saltstack.cn/zh_CN/latest/topics/tutorials/pillar.html

    grains:http://docs.saltstack.cn/zh_CN/latest/topics/targeting/grains.html#targeting-grains

            http://www.furion.info/414.html

    pillar和grains:http://blog.cunss.com/?p=267





pillar:

    salt一个非常重要的组件,它用于给特定的minion定义任何你需要的数据(数据是动态的),这些数据可以被Salt的其他组件(如:state)使用

    可以根据需求自定义pillar变量,如:用户和uid相关的变量,操作系统与软件包相关的变量等等;在pillar中定义变量,每个变量对应一个值,就像python中的字典一样,一个键对应一个值,我们可以通过指定自定义的pillar变量名,来获取pillar变量对应的值{{ pillar['key']['key'] }} ,pillar里面也有类似嵌套


grains:

    主要负责搜集minion端一些基本信息,如:主机名,ip,接口,操作系统等等,这些信息都是静态的     grains可以自定义,可以在minion端自定义,然后minion端搜集本地信息发送给master端;也可以在master端自定义,然后master端把自定义的grains推送到minion端,去采集minion端相关信息


区别:

    1、grains是静态、不常变化的;pillar则是动态的

    2、grains是存储在minion本地,而pillar存储在master本地

    3、minion有权限操作自己的grains值,如增加、删除,但minion只能查看自己的pillar,无权修改

那么我们就可以得到一个大致的判断,如果你想定义的属性值是经常变化的,那请采用pillar,如果是很固定、不易变的那请用grains


我通常会把pillar或grains看成是一个大的字典,字典名就是pillar或grains;在grains字典中会有许多个键值对,每个键对应一个值,如:{{ grains['os'] }} 的值就是CentOS




pillar:

    命令:

        salt '*' pillar.items              #查看pillar所有信息

        salt '*' pillar.item users         #查看pillar某个信息


    定义pillar变量;

##创建pillar目录:
[root@dbm133 ~]# mkdir /srv/pillar/

##pillar目录树:
[root@dbm133 ~]# cd /srv/pillar/
[root@dbm133 pillar]# tree
.
├── file
│   └── init.sls
└── top.sls

##pillar入口文件:
[root@dbm133 pillar]# cat top.sls 
base:
  '*':
    - file

##pillar的.sls文件
[root@dbm133 pillar]# cd file/
[root@dbm133 file]# ll
total 4
-rw-r--r-- 1 root root 29 Jul 21 13:40 init.sls
[root@dbm133 file]# cat init.sls 
files:
    file1: /tmp/scj/file10          ##pillar变量格式就是键值对,key:value;此处是嵌套
name: jeff

##当pillar数据在master变更时,minions需要刷新本地数据,可以通过saltutil.refresh_pillar函数完成
salt '*' saltutil.refresh_pillar         ##所有minion刷新本地数据


    调用pillar变量:

##创建.sls文件:
[root@dbm133 httpd]# pwd
/srv/salt/web/httpd
[root@dbm133 httpd]# cat conf.sls 
{{ pillar['files']['file1'] }}:     ##调用pillar变量,两个花括号;可以改成{{ pillar.get('files:file1','') }}
  file:
    - managed
    - source: salt://web/files/file1
    - template: jinja               ##一定要指定template: jinja,只有这样才会去找pillar变量

##配置salt://web/files/file1文件:
[root@dbm133 files]# pwd
/srv/salt/web/files
[root@dbm133 files]# cat file1 
hello {{ pillar['name'] }}          ##调用pillar变量,两个花括号,调用pillar字典中name键所对应的值

###在.sls文件和配置文件里都可以调用pillar变量和grains变量


    推送到minion:

[root@dbm133 httpd]# salt zszz_192.168.186.132 state.highstate
zszz_192.168.186.132:
----------
          ID: /tmp/scj/file10
    Function: file.managed
      Result: True
     Comment: File /tmp/scj/file10 updated
     Started: 16:11:14.772045
    Duration: 30.101 ms
     Changes:   
              ----------
              diff:
                  New file
              mode:
                  0644

Summary
------------
Succeeded: 1 (changed=1)
Failed:    0
------------
Total states run:     1


     minion端查看是否调用成功:

[root@dbm132 scj]# ll /tmp/scj/file10
-rw-r--r-- 1 root root 11 Jul 22 16:11 /tmp/scj/file10
[root@dbm132 scj]# cat /tmp/scj/file10
hello jeff               ##文件名和文件内容都对




更复杂的调用pillar变量:

http://docs.saltstack.cn/zh_CN/latest/topics/tutorials/pillar.html

{% if pillar.get('webserver_role', '') %}       #键不存在则为空,''可改为{}
/var/www/foobarcom:
  file.recurse:
    - source: salt://webserver/src/foobarcom
    - env: {{ pillar['webserver_role'] }}
    - user: www
    - group: www
    - dir_mode: 755
    - file_mode: 644
{% endif %}


{% for user,uid in pillar.get('users',{}).items() %}      ##pillar.get('users',{})可用pillar['users']代替,前者在没有得到值的情况下,则为空;后者没有得到值则会报错
{{ user }}:
  user.present:
    - uid: {{ uid }}
{% endfor %}




grains:

   命令:

        salt '*' grains.ls            查看grains所有分类

        salt '*' grains.items         查看grains所有信息

        salt '*' grains.item os       查看grains某个分类信息


   自定义grains:

方法一:在minion端自定义(不常用)
[root@dbm132 ~]#vi /etc/salt/minion
将#default_include: minion.d/*.conf,注释去掉
[root@dbm132 ~]#cd /etc/salt/minion.d/
[root@dbm132 minion.d]# vi grains1.conf
grains:                      #必须声明是grains
    name: jeff               #键值对
    age: 25
    id:                      #多个值,每行一个
        - 100
        - 101
[root@dbm132 minion.d]# /etc/init.d/salt-minion restart
Stopping salt-minion daemon:                               [  OK  ]
Starting salt-minion daemon:                               [  OK  ]

master端查看:
[root@dbm133 ~]# salt 'zszz_192.168.186.132' grains.item name age id
zszz_192.168.186.132:
    ----------
    age:
        25
    id:
        - 100
        - 101
    name:
        jeff
方法二:在master端定义:
##在master端定义,需要用python去编写
##创建_grains目录
[root@dbm133 ~]# mkdir /srv/salt/_grains            #必须是_grains目录
[root@dbm133 ~]# cd /srv/salt/_grains
[root@dbm133 _grains]# vi mygrains.py
#!/usr/bin/python
#encoding:utf-8

def mygrain():
    grain1={}               #需要定义一个字典,因为grains就是一个大的字典
    grain1['company']='chengmeng'
    grain1['zhiwei']='yunwei'
    return grain1

##把自定义grains推送到minion端:
[root@dbm133 ~]# salt '*' saltutil.sync_all
zszz_192.168.186.135:
    ----------
    beacons:
    grains:
        - grains.mygrains                   ##mygrains 即:python脚本名
    modules:
    outputters:
    renderers:
    returners:
    states:
    utils:
zszz_192.168.186.132:
    ----------
    beacons:
    grains:
        - grains.mygrains
    modules:
    outputters:
    renderers:
    returners:
    states:
    utils:

##测试:
[root@dbm133 ~]# salt 'zszz_192.168.186.132' grains.item company zhiwei
zszz_192.168.186.132:
    ----------
    company:
        chengmeng
    zhiwei:
        yunwei


##继续深入方法二:
[root@dbm133 _grains]# ll
total 8
-rw-r--r-- 1 root root 202 Jul 22 17:30 mygrains1.py
-rw-r--r-- 1 root root 226 Jul 22 17:14 mygrains.py
[root@dbm133 _grains]# cat mygrains1.py        ##再创建一个python脚本
#!/usr/bin/python
#encoding:utf-8

def mygrains():
    grain1={}               #需要定义一个字典,因为grains就是一个大的字典
    grain1['bumen']={'zhiwei':'yunwei'}       ##字典嵌套
    return grain1

##推送到minion端:
[root@dbm133 pillar]# salt '*' saltutil.sync_all
zszz_192.168.186.132:
    ----------
    beacons:
    grains:
        - grains.mygrains1
    modules:
    outputters:
    renderers:
    returners:
    states:
    utils:
zszz_192.168.186.135:
    ----------
    beacons:
    grains:
        - grains.mygrains1
    modules:
    outputters:
    renderers:
    returners:
    states:
    utils:

##测试:
[root@dbm133 ~]# salt 'zszz_192.168.186.132' grains.item bumen
zszz_192.168.186.132:
    ----------
    bumen:
        ----------
        zhiwei:
            yunwei               ##字典嵌套
##其他例子
cat /srv/salt/_grains/fc.py
#!/usr/bin/python
import os,commands,math
def fc():
  fc = {} 
  fc['role'] = 'cpisfc_web'
  fc['disks'] = commands.getoutput('df -m| grep "/data/cache" | awk \' { print $NF } \' ')
  fc['disk_size'] = commands.getoutput('df -m| grep "/data/cache" | tail -n 1 | awk \' { print $2 } \' ')
  fc['disk_size_per'] = int(math.floor(float(fc['disk_size'])/100000))*1000
  fc['node'] = commands.getoutput('hostname | cut -c1-8')
  return fc

  
###注意:grains获取的是minion端的相关信息
[root@dbm133 _grains]# vi mygrains.py 
#!/usr/bin/python
#encoding:utf-8
import commands

def mygrains():
    grain1={}               #需要定义一个字典,因为grains就是一个大的字典
    grain1['company']='chengmeng'
    grain1['zhiwei']='yunwei'
    grain1['myip']=commands.getoutput("ifconfig  | grep Bcast | awk '{print $2}' | awk -F':' '{print $2}'")            ##获取minion端的ip
    return grain1
    
[root@dbm133 ~]# salt '*' saltutil.sync_all
[root@dbm133 ~]# salt 'zszz_192.168.186.132' grains.item myip
zszz_192.168.186.132:
    ----------
    myip:
        192.168.186.132             ##获取的的确是132的ip


    调用grains变量:

        在state模块.sls文件,pillar的.sls文件和配置文件里都可以调用grains变量

1、配置文件里调用grains变量:
##定义.sls文件
[root@dbm133 httpd]# pwd
/srv/salt/web/httpd
[root@dbm133 httpd]# cat conf.sls 
{{ pillar['files']['file1'] }}:
  file:
    - managed
    - source: salt://web/files/file1
    - template: jinja               ##一定要指定template: jinja
    
##定义salt://web/files/file1配置文件:
[root@dbm133 files]# pwd
/srv/salt/web/files
[root@dbm133 files]# cat file1 
hello {{ pillar['name'] }}
worker_processes {{ grains['num_cpus'] }}           ##调用grains变量,两个花括号;获取minion的cpu个数

##同步数据:
[root@dbm133 ~]# salt 'zszz_192.168.186.132' state.sls web.httpd.conf
zszz_192.168.186.132:
----------
          ID: /tmp/scj/file10
    Function: file.managed
      Result: True
     Comment: File /tmp/scj/file10 updated
     Started: 09:17:42.690891
    Duration: 320.077 ms
     Changes:   
              ----------
              diff:
                  ---  
                  +++  
                  @@ -1,1 +1,2 @@
                   hello jeff
                  +worker_processes 1

Summary
------------
Succeeded: 1 (changed=1)
Failed:    0
------------
Total states run:     1

##minion端
[root@dbm132 scj]# ll /tmp/scj/file10
-rw-r--r-- 1 root root 30 Jul 23 09:17 /tmp/scj/file10
[root@dbm132 scj]# cat /tmp/scj/file10 
hello jeff
worker_processes 1                    ##调用成功
2、pillar的.sls文件里调用grains变量:
##定义pillar的.sls文件:
[root@dbm133 file]# cat /srv/pillar/file/init.sls 
files:
    file1: /tmp/scj/file10
name: jeff

xingming:
    {% if grains['os'] == 'CentOS' %}            #####调用grains变量####
        name: jeff                               ##定义pillar变量
    {% elif grains['os'] == 'RedHat' %}
        name: scj
    {% else %}
        name: other
    {% endif %}

##创建state的.sls文件:
[root@dbm133 file]# cat /srv/salt/web/httpd/conf.sls 
{{ pillar['files']['file1'] }}:
  file:
    - managed
    - source: salt://web/files/file1
    - template: jinja                       ##一定要指定template: jinja
 
 ##创建salt://web/files/file1配置文件,调用pillar变量:
 [root@dbm133 files]# cat /srv/salt/web/files/file1 
hello {{ pillar['name'] }}
worker_processes {{ grains['num_cpus'] }}
welcome {{ pillar['xingming']['name'] }}            ##调用pillar变量

##同步数据到minion:
[root@dbm133 ~]# salt 'zszz_192.168.186.132' state.sls web.httpd.conf
zszz_192.168.186.132:
----------
          ID: /tmp/scj/file10
    Function: file.managed
      Result: True
     Comment: File /tmp/scj/file10 updated
     Started: 09:32:20.510124
    Duration: 197.122 ms
     Changes:   
              ----------
              diff:
                  ---  
                  +++  
                  @@ -1,2 +1,3 @@
                   hello jeff
                   worker_processes 1
                  +welcome jeff

Summary
------------
Succeeded: 1 (changed=1)
Failed:    0
------------
Total states run:     1

##minion查看:
[root@dbm132 scj]# ll /tmp/scj/file10
-rw-r--r-- 1 root root 43 Jul 23 09:32 /tmp/scj/file10
[root@dbm132 scj]# cat /tmp/scj/file10 
hello jeff
worker_processes 1
welcome jeff              ##正常
3、state的.sls文件里调用grains变量:
##创建state的.sls文件
[root@dbm133 httpd]# cat /srv/salt/web/httpd/conf.sls 
{{ pillar['files']['file1'] }}:
  file:
    - managed
    - source: salt://web/files/file1
    - template: jinja

{% set myos = grains['os'] %}             ##调用grains变量,定义一个本地myos变量;可以改成{% set myos = grains.get('os','') %}
{% if myos == 'CentOS' %}
/tmp/scj/file11:                          ##虽然if语句要求严格缩进,但是.sls文件的标识必须顶格
    file:
       - managed
       - template: jinja                  
{% endif %}

##同步数据:
[root@dbm133 ~]# salt 'zszz_192.168.186.132' state.sls web.httpd.conf
zszz_192.168.186.132:
----------
          ID: /tmp/scj/file10
    Function: file.managed
      Result: True
     Comment: File /tmp/scj/file10 is in the correct state
     Started: 09:58:24.923975
    Duration: 101.966 ms
     Changes:   
----------
          ID: /tmp/scj/file11
    Function: file.managed
      Result: True
     Comment: Empty file
     Started: 09:58:25.031602
    Duration: 1.758 ms
     Changes:   
              ----------
              new:
                  file /tmp/scj/file11 created

Summary
------------
Succeeded: 2 (changed=1)
Failed:    0
------------
Total states run:     2

##minion端
[root@dbm132 scj]# ll /tmp/scj/file11
-rw-r--r-- 1 root root 0 Jul 23 09:58 /tmp/scj/file11