在Pillar中存储静态数据

Pillar是Salt用来分发全局变量到所有minions的一个接口。Pillar data的管理类似于Salt State Tree。

Pillar是在Salt 0.9.8版本中加入的。

注解

存储敏感数据

不像是state tree, pillar只对匹配类型的minion有效。 这使它为特定的minion存储敏感数据非常有用.

声明Master Pillar

Salt Master服务器维护了一个pillar_roots 设置 ,和在Salt 文件服务器上使用的file_roots结构对应。和Salt 文件服务器类似,master配置文件中的 pillar_roots 选项也是基于环境映射到目录。Pillar数据被映射到基于top文件匹配到的Minion上,top 文件是和state top文件一样的方式列出的。Salt pillar可以使用和标准的top 文件同样的匹配器类型。

主配置文件中的 pillar_rootsfile_roots 的功能是相同的。

pillar_roots:
  base:
    - /srv/pillar

This example configuration declares that the base environment will be located in the /srv/pillar directory. It must not be in a subdirectory of the state tree.

The top file used matches the name of the top file used for States, and has the same structure:

/srv/pillar/top.sls

base:
  '*':
    - packages

In the above top file, it is declared that in the base environment, the glob matching all minions will have the pillar data found in the packages pillar available to it. Assuming the pillar_roots value of /srv/pillar taken from above, the packages pillar would be located at /srv/pillar/packages.sls.

Any number of matchers can be added to the base environment. For example, here is an expanded version of the Pillar top file stated above:

/srv/pillar/top.sls:

base:
  '*':
    - packages
  'web*':
    - vim

In this expanded top file, minions that match web* will have access to the /srv/pillar/pacakges.sls file, as well as the /srv/pillar/vim.sls file.

Another example shows how to use other standard top matching types to deliver specific salt pillar data to minions with different properties.

Here is an example using the grains matcher to target pillars to minions by their os grain:

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

/srv/pillar/packages.sls

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

company: Foo Industries

重要

See Is Targeting using Grain Data Secure? for important security information.

The above pillar sets two key/value pairs. If a minion is running RedHat, then the apache key is set to httpd and the git key is set to the value of git. If the minion is running Debian, those values are changed to apache2 and git-core respectively. All minions that have this pillar targeting to them via a top file will have the key of company with a value of Foo Industries.

Consequently this data can be used from within modules, renderers, State SLS files, and more via the shared pillar dict:

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

Finally, the above states can utilize the values provided to them via Pillar. All pillar values targeted to a minion are available via the 'pillar' dictionary. As seen in the above example, Jinja substitution can then be utilized to access the keys and values in the Pillar dictionary.

Note that you cannot just list key/value-information in top.sls. Instead, target a minion to a pillar file and then list the keys and values in the pillar. Here is an example top file that illustrates this point:

base:
  '*':
     - common_pillar

And the actual pillar file at '/srv/pillar/common_pillar.sls':

foo: bar
boo: baz

Pillar 命名空间是平整的

分开的pillar文件共享同一个命名空间。在 top.sls 设置:

base:
  '*':
    - packages
    - services

packages.sls文件设置:

bind: bind9

而且 services.sls 文件中设置:

bind: named

Then a request for the bind pillar will only return named; the bind9 value is not available. It is better to structure your pillar files with more hierarchy. For example your package.sls file could look like:

packages:
  bind: bind9

Pillar Namespace Merges

With some care, the pillar namespace can merge content from multiple pillar files under a single key, so long as conflicts are avoided as described above.

For example, if the above example were modified as follows, the values are merged below a single key:

base:
  '*':
    - packages
    - services

And a packages.sls file like:

bind:
  package-name: bind9
  version: 9.9.5

And a services.sls file like:

bind:
  port: 53
  listen-on: any

The resulting pillar will be as follows:

$ salt-call pillar.get bind
local:
    ----------
    listen-on:
        any
    package-name:
        bind9
    port:
        53
    version:
        9.9.5

注解

