配置管理系统的执行方式是配置管理领域中一个备受争议的话题。 关于该主题存在两种主要的哲学,要么以命令式的方式执行(按事物的定义顺序执行事物),要么以声明式的方式执行,其中需要在对象之间映射依赖关系。
命令式排序功能是有限的,通常被认为更容易编写。声明式排序更强大,更灵活,但通常被认为更难以创建。
创建Salt是为了兼顾以上,做到两全其美。 状态以有限顺序进行评估,这保证了状态始终以相同顺序执行,并且状态运行时是声明性的,从而使Salt通过必需依赖性的系统充分了解依赖关系。
Salt总是以有限的方式执行状态,这意味着它们将始终以相同的顺序执行,而不管执行它们的系统如何。 但是在Salt 0.17.0中,添加了state_auto_order
选项。 此选项使状态按照在sls文件(包括top.sls文件)中定义的顺序进行评估。
评估顺序使您很容易知道状态将以什么顺序执行,但是必须注意,必需性依赖的系统将覆盖文件中定义的顺序,并且下面描述的在sls文件中定义的order选项也将覆盖状态的顺序。
如果首选经典排序(按字典顺序),则在master配置文件中将state_auto_order
设置为False
。 state_auto_order
默认值为True
。
注意:必需的行为在Salt的0.9.7版本中已更改。 本文档适用于0.9.7及更高版本中的requisites必备条件。
通常,在设置状态时,任何一项操作都将需要或取决于另一项操作。 Salt允许使用必需性依赖的声明的陈述建立状态之间的关系。 Requisite语句确保在执行指定状态之前先行对其依赖的状态进行评估。 Salt中包含三种类型的必要性依赖语句,require,watch和prereq。
这些必需性依赖的语句适用于特定的状态声明:
httpd:
pkg.installed: []
file.managed:
- name: /etc/httpd/conf/httpd.conf
- source: salt://httpd/httpd.conf
- require:
- pkg: httpd
在此示例中,require 必要条件用于声明仅在pkg状态成功执行时才设置文件/etc/httpd/conf/httpd.conf
。
Requisites系统通过找到所需状态并在需要使用的状态之前执行它们来工作。 然后可以评估所需的状态,以查看它们是否已正确执行。
Require语句可以引用Salt中定义的任何状态。 基本示例是pkg、service和file,但可以引用任何已使用状态。
除了状态声明(例如pkg、file等)之外,还可以识别sls类型的要求,并且本质上允许状态的“链接”。 这提供了一种机制来确保复杂状态公式的正确顺序,尤其是在离散状态被拆分或分组为单独的sls文件时:
include:
- network
httpd:
pkg.installed: []
service.running:
- require:
- pkg: httpd
- sls: network
在此示例中,除非同时安装了httpd软件包和满足network网络状态,否则不会应用httpd service running状态(即,不会启动httpd服务)。
注意: Requisite 匹配
ID声明和
name
参数上要求都匹配。 因此,如果使用pkgs
或sources
参数以pkg状态安装软件包列表,则需要注意的是,由于所有软件包都以单个状态安装,因此不可能匹配列表中的单个软件包。
必要性语句可以作为列表传递,从而允许轻松添加更多必要性的依赖关系。 此外,像下面两种必要性依赖类型也可以分别声明:
httpd:
pkg.installed: []
service.running:
- enable: True
- watch:
- file: /etc/httpd/conf/httpd.conf
- require:
- pkg: httpd
- user: httpd
- group: httpd
file.managed:
- name: /etc/httpd/conf/httpd.conf
- source: salt://httpd/httpd.conf
- require:
- pkg: httpd
user.present: []
group.present: []
在此示例中,仅在成功执行 package、user、group 和 file状态的情况下才会启动httpd服务。
有关每个必要性依赖条件的详细信息,请在此处查看。
在使用order选项之前,请记住,大多数状态排序应使用Requisite声明完成,并且必要性依赖的声明将覆盖order选项,因此带有order选项的状态不应依赖于或被其他状态所依赖。
通过将一个顺序号数字添加到带有选项order的状态声明中来使用order选项:
vim:
pkg.installed:
- order: 1
通过将order选项添加到1,可以确保vim软件包与其他设置为order 1的状态声明一起安装。
所有声明了不带order选项的状态都将在所有带命令选项的状态执行后执行。
但是这种构造只能从一开始就处理排序状态。 在某些情况下,会出现需要将状态发送到行尾的情况。 为此,可以将执行顺序设置为last
:
vim:
pkg.installed:
- order: last
在Salt版本2017.7.0中引入,现在可以并行运行选定的状态。 通过在您的状态声明中添加parallel:True
选项,可以非常轻松地完成此操作:
nginx:
service.running:
- parallel: True
现在,nginx
将在与正常状态运行不同的单独进程中启动,因此不会阻塞其他状态。
并行运行的state状态仍然要恪守必要性依赖的限制条件。 如果给定状态需要依赖于并行运行的另一个状态,则状态运行时仍将等待所需状态完成。
考虑以下示例:
sleep 10:
cmd.run:
- parallel: True
nginx:
service.running:
- parallel: True
- require:
- cmd: sleep 10
sleep 5:
cmd.run:
- parallel: True
sleep 10
将首先启动,然后状态系统将在启动nginx时阻塞,直到sleep 10
完成。 一旦确保nginx正在运行,则sleep 5
将开始。
这意味着仍然遵循对Salt状态和必要条件的评估顺序,并且在上述情况下,parallel:True
并不能真正加快速度。
为了更快地运行上述状态,请确保在nginx状态之前执行sleep 5
。
sleep 10:
cmd.run:
- parallel: True
sleep 5:
cmd.run:
- parallel: True
nginx:
service.running:
- parallel: True
- require:
- cmd: sleep 10
现在,两个sleep调用将并行启动,nginx仍将等待所需的状态,但是在等待时,sleep 5
状态也将完成。
并行状态不会阻止您在系统上创建存在并行冲突的状态。 这意味着,如果您使用Salt启动多个软件包安装,则软件包管理器将发生阻止或失败。 如果尝试并行管理具有多个状态的同一文件,则结果可能会产生意外的文件。
确保选择并行运行的状态不会产生冲突,否则,就像在任何并行编程环境中一样,结果可能不是您期望的。 如果只是简单地使所有状态并行运行,几乎肯定会导致意外的行为。
话虽这么说,并行运行状态在大多数时间应该是安全的,并且意外行为最可能的罪魁祸首是并行运行多个软件包安装。