Salt States 基本法一

关于 Salt States ,《Salt Stack 一日游》(链接:http://t.cn/RqYQK0Q)从整体上介绍了 salt 系统以及各个组件,接着《如何使用盐态》(链接:http://t.cn/Rq8vJVF)把 state 相关的知识过了一遍。但,这些多半是理论居多,实践得少,就像程序员学习一门新的编程语言一样,你讲再多都不如一个 Hello World 来的亲切。

纸上得来终觉浅,得知此事须躬行。

本文的目的就是手把手教你“怎样快速地运用 Salt States 来配置系统”。当然啦,想要挖掘更多 Salt States 的内幕信息,请移步官方文档,那里有你想知道的所有奇技淫巧。

这个示例将分为四集,我打算从今天开始每晚放出一集熟肉版。

本集前情提要:

使用 Salt 配置一个 minion,使之运行 Apache 服务器,并确保该服务正常运行。

首先,请检查下你是否正确安装并配置好了 salt-mastersalt-minion 的运行环境。要是连这个你都还不会,额~你也没必要往下继续看了。

建立 Salt State 树🌲

States 纯粹是存放在 master 上的一些文本文件,minions 根据自身需要到 master 的文件服务器上拉取,这些 state 文件就构成了 State 树🌲

因此,为了让 salt 能使用 state 配置系统,必须先设置好 Salt 文件服务器。编辑 master 的配置文件(/etc/salt/master)中的 file_roots 字段,取消下面几行的注释:

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

重启 salt-maser 来使配置生效:

1
2
pkill salt-master
salt-master -d

准备 top 文件

master 中刚刚设置好的 state 文件目录(默认为:/srv/salt)中,新建一个 top.sls 文件并写入如下内容:

1
2
3
base:
'*':
- webserver

top 文件可以区分多个运行环境(这个以后会再详细论述),默认的运行环境是 base。在 base 环境下,定义了一系列的 minion,对于上面这个例子来说,它适用于所有(*) minion 主机。

新建 SLS 文件

top 文件所在目录中,新建一个 webserver.sls 文件,文件内容为:

1
2
3
apache:                 # ID declaration
pkg: # state declaration
- installed # function declaration

第 1 行,是 ID 声明,可以为任何标识符,本例中它指代将要安装的软件名(apache)。

注意:Apache 服务器在不同的操作系统中,其软件安装包名可能不一样,比如,在 Fedora 系统中叫 httpd,但是在 DebianUbuntu 中,它叫 apache2

第 2 行,是 State 声明,定义使用的是哪个 Salt States 模块,本例中,我们使用 pkg state 模块来安装某个指定的软件包。

第 3 行,是 方法声明,定义使用 pkg state 模块中的哪个方法。

安装软件包

接下来,让我们来运行这个 state。在 maser 上打开终端,运行:

1
salt '*' state.apply

master 通知所有的目标 minions 来执行 state.apply 方法。当 state.apply方法不带任何 sls 文件作为参数时,minion 将下载 mastertop 文件并尝试去匹配里面的表达式(top.sls 的第 2 行),如果匹配上,它将下载对应的 sls 文件(webserver.sls),编译(还记得yaml_jinja 吗?),运行。

一旦执行完毕,minion 会将它所执行的具体动作及结果汇报给 master

SLS命名空间

你可能注意到,本例中红 webserver 指代 webserver.sls,在 top.sls
中 sls 文件的引用规则如下:

  • .sls 后缀被舍弃(如:webserver.sls 变成 webserver

  • 允许子目录存在以便更好地管理 sls 文件。

    • 每个子目录可以用.(沿用 python import 某个模块的习惯)或者/来表示(webserver/dev.sls 可以用 webserver.dev 表示)
    • 由于/表示成.,因此 sls 文件名中除了后缀.sls,其他部分不能包含有.。比如:webserver_1.0.sls 将无法匹配,webserver_1.0 将匹配webserver_1/0.sls
  • 子目录的 init.sls 可以直接用目录名引用。因此,webserver/init.sls 可以用 webserver 指代。

  • 如果 webserver.slswebserver/init.sls 都存在,将忽略 webserver/init.sls 并用 webserver 指代 webserver.sls

排查问题

如果事情不向我们想象得那么顺利,下面这些小提示能帮助我们排查问题出在哪里。

打开日志开关

输出更多的日志信息:

1
salt-minion -l debug

前台运行 minion

直接把 minion 放到前台运行可以直接看到任何输出信息:

1
salt-minion

延长超时时间

比如,将 salt 运行的超时设为 60 秒:

1
salt -t 60

最好的方式是,将这几套合拳结合起来一起用:

1
2
salt-minion -l debug        # On the minion
salt '*' state.apply -t 60 # On the master

调用多个 States

你可以在一个 ID 声明下面指定多个 State 声明。举个栗子🌰:修改前面的 webserv.sls,如果 Apache 没有运行,则启动它。

1
2
3
4
5
apache:
pkg.installed: []
service.running:
- require:
- pkg: apache

你可以试着先停止 Apache 服务器,再运行一遍 state.apply,并观察输出结果。

依赖其他 States

真是一个赛艇蛤,现在我们已经安装了一个 Apache 服务器,让我们来更多点膜法:给我们的网站添加一个个性化的 HTML 文件。

很明显,只有网页文件却没有相应的 web 服务器是无法让网站工作起来的,因此在部署网页文件前必须检查 Apache 服务器是否已安装并运行。

webserver/init.sls 文件底部加入如下内容:

1
2
3
4
5
6
7
8
9
10
11
12
1 apache:
2 pkg.installed: []
3 service.running:
4 - require:
5 - pkg: apache
6
7 /var/www/index.html: # ID declaration
8 file: # state declaration
9 - managed # function
10 - source: salt://webserver/index.html # function arg
11 - require: # requisite declaration
12 - pkg: apache # requisite reference

第 7 行是 ID 声明,本例中它是将要安装的 HTMl 文件路径。

注:Apache 网站的默认根目录在不同系统下面可能不一样,在 Debian 系统下它是 /var/www

第 8 行是 State 模块声明,本例中使用了 Statefile 模块。

第 9 行是 State 模块的方法声明,managed 方法会从 master 下载文件并将其存放在指定的位置。

第 10 行是方法的参数声明,这里传递了 source 参数给 managed

第 11 行是 Requisite 必要语句。

第 12 行是 Requisite 引用的某个 state 及其 ID,本例中,它引用了前面的 ID 声明(apache),它告诉 salt 只有 Apache 已安装才能部署网站文件。

下一步,新建如下内容的 index.html 文件并保存于 webserver 目录(/srv/salt/webserer)中.

1
2
3
4
5
6
7
<!DOCTYPE html>
<html>
<head><title>Salt rocks</title></head>
<body>
<h1>This file brought to you by Salt</h1>
</body>
</html>

最后,终于到了最后,再执行一遍 state.apply 命令,minion 会从 master 的文件服务器上下载该 index.html 文件并把它存放在 Apache 网站的根目录中。

1
salt '*' state.apply

验证下这个 index.html 是否真的已经在 minion 的网站中。

下集预告

本集主要给大家演示了如何快速地让 salt state 工作起来,下集将讨论有关 include, extend 以及 sls 模版等高级配置语法。

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

hxzqlh wechat