Pillar files are applied in the order they are listed in the top file. Therefore conflicting keys will be overwritten in a 'last one wins' manner! For example, in the above scenario conflicting key values in services will overwrite those in packages because it's at the bottom of the list.

包含其他Pillar

0.16.0 新版功能.

Pillar SLS文件可以包含其他pillar文件,和State文件类似。两个语法可以实现这个目的。简单的方式是包含附加的pillar文件夹,就像是原文件的一部分一样。

include:
  - users

全包含形式允许两个附加选项 --传递默认值给模板引擎给包含的pillar文件,就像是包含的pillar下嵌套的一个可选项。

include:
  - users:
      defaults:
          sudo: ['bob', 'paul']
      key: users

这种形式,包含的文件(users.sls)将被嵌入编译后的pillar的 'users' 键下。而且, 'sudo' 值在user.sls中作为一个模板变量还是有效的。

查看 Minion Pillar

Once the pillar is set up the data can be viewed on the minion via the pillar module, the pillar module comes with functions, pillar.items and pillar.raw. pillar.items will return a freshly reloaded pillar and pillar.raw will return the current pillar without a refresh:

salt '*' pillar.items

注解

在0.16.2版本之前,这个函数被命名为 pillar.data。这个函数的命名依然保持着向后兼容。

Pillar "get" 函数

0.14.0 新版功能.

pillar.get 函数多数情况下工作方式和python字典中的 get 方法一样,但是带来了一项改进:嵌套的字典结构可以使用一个 : 分隔符提取。

如果在pillar中有这样的一个结构

foo:
  bar:
    baz: qux

在sls公式或文件模板中从原始pillar中提取数据是通过这种方式完成的:

{{ pillar['foo']['bar']['baz'] }}

现在,有了新的 pillar.get 函数,数据可以安全的收集和设置设置一个默认,当值不可用时允许模板回滚。

{{ salt['pillar.get']('foo:bar:baz', 'qux') }}

这使得处理嵌套结构更加容易。

注解

pillar.get() vs salt['pillar.get']()

需要注意的是,在模板中, pillar 变量只是一个字典。这就是说调用在一个模板内部调用 pillar.get() 函数将只是使用默认的字典的 .get() 函数,并不包含额外的 : 分隔符的功能。必须调用上面的语法(salt['pillar.get']('foo:bar:baz', 'qux'))得到salt的函数,而不是默认的字典的行为。

刷新Pillar数据

当pillar数据在master变更时,minions需要刷新本地数据。这可以通过 saltutil.refresh_pillar 函数完成。

salt '*' saltutil.refresh_pillar

这个函数触发minion异步刷新pillar并且总是返回 None

Set Pillar Data at the Command Line

Pillar data can be set at the command line like the following example:

salt '*' state.highstate pillar='{"cheese": "spam"}'

This will create a dict with a key of 'cheese' and a value of 'spam'. A list can be created like this:

salt '*' state.highstate pillar='["cheese", "milk", "bread"]'

注解

Be aware that when sending sensitive data via pillar on the command-line that the publication containing that data will be received by all minions and will not be restricted to the targeted minions. This may represent a security concern in some cases.

Master Config In Pillar

For convenience the data stored in the master configuration file can be made available in all minion's pillars. This makes global configuration of services and systems very easy but may not be desired if sensitive data is stored in the master configuration. This option is disabled by default.

To enable the master config from being added to the pillar set pillar_opts to True:

pillar_opts: True

Minion Config in Pillar

Minion configuration options can be set on pillars. Any option that you want to modify, should be in the first level of the pillars, in the same way you set the options in the config file. For example, to configure the MySQL root password to be used by MySQL Salt execution module, set the following pillar variable:

mysql.pass: hardtoguesspassword

Master Provided Pillar Error

By default if there is an error rendering a pillar, the detailed error is hidden and replaced with:

Rendering SLS 'my.sls' failed. Please see master log for details.

The error is protected because it's possible to contain templating data which would give that minion information it shouldn't know, like a password!

To have the master provide the detailed error that could potentially carry protected data set pillar_safe_render_error to False:

pillar_safe_render_error: False