Salt提供了一个接口来管理Salt minions的配置或“状态”。 此接口是一个完备的功能机制的实现,用于根据中心管理系统的定义强制管控本地的系统状态。

您也可以参考在Github上维护的这一份技术资料:State System Reference

State Management 状态管理

状态管理,通常也称为软件配置管理(SCM),是一种将系统保持在预定状态的管理方法。 它安装软件包、启动或重新启动服务,或将配置文件放置到位并监视它们的更改。

有了状态管理系统,就可以轻松可靠地配置和管理几台服务器或几千台服务器。 它允许将配置保存在版本控制管理下。

Salt State是我们在先前的远程执行教程中讨论的Salt模块的扩展。 不再是基于一次性执行的方式来管理系统,可以轻松定义系统状态,然后强制执行。

Understanding the Salt State System Components - 理解Salt State状态系统组件

Salt状态系统由许多组件组成。 作为用户,需要了解SLS和渲染器系统。 但是作为开发人员,还需要了解Salt状态以及如何编写状态。

注意:状态仅在针对的目标minions上编译和执行。 要直接在masters上执行功能,请参见runners

Salt SLS System

Salt状态系统主要使用的是SLS系统。 SLS代表SaLt State。

Salt状态是包含有关如何配置Salt minions的信息的文件。 状态放置在目录树中,并且可以用许多不同的格式编写。

文件的内容及其布局方式应尽可能简单,同时要具有最大的灵活性。 这些文件按状态排列,并包含有关如何配置minions的信息。

SLS File Layout

SLS文件放置在Salt文件服务器中。

一个简单的布局如下所示:

top.sls
ssh.sls
sshd_config
users/init.sls
users/admin.sls
salt/master.sls
web/init.sls

top.sls文件是关键组件。 top.sls文件用于确定应将哪些SLS文件应用于哪个minions。

上面示例中带有.sls扩展名的其余文件是状态文件。

Salt master将不带.sls扩展名的文件视为可以下载到Salt Minion的文件。

状态会被转换为点表示法。 例如,ssh.sls文件被视为ssh状态,users/admin.sls文件被视为users.admin状态。

名为init.sls的文件将转换为父目录的状态名称,因此web/init.sls文件将转换为Web状态。

在Salt中,所有内容都是文件; 没有文件和文件类型的“魔术翻译”。 这意味着状态文件可以像纯文本文件或二进制文件一样分发到minions。

SLS Files

Salt状态文件是简单的数据集。 由于SLS文件只是数据,因此可以用许多不同的方式表示它们。

默认格式是从Jinja模板生成的YAML。 这允许状态文件具有Python的所有语言结构以及YAML的简单性。

状态文件可以是复杂的Jinja模板,可以转换为YAML,也可以只是简单的YAML文件。

状态文件只是简单的通用数据结构,例如字典和列表,是使用模板语言(例如YAML)构造的。

这是Salt状态的示例:

vim:
  pkg.installed: []

salt:
  pkg.latest:
    - name: salt
  service.running:
    - names:
      - salt-master
      - salt-minion
    - require:
      - pkg: salt
    - watch:
      - file: /etc/salt/minion

/etc/salt/minion:
  file.managed:
    - source: salt://salt/minion
    - user: root
    - group: root
    - mode: 644
    - require:
      - pkg: salt

这个简短的段落将确保已安装vim、Salt已安装且是最新的、salt-master和salt-minion守护程序正在运行并且Salt minion配置文件已就绪。 它还将确保按正确的顺序部署所有内容,并确保在监视文件更新时重新启动Salt服务。

The Top File

Top file 文件用来控制minions和应用于它们的状态之间的映射关系。

Top file 文件指定哪个minions应用哪个SLS文件,以及应从哪个环境提取这些SLS文件。

Top file 文件通过在顶层指定环境的关键字来工作。

每个环境都包含目标表达式以匹配minions。 最后,每个目标表达式都包含一个Salt状态列表,以应用于匹配的minions:

base:
  '*':
    - salt
    - users
    - users.admin
  'saltmaster.*':
    - match: pcre
    - salt.master

上面的示例使用默认Salt设置中内置的base环境。

base环境具有目标表达式。 第一个是匹配所有minions,它下方的SLS文件适用于所有minions。

第二个表达式是一个正则表达式,它将匹配所有带有ID匹配saltmaster.*的minions,并指定对于那些minions,应用salt.master状态。

重要:从2014.7.0版开始,默认匹配器(当未如上例中的第二个表达式中明确定义时)为复合匹配器。 由于此匹配器解析表达式中的单个单词,因此使用此匹配器将无法正确匹配包含空格的minion ID。 因此,如果您的目标表达式旨在匹配包含空格的minion ID,则必须指定其他匹配类型(例如glob)。 例如:

base:
  'test minion':
    - match: glob
    - foo
    - bar
    - baz

一个完整的匹配类型说明表格,请参见这里

Reloading Modules - 重新加载模块

一些Salt状态要求安装特定的软件包才能加载模块。 例如,pip状态模块需要pip包才能进行正确的名称和版本解析。

在大多数常见情况下,Salt足够聪明,可以透明地重新加载模块。 例如,如果您安装软件包,Salt会重新加载模块,因为某些其他模块或状态可能只需要已安装的软件包。

在某些情况下,可能需要告知Salt重新加载模块。 考虑以下状态文件,我们将其称为pep8.sls

python-pip:
  cmd.run:
    - name: |
        easy_install --script-dir=/usr/bin -U pip
    - cwd: /

pep8:
  pip.installed:
    - require:
      - cmd: python-pip

上面的示例使用setuptools中的easy_install安装pip,并使用pip安装pep8,如前所述,这要求在整个系统范围内安装pip。 让我们执行以下状态:

salt-call state.apply pep8

上面命令的输出会类似下面:

----------
    State: - pip
    Name:      pep8
    Function:  installed
        Result:    False
        Comment:   State pip.installed found in sls pep8 is unavailable

        Changes:

Summary
------------
Succeeded: 1
Failed:    1
------------
Total:     2

如果此时再执行一遍命令,则输出会变成下面这样:

----------
    State: - pip
    Name:      pep8
    Function:  installed
        Result:    True
        Comment:   Package was successfully installed
        Changes:   pep8==1.4.6: Installed

Summary
------------
Succeeded: 2
Failed:    0
------------
Total:     2

由于我们使用cmd安装了pip,因此Salt无法知道已安装了系统范围的软件包。

在第二次执行时,由于已安装了所需的pip包,因此状态可以正确执行。

注意:Salt不会在每个状态运行时都重新加载模块,因为这样做会大大减慢状态执行速度。

那么我们如何解决这种极端情况呢? reload_modules

reload_modules是在所有可用状态下salt都可以识别的布尔选项,一旦给定的状态完成设置,它就将强制salt重新加载其模块。

修改后的状态文件现在为:

python-pip:
  cmd.run:
    - name: |
        easy_install --script-dir=/usr/bin -U pip
    - cwd: /
    - reload_modules: true

pep8:
  pip.installed:
    - require:
      - cmd: python-pip

现在,让我们执行一次状态配置命令:

salt-call state.apply pep8

输出像下面这样:

----------
    State: - pip
    Name:      pep8
    Function:  installed
        Result:    True
        Comment:   Package was successfully installed
        Changes:   pep8==1.4.6: Installed

Summary
------------
Succeeded: 2
Failed:    0
------------
Total:     2