Pillar是什么?

Pillar是Salt非常重要的一个组件,它用于给特定的minion定义任何你需要的数据,这些数据可以被Salt的其他组件使用。Salt在 0.9.8版本中引入了Pillar。Pillar在解析完成后,是一个嵌套的dict结构;最上层的key是minion ID,其value是该minion所拥有的Pillar数据;每一个value也都是key/value。

这里可以看出Pillar的一个特点,Pillar数据是与特定minion关联的,也就是说每一个minion都只能看到自己的数据,所以Pillar 可以用来传递敏感数据(在Salt的设计中,Pillar使用独立的加密session,也是为了保证敏感数据的安全性)。

Pillar可以用在哪些地方?

  • 敏感数据

例如ssh key,加密证书等,由于Pillar使用独立的加密session,可以确保这些敏感数据不被其他minion看到。

  • 变量

可以在Pillar中处理平台差异性,比如针对不同的操作系统设置软件包的名字,然后在State中引用。

  • 其他的任何数据

可以在Pillar中添加任何需要用到的数据。比如定义用户和UID的对应关系,mnion的角色等。

  • 用在Targetting中

Pillar可以用来选择minion,使用-I选项

怎样定义Pillar数据?

master配置文件中定义

默认情况下,master配置文件中的所有数据都添加到Pillar中,且对所有minion可用。如果要禁用这一默认值,可以在master配置文件中添加如下数据,重启服务后生效:

pillar_opts: False

使用SLS文件定义Pillar

Pillar使用与State相似的SLS文件。Pillar文件放在master配置文件中pillar_roots定义的目录下。示例如下:

pillar_roots:
  base:
    - /srv/pillar

这段代码定义了base环境下的Pillar文件保存在/srv/pillar/目录下。与State相似,Pillar也有top file,也使用相同的匹配方式将数据应用到minion上。示例如下:
/srv/pillar/top.sls:

base:
  '*':
    - data    
    - packages

/srv/pillar/packages.sls:

{% if grains['os'] == 'RedHat' %}
apache: httpd
git: git
{% elif grains['os'] == 'Debian' %}
apache: apache2
git: git-core
{% endif %}

/srv/pillar/data/init.sls:

role: DB_master

这段代码表示,base环境中所有的minion都具有packages和data中定义的数据。Pillar采用与file server相同的文件映射方式,在本例中,packages映射到文件/srv/pillar/packages.sls,data映射到/srv/pillar/data/init.sls。注意key与value要用冒号加空格分隔,没有空格的话将解析失败。


Pillar还可以使用其他的匹配方式来选择minion,下面的例子中,servers只应用到操作系统是Debain的机器:

dev:
  'os:Debian':
    - match: grain    - servers

如何知道minion拥有哪些Pillar数据?

使用执行模块pillar。pillar模块有两个funtion:pillar.data和pillar.raw。示例如下:

