当你想确保minion按照你想要的方式配置和运行时,对minion执行state或highstate是一个完美的办法。 但有时你可能会需要同时配置一组minions。例如,如果要在Web服务器集群前设置负载均衡器,可以确保首先设置好负载均衡器服务,然后在整个集群工作节点中应用一致的状态配置。
服务编排便是实现此目的的一种方法。
New in version 0.17.0.
注意 Orchestrate弃用OverState
Orchestrate Runner(最初称为state.sls runner)除了提供了OverState的所有功能外,但还具有以下优点:
- 可以使用states中所有的Requisites and Other Global State Arguments。
- states/functions 也同样适用于salt-ssh minions。
Orchestrate Runner取代了Salt 2015.8.0中的OverState系统。
Orchestrate runner将Salt状态系统概括为Salt master上下文。 而state.sls
,state.highstate
等函数在每个Salt minion上同时独立执行,state.orchestrate
runner在master上执行,这给它提供了一个master-level视图并可以控制必要的条件,例如状态排序和执行条件。 这允许一组minions可以建立起条件依赖关系,例如一个需要在不同的minions上执行状态配置的应用,这些状态配置并不能绝对地同时发生,但可以在其中一个minion的状态配置任务失败时,停止所有minions的状态配置任务。
state.sls
,state.highstate
等函数允许有状态地管理每个minion,而state.orchestrate
runner允许你有状态地管理整个基础结构。
Orchestrate SLS文件存放在与State SLS文件相同的位置。 这意味着file_roots
和gitfs_remotes
都会影响reactor和orchestrator可用的SLS文件。
建议将reactor和orchestrator SLS文件保存在各自唯一命名的子目录中,例如像_orch/
, orch/
, _orchestrate/
, react/
, _reactor/
等。这样可以避免重复命名,有助于防止混淆。
Orchestrate Runner命令格式与state.sls
函数的格式相同,只是因为它是一个runner程序,所以它使用salt-run
而不是salt
执行。 假设你有一个名为/srv/salt/orch/webserver.sls
的state.sls文件,则在master服务器上运行以下命令将应用该文件中定义的状态。
salt-run state.orchestrate orch.webserver
注意:state.orch 是 state.orchestrate 的一个别名
Changed in version 2014.1.1: runner函数被重命名为state.orchestrate
,以避免与state.sls
执行函数混淆。 在版本0.17.0到2014.1.0中,则必须使用state.sls。
New in version 2016.11.0.
为了支持对masterless minions的Salt编排,Orchestrate Runner可用作执行模块。 Masterless 服务编排的语法没有变化,但它使用salt-call
命令,而minion配置文件中必须包含file_mode: local
的选项。 或者,在命令行上使用salt-call --local
。
salt-call --local state.orchestrate orch.webserver
注意:Masterless业务编排流程仅支持sls文件中的
salt.state
命令; 它(当前)不支持salt.function
命令。
使用 salt.function 执行一个函数。
# /srv/salt/orch/cleanfoo.sls
cmd.run:
salt.function:
- tgt: '*'
- arg:
- rm -rf /tmp/foo
salt-run state.orchestrate orch.cleanfoo
如果省略“name”参数,则状态的ID将是默认名称,或者在salt.function
的情况下,运行执行模块函数。 可以通过指定“name”参数以避免ID冲突(当需要执行多次相同的模块函数时会发生):
copy_some_file:
salt.function:
- name: file.copy
- tgt: '*'
- arg:
- /path/to/file
- /tmp/copy_of_file
- kwarg:
remove_existing: true
在业务流程中运行远程执行功能时,这些功能的某些返回值可能表示有失败的情况发生,而函数本身并未设置返回代码。 对于这些情况,使用“fail function”功能提供了一种允许更灵活的评估成功或失败的方法。
一个失败函数可以作为自定义执行模块的一部分编写。 该函数需要接受一个参数,并返回一个布尔结果。 例如:
def check_func_result(retval):
if some_condition:
return True
else:
return False
可以在orchestration SLS 文件中像下面这样调用"失败函数":
do_stuff:
salt.function:
- name: modname.funcname
- tgt: '*'
- fail_function: mymod.check_func_result
重要:失败函数在master服务器上运行,因此必须使用
salt-run saltutil.sync_modules
同步它们。
使用 salt.state 执行一个state状态。
# /srv/salt/orch/webserver.sls
install_nginx:
salt.state:
- tgt: 'web*'
- sls:
- nginx
salt-run state.orchestrate orch.webserver
需要运行一个 highstate时, 在你的state配置中设置 highstate: True
:
# /srv/salt/orch/web_setup.sls
webserver_setup:
salt.state:
- tgt: 'web*'
- highstate: True
salt-run state.orchestrate orch.web_setup
要执行另一个runner,请使用salt.runner。 例如,要在业务流程状态编排中使用cloud.profile
runner来替换已配置的配置文件中的值,请使用以下命令:
# /srv/salt/orch/deploy.sls
create_instance:
salt.runner:
- name: cloud.profile
- prof: cloud-centos
- provider: cloud
- instances:
- server1
- opts:
minion:
master: master1
要获得更动态的状态,请将jinja变量与inline pillar data
一起使用。 使用相同的例子,但传递pillar数据,状态将是这样的。
# /srv/salt/orch/deploy.sls
{% set servers = salt['pillar.get']('servers', 'test') %}
{% set master = salt['pillar.get']('master', 'salt') %}
create_instance:
salt.runner:
- name: cloud.profile
- prof: cloud-centos
- provider: cloud
- instances:
- {{ servers }}
- opts:
minion:
master: {{ master }}
执行带pillar数据的命令:
salt-run state.orch orch.deploy pillar='{"servers": "newsystem1","master": "mymaster"}'
New in version 2018.3.0.
State状态(salt.state
)作业能够通过状态返回字典报告失败。 远程执行(salt.function
)作业能够通过在__context__
字典中设置retcode
键来报告失败。 但是,当runner/wheel函数引发异常时,runner(salt.runner
)和wheel(salt.wheel
)作业只会报告一个False
的结果。 从2018.3.0版本开始,可以像在远程执行功能中一样在 runner 和 wheel功能函数中设置retcode。 下面是一些伪代码示例:
def myrunner():
...
do stuff
...
if some_error_condition:
__context__['retcode'] = 1
return result
这允许一个自定义的 runner/wheel
功能函数报告其失败,以便可以按管理需要准确地告知作业失败。
可以在单个文件中配置许多的states/functions,当与 Requisites and Other Global State Arguments 组合时,可以使用它们轻松配置复杂的编排任务。 此外, states/functions将按照定义它们的顺序执行,除非通过任何Requisites and Other Global State Arguments条件禁止这样做。这是自0.17.0以来SLS文件中的默认行为。
bootstrap_servers:
salt.function:
- name: cmd.run
- tgt: 10.0.0.0/24
- tgt_type: ipcidr
- arg:
- bootstrap
storage_setup:
salt.state:
- tgt: 'role:storage'
- tgt_type: grain
- sls: ceph
- require:
- salt: webserver_setup
webserver_setup:
salt.state:
- tgt: 'web*'
- highstate: True
根据上述设置,业务流程将会按如下顺序执行:
- shell命令
bootstrap
将在10.0.0.0/24子网中的所有minions上执行。 - 由于
storage_setup
状态的一个必需条件要求,在ID为“web”开头的所有minions上运行Highstate命令。 - 最后,将在所有具有
'role:storage'
的grain属性的目标minions上执行ceph
SLS。
注意:请记住,salt-run始终在master节点上执行。
业务流程编排作业返回特定数据结构的输出。 根据使用的outputter输出器不同,该数据结构的表示方式也不同。 使用业务流程编排的默认输出器,你可以获得一个很好的容易阅读的输出。 假设有以下SLS编排任务:
good_state:
salt.state:
- tgt: myminion
- sls:
- succeed_with_changes
bad_state:
salt.state:
- tgt: myminion
- sls:
- fail_with_changes
mymod.myfunc:
salt.function:
- tgt: myminion
mymod.myfunc_false_result:
salt.function:
- tgt: myminion
使用默认输出器运行时它将产生如下所示的输出:
fa5944a73aa8_master:
----------
ID: good_state
Function: salt.state
Result: True
Comment: States ran successfully. Updating myminion.
Started: 21:08:02.681604
Duration: 265.565 ms
Changes:
myminion:
----------
ID: test succeed with changes
Function: test.succeed_with_changes
Result: True
Comment: Success!
Started: 21:08:02.835893
Duration: 0.375 ms
Changes:
----------
testing:
----------
new:
Something pretended to change
old:
Unchanged
Summary for myminion
------------
Succeeded: 1 (changed=1)
Failed: 0
------------
Total states run: 1
Total run time: 0.375 ms
----------
ID: bad_state
Function: salt.state
Result: False
Comment: Run failed on minions: myminion
Started: 21:08:02.947702
Duration: 177.01 ms
Changes:
myminion:
----------
ID: test fail with changes
Function: test.fail_with_changes
Result: False
Comment: Failure!
Started: 21:08:03.116634
Duration: 0.502 ms
Changes:
----------
testing:
----------
new:
Something pretended to change
old:
Unchanged
Summary for myminion
------------
Succeeded: 0 (changed=1)
Failed: 1
------------
Total states run: 1
Total run time: 0.502 ms
----------
ID: mymod.myfunc
Function: salt.function
Result: True
Comment: Function ran successfully. Function mymod.myfunc ran on myminion.
Started: 21:08:03.125011
Duration: 159.488 ms
Changes:
myminion:
True
----------
ID: mymod.myfunc_false_result
Function: salt.function
Result: False
Comment: Running function mymod.myfunc_false_result failed on minions: myminion. Function mymod.myfunc_false_result ran on myminion.
Started: 21:08:03.285148
Duration: 176.787 ms
Changes:
myminion:
False
Summary for fa5944a73aa8_master
------------
Succeeded: 2 (changed=4)
Failed: 2
------------
Total states run: 4
Total run time: 778.850 ms
使用json输出器时,可以以程序易于加载和解析的格式获取输出:
salt-run state.orchestrate test --out=json
{
"outputter": "highstate",
"data": {
"fa5944a73aa8_master": {
"salt_|-good_state_|-good_state_|-state": {
"comment": "States ran successfully. Updating myminion.",
"name": "good_state",
"start_time": "21:35:16.868345",
"result": true,
"duration": 267.299,
"__run_num__": 0,
"__jid__": "20171130213516897392",
"__sls__": "test",
"changes": {
"ret": {
"myminion": {
"test_|-test succeed with changes_|-test succeed with changes_|-succeed_with_changes": {
"comment": "Success!",
"name": "test succeed with changes",
"start_time": "21:35:17.022592",
"result": true,
"duration": 0.362,
"__run_num__": 0,
"__sls__": "succeed_with_changes",
"changes": {
"testing": {
"new": "Something pretended to change",
"old": "Unchanged"
}
},
"__id__": "test succeed with changes"
}
}
},
"out": "highstate"
},
"__id__": "good_state"
},
"salt_|-bad_state_|-bad_state_|-state": {
"comment": "Run failed on minions: test",
"name": "bad_state",
"start_time": "21:35:17.136511",
"result": false,
"duration": 197.635,
"__run_num__": 1,
"__jid__": "20171130213517202203",
"__sls__": "test",
"changes": {
"ret": {
"myminion": {
"test_|-test fail with changes_|-test fail with changes_|-fail_with_changes": {
"comment": "Failure!",
"name": "test fail with changes",
"start_time": "21:35:17.326268",
"result": false,
"duration": 0.509,
"__run_num__": 0,
"__sls__": "fail_with_changes",
"changes": {
"testing": {
"new": "Something pretended to change",
"old": "Unchanged"
}
},
"__id__": "test fail with changes"
}
}
},
"out": "highstate"
},
"__id__": "bad_state"
},
"salt_|-mymod.myfunc_|-mymod.myfunc_|-function": {
"comment": "Function ran successfully. Function mymod.myfunc ran on myminion.",
"name": "mymod.myfunc",
"start_time": "21:35:17.334373",
"result": true,
"duration": 151.716,
"__run_num__": 2,
"__jid__": "20171130213517361706",
"__sls__": "test",
"changes": {
"ret": {
"myminion": true
},
"out": "highstate"
},
"__id__": "mymod.myfunc"
},
"salt_|-mymod.myfunc_false_result-mymod.myfunc_false_result-function": {
"comment": "Running function mymod.myfunc_false_result failed on minions: myminion. Function mymod.myfunc_false_result ran on myminion.",
"name": "mymod.myfunc_false_result",
"start_time": "21:35:17.486625",
"result": false,
"duration": 174.241,
"__run_num__": 3,
"__jid__": "20171130213517536270",
"__sls__": "test",
"changes": {
"ret": {
"myminion": false
},
"out": "highstate"
},
"__id__": "mymod.myfunc_false_result"
}
}
},
"retcode": 1
}
2018.3.0版本包含了一些修复优化程序,可以更轻松、更准确地解析这些数据。
- 第一个是在自定义runner或wheel功能中设置返回码的能力,如上所述。
- 第二个是对将故障信息包含在返回数据中的更改。 在2018.3.0版本之前,
salt.state
编排工作中失败的minions将显示在返回数据的comment
字段中,以易于解析的人类可读字符串形式显示。 它们现在则是包含在changes
词典中,与成功的minions一起。 - 此外,当
salt.function
作业因fail function返回False
而失败时,已经将用于处理他们的失败的方式改为与salt.state
作业相似的方式了。
Orchestrate runner可用于在不使用minion的情况下在master上执行状态。 例如,假设salt://foo.sls
包含以下SLS:
/etc/foo.conf:
file.managed:
- source: salt://files/foo.conf
- mode: 0600
在这种情况下,运行salt-run state.orchestrate foo
将等同于运行state.sls foo
,但它只在master上执行,并且不需要在master上运行minion守护程序。
这并不是技术上的服务编排,但它在某些用例中会很有用。
使用此方法时一次只能运行一个SLS目标,而使用state.sls则允许在逗号分隔列表中传递多个SLS文件。