Salt States 基本法四

这周翻译了四篇有关 salt state 的文章,基本上是每天发一篇掉一个粉,到今天已经掉了 5 个粉了,技术文章阅读量低也是意料之中的。

but,I don’t care.

鲁迅爷爷说过:

真的猛男,敢于直面永不破百的阅读量和点赞数,敢于正视不忠取关的粉丝。

今天来继续讲一讲 state 中的 top 文件。

top.sls 的由来

大多数系统都是由多组机器构成,同一组的每台机器分担的职责大致相同,比如数据库集群负责数据存储,web服务器专心于负载均衡、请求响应,还有一大堆的机器专门负责执行具体的业务逻辑。

为了有效地管理这些机器,管理员需要为它们分配不同的角色。比如,那些负责处理来自前台请求的机器的角色可能是这样:它们应该全部都安装好 Apache 服务器并且保证服务正常运行。

Salt 中,定义了不同组机器它们要配置的角色 的映射关系的文件就是 top.sls

top,顾名思义,它在所有 state 文件目录的最顶层,这些目录结构构成了一棵 state 树🌲

一个简单示例

top.sls 中有三个元素:

  • 运行环境: 运行环境是指包含了一个 top 文件和多个 state 文件的目录结构。默认为 base,可以声明多个运行环境,建议用户只在多个版本的 state 树的情况下才配置多运行环境。
  • 目标 minions:一组机器,它们要去执行 state 文件。
  • State 文件: 要应用到目标 minionsls 文件,每个 sls 文件描述了一个或多个 state

三者之间的关系如下:

  • 环境包含目标
  • 目标包含 State

有了这些概念,我们就可以描述这样一个 top 文件:所有 IDweb 开头的 minion 都要执行一个叫 apacheState

1
2
3
base:          # Apply SLS files from the directory root for the 'base' environment
'web*': # All minions with a minion_id that begins with 'web'
- apache # Apply the state file named 'apache.sls'

使用 top.sls

每种运行环境都通过 master 配置文件的 file_roots 属性来指定这种环境的根目录,前面介绍过了,可以为一个或多个,只要根目录列表里能找到 top.sls 即可。

在最常见的单运行环境中,只声明一个 base 环境,并且它对应的 state 树目录也只有一个。

/etc/salt/master

1
2
3
file_roots:
base:
- /srv/salt

接下来,/srv/salt 目录中的 top.sls 中相应地声明了 base 环境,在该环境中所有的 minion 都要应用 coreedit 这两个 state

/srv/salt/top.sls

1
2
3
4
base:
'*':
- core
- edit

如上述配置,那么 Salt 将会在 /srv/salt 目录中搜索 core.slsedit.sls

多运行环境

这部分之前有个例子讲的很清楚了,请参考 《Salt States 基本法之三》(链接:http://t.cn/Rqn0foT)

minion 匹配技巧

top 文件中,可以通过 Grainspillar、正则表达式等多重组合方式来筛选 minion。

下面是一个稍微复杂点的 top.sls,展示了几种匹配 minion 的技巧:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
# All files will be taken from the file path specified in the base
# environment in the ``file_roots`` configuration value.

base:
# All minions get the following three state files applied

'*':
- ldap-client
- networking
- salt.minion

# All minions which have an ID that begins with the phrase
# 'salt-master' will have an SLS file applied that is named
# 'master.sls' and is in the 'salt' directory, underneath
# the root specified in the ``base`` environment in the
# configuration value for ``file_roots``.

'salt-master*':
- salt.master

# Minions that have an ID matching the following regular
# expression will have the state file called 'web.sls' in the
# nagios/mon directory applied. Additionally, minions matching
# the regular expression will also have the 'server.sls' file
# in the apache/ directory applied.

# NOTE!
#
# Take note of the 'match' directive here, which tells Salt
# to treat the target string as a regex to be matched!

'^(memcache|web).(qa|prod).loc$':
- match: pcre
- nagios.mon.web
- apache.server

# Minions that have a grain set indicating that they are running
# the Ubuntu operating system will have the state file called
# 'ubuntu.sls' in the 'repos' directory applied.
#
# Again take note of the 'match' directive here which tells
# Salt to match against a grain instead of a minion ID.

'os:Ubuntu':
- match: grain
- repos.ubuntu

# Minions that are either RedHat or CentOS should have the 'epel.sls'
# state applied, from the 'repos/' directory.

'os:(RedHat|CentOS)':
- match: grain_pcre
- repos.epel

# The three minions with the IDs of 'foo', 'bar' and 'baz' should
# have 'database.sls' applied.

'foo,bar,baz':
- match: list
- database

# Any minion for which the pillar key 'somekey' is set and has a value
# of that key matching 'abc' will have the 'xyz.sls' state applied.

'somekey:abc':
- match: pillar
- xyz

# All minions which begin with the strings 'nag1' or any minion with
# a grain set called 'role' with the value of 'monitoring' will have
# the 'server.sls' state file applied from the 'nagios/' directory.

'nag1* or G@role:monitoring':
- match: compound
- nagios.server

top.sls 是如何编译的

当使用多运行环境时,没必要为每个环境都写一个 top 文件。最常见且最方便维护的方式是:将 top.sls 存放在这多种环境中的一个即可。

but,某些奇葩的工作流确实需要多个 top 文件,在这种情况下,这些多个 top.sls 将被合并,为 state 编译器生成高级数据,最后,minion 利用这些数据来编译 state

假设,某配置如下:

/etc/salt/master:

1
2
3
4
5
file_roots:
first_env:
- /srv/salt/first
second_env:
- /srv/salt/second

/srv/salt/first/top.sls:

1
2
3
4
5
6
first_env:
'*':
- first
second_env:
'*':
- second

聪明的读者可能会疑问:

如果 minion 不属于某个特定的环境(或者同时匹配到多个环境),也没有 saltenv 参数传给 state 方法,state 编译器将如何处理这种冲突?

如上,在 salt '*' state.apply 命令中,应用的 state 文件,是first.sls 还是 second.sls 呢?

当冲突发生时,在 master 配置文件里,有几个相应的选项来控制这些行为:

  • env_order

设置 state 环境的编译顺序。比如,你声明了 basedevprod 三种环境,你可以设置编译顺序为 ['base'、'dev'、'prod'],如果有冲突的 key,以 最后 的那个环境值为准。

  • top_file_merging_strategy

    • merge:这是默认选项,top 文件被合并,可以通过控制 env_order 属性来设置编译顺序。
    • same:只会编译匹配到的环境的 top 文件。
  • default_top

如果 top_file_merging_strategysame并且某个环境没有 top 文件,将用 default_top 值作为该环境的 top 文件,默认值为 base

下集预告

介绍有关 pillar 的那些事儿,吼不吼啊?

很惭愧,今晚又做了一点微小的贡献,谢谢大家!

彦祖老师 wechat