# salt '*' pillar.data
kaibin.test3:
    ----------
    master:
        ----------
        __role:
            master
        auth_mode:
            1
        auto_accept:
            False
        cachedir:
            /var/cache/salt/master
        cli_summary:
            False
        client_acl:
            ----------
        client_acl_blacklist:
            ----------
        cluster_masters:
        cluster_mode:
            paranoid
        color:
            True
        conf_file:
            /etc/salt/master
        config_dir:
            /etc/salt
        cython_enable:
            False
        daemon:
            True
        default_include:
            master.d/*.conf
        enable_gpu_grains:
            False
        enforce_mine_cache:
            False
        enumerate_proxy_minions:
            False
        environment:
            None
        ext_job_cache:
            
        ext_pillar:
        extension_modules:
            /var/cache/salt/extmods
        external_auth:
            ----------
        failhard:
            False
        file_buffer_size:
            1048576
        file_client:
            local
        file_ignore_glob:
            None
        file_ignore_regex:
            None
        file_recv:
            False
        file_recv_max_size:
            100
        file_roots:
            ----------
            base:
                - /srv/myself/
        fileserver_backend:
            - roots
        fileserver_followsymlinks:
            True
        fileserver_ignoresymlinks:
            False
        fileserver_limit_traversal:
            False
        gather_job_timeout:
            5
        gitfs_base:
            master
        gitfs_env_blacklist:
        gitfs_env_whitelist:
        gitfs_insecure_auth:
            False
        gitfs_mountpoint:
            
        gitfs_passphrase:
            
        gitfs_password:
            
        gitfs_privkey:
            
        gitfs_pubkey:
            
        gitfs_remotes:
        gitfs_root:
            
        gitfs_user:
            
        hash_type:
            md5
        hgfs_base:
            default
        hgfs_branch_method:
            branches
        hgfs_env_blacklist:
        hgfs_env_whitelist:
        hgfs_mountpoint:
            
        hgfs_remotes:
        hgfs_root:
            
        id:
            kaibin.test3
        interface:
            192.168.65.129
        ioflo_console_logdir:
            
        ioflo_period:
            0.01
        ioflo_realtime:
            True
        ioflo_verbose:
            0
        ipv6:
            False
        jinja_lstrip_blocks:
            False
        jinja_trim_blocks:
            False
        job_cache:
            True
        keep_jobs:
            24
        key_logfile:
            /var/log/salt/key
        keysize:
            4096
        log_datefmt:
            %H:%M:%S
        log_datefmt_logfile:
            %Y-%m-%d %H:%M:%S
        log_file:
            /var/log/salt/master
        log_fmt_console:
            [%(levelname)-8s] %(message)s
        log_fmt_logfile:
            %(asctime)s,%(msecs)03.0f [%(name)-17s][%(levelname)-8s] %(message)s
        log_granular_levels:
            ----------
        log_level:
            warning
        loop_interval:
            60
        maintenance_floscript:
            /usr/lib/python2.6/site-packages/salt/daemons/flo/maint.flo
        master_floscript:
            /usr/lib/python2.6/site-packages/salt/daemons/flo/master.flo
        master_job_cache:
            local_cache
        master_pubkey_signature:
            master_pubkey_signature
        master_roots:
            ----------
            base:
                - /srv/salt-master
        master_sign_key_name:
            master_sign
        master_sign_pubkey:
            False
        master_tops:
            ----------
        master_use_pubkey_signature:
            False
        max_event_size:
            1048576
        max_minions:
            0
        max_open_files:
            100000
        minion_data_cache:
            True
        minionfs_blacklist:
        minionfs_env:
            base
        minionfs_mountpoint:
            
        minionfs_whitelist:
        nodegroups:
            ----------
        open_mode:
            False
        order_masters:
            False
        outputter_dirs:
        peer:
            ----------
        permissive_pki_access:
            False
        pidfile:
            /var/run/salt-master.pid
        pillar_opts:
            True
        pillar_roots:
            ----------
            base:
                - /srv/pillar
        pillar_source_merging_strategy:
            smart
        pillar_version:
            2
        ping_on_rotate:
            False
        pki_dir:
            /etc/salt/pki/master
        preserve_minion_cache:
            False
        pub_hwm:
            1000
        publish_port:
            4505
        publish_session:
            86400
        queue_dirs:
        raet_main:
            True
        raet_mutable:
            False
        raet_port:
            4506
        range_server:
            range:80
        reactor:
        reactor_refresh_interval:
            60
        renderer:
            yaml_jinja
        rep_hwm:
            50000
        ret_port:
            4506
        root_dir:
            /
        rotate_aes_key:
            True
        runner_dirs:
        saltversion:
            2014.7.0
        search:
            
        search_index_interval:
            3600
        serial:
            msgpack
        show_jid:
            False
        show_timeout:
            False
        sign_pub_messages:
            False
        sock_dir:
            /var/run/salt/master
        sqlite_queue_dir:
            /var/cache/salt/master/queues
        ssh_passwd:
            
        ssh_port:
            22
        ssh_sudo:
            False
        ssh_timeout:
            60
        ssh_user:
            root
        state_aggregate:
            False
        state_auto_order:
            True
        state_events:
            False
        state_output:
            full
        state_top:
            salt://top.sls
        state_verbose:
            True
        svnfs_branches:
            branches
        svnfs_env_blacklist:
        svnfs_env_whitelist:
        svnfs_mountpoint:
            
        svnfs_remotes:
        svnfs_root:
            
        svnfs_tags:
            tags
        svnfs_trunk:
            trunk
        syndic_event_forward_timeout:
            0.5
        syndic_master:
            
        syndic_max_event_process_time:
            0.5
        syndic_wait:
            5
        timeout:
            5
        token_dir:
            /var/cache/salt/master/tokens
        token_expire:
            43200
        transport:
            zeromq
        user:
            root
        verify_env:
            True
        win_gitrepos:
            - https://github.com/saltstack/salt-winrepo.git
        win_repo:
            /srv/salt/win/repo
        win_repo_mastercachefile:
            /srv/salt/win/repo/winrepo.p
        worker_floscript:
            /usr/lib/python2.6/site-packages/salt/daemons/flo/worker.flo
        worker_threads:
            5
        zmq_filtering:
            False

在master上修改Pilla文件后,需要用以下命令刷新minion上的数据:

salt '*' saltutil.refresh_pillar

如果定义好的pillar不生效,建议刷新一下试试。

Pillar中数据如何使用?

Pillar解析后是dict对象,直接使用Python语法,可以用索引(pillar['pkgs']['apache'])或get方法(pillar.get('users', {}))。详见下面的例子

示例

targeting

使用-I选项表示使用Pillar来匹配minion.

salt -I 'role:DB*' test.ping

在Pillar中使用列表

Pillar的key/value结构中的value可以是string,也可以是一个list。Pillar文件定义如下:
/srv/pillar/users/init.sls:

users:
  thatch: 1000
  shouse: 1001
  utahdave: 1002
  redbeard: 1003

在top.sls中引用Pillar文件,对所有的minion应用users中的内容:
/srv/pillar/top.sls:

base:
  '*':
    - data    - users

现在所有的minion都具有了users数据,可以在state文件中使用:
/srv/salt/users/init.sls:

{% for user, uid in pillar.get('users', {}).items() %}`user`:
  user.present:
    - uid: `uid`{% endfor %}

利用Pillar处理平台差异

不同的操作系统不仅管理资源的方式不同,软件包的名字、配置文件的路径也有有可能不一样。Salt的执行模块屏蔽了系统管理资源的差异。其他的差异可以根 据grains中的的os、cpuarch等信息来处理,这些条件判断可以写在State文件中,但会使得State文件的逻辑不清晰。Pillar可以 很好地解决这个问题。下面的例子中,在不同的os上安装对应的软件包,但state file完全一样,不需要针对os作修改,灵活方便。

/srv/pillar/pkg/init.sls:

pkgs:
  {% if grains['os_family'] == 'RedHat' %}
  apache: httpd
  vim: vim-enhanced  {% elif grains['os_family'] == 'Debian' %}
  apache: apache2
  vim: vim  {% elif grains['os'] == 'Arch' %}
  apache: apache
  vim: vim  {% endif %}

/srv/pillar/top.sls:

base:
  '*':
    - data    
    - users    
    - pkg

/srv/salt/apache/init.sls:

apache:
  pkg.installed:
    - name: {{ pillar['pkgs']['apache'] }}

还可以在state file中设置默认值: srv/salt/apache/init.sls:

apache:
  pkg.installed:
    - name: {{ salt['pillar.get']('pkgs:apache', 'httpd') }}

自定义pillar数据

  1. 定义pillar目录

pillar_roots:
  base:
    - /srv/base/pillar
  test:
    - /srv/test/pillar
  prod:
    - /srv/prod/pillar

2.创建pillar top file

[root@master pillar]# pwd
/srv/base/pillar
[root@master pillar]# cat top.sls 
base:
  'kaibin.test2':
    - zabbix

3.创建自定义sls文件

[root@master pillar]# cat zabbix.sls 
Zabbix_Server: 192.168.65.128

4.刷新pillar数据

[root@master pillar]# salt '*' saltutil.refresh_pillar
master:
    True
kaibin.test2:
    True

5.检索自定义pillar数据

[root@master pillar]# salt '*' pillar.item Zabbix_Server
master:
    ----------
kaibin.test2:
    ----------
    Zabbix_Server:
        192.168.65.128

6.pillar的匹配

[root@master pillar]# salt -I 'Zabbix_Server:192.168.65.128' test.ping
kaibin.test2:
    True
[root@master pillar]# salt '*' pillar.get Zabbix_Server
master:
kaibin.test2:
    192.168.65.128