what is saltstack系列三:SaltStack事件驱动的基础设施
SaltStack是基础设施管理的革命性方法,能够以速度取代复杂性。 SaltStack足够简单,可以在几分钟内运行,可扩展到足以管理数以万计的服务器,并且速度足以在几秒钟内与每个系统进行通信。
这些入门教程向您介绍了使SaltStack启动并运行的基础知识。
What is SaltStack系列三:SaltStack事件驱动的基础设施
- 基于事件驱动的基础设施
- 观察Salt事件
- 添加事件以及自定义Salt事件
- Salt Beacon 信标
- Salt Event Reactor 事件反应器
1、基于事件驱动的基础设施
Salt围绕事件基础设施构建,可以利用并扩展该基础设施,以推动基础架构中所有设备的响应式配置和管理。
本入门指南向您介绍Salt事件系统,并向您展示如何:
- 监控并启用Salt事件
- 启用对非Salt活动的监视
- 基于事件触发的响应
你都可以使用Salt事件做什么?这里有一些我们的用户的使用例子:
- 当有用户登录到生产服务器时发送一个文本消息;
- 构建失败时通知Slack或HipChat频道等IM交互工具;
- 当发现未经授权的更改时立即恢复配置文件;
- 自动缩放云资源;
- 监视磁盘,处理器,RAM和其他系统状态并采取超出定义的阈值的操作;
2、观察Salt事件
Salt的内部组件通过发送和监听事件来相互沟通。 在Salt中,事件会发送给您能想象到的所有事物:
- Salt minions连接
- **被接受或拒绝
- job发送
- 从一个minion返回了一个job result
-
执行心跳健康检查(默认关闭)
即使是Salt命令行界面也在使用事件系统。在将命令发送给Salt Master后,Salt CLI仅监视事件总线以获得来自目标minions返回的作业结果。
2.1 观察Salt事件的方法
Salt提供了一个runner,可以在Salt Master收到它们时实时显示出事件信息。
salt-run state.event pretty=True
以下是一些类似于您可以在Salt Master上看到的事件:
salt/job/20150923203228234305/new {
"_stamp": "2015-09-23T20:32:28.235712",
"arg": [],
"fun": "test.ping",
"jid": "20150923203228234305",
"minions": [
"minion2"
],
"tgt": "*",
"tgt_type": "glob",
"user": "sudo_vagrant"
}
salt/job/20150923203228234305/ret/minion2 {
"_stamp": "2015-09-23T20:32:28.291789",
"cmd": "_return",
"fun": "test.ping",
"fun_args": [],
"id": "minion2",
"jid": "20150923203228234305",
"retcode": 0,
"return": true,
"success": true
}
salt/auth {
"_stamp": "2015-09-23T20:30:02.998305",
"act": "pend",
"id": "minion1",
"pub": "-----BEGIN PUBLIC KEY-----\...\n-----END PUBLIC KEY-----\n",
"result": true
}
2.2 事件信息的格式
事件由两个主要部分组成:识别被触发事件的标记以及包含有关事件详细信息的数据。
2.3 事件信息的标识
所有的salt事件都以salt/为前缀,并根据事件类型添加其他级别。 例如,作业事件的前缀为salt/job/。 每个事件部分使用/分隔以提供简单的命名空间。 这是标识符,被称为事件标签,并且通常包含特定的详细信息,如job ID或minion ID。
除了事件标签外,每个事件还包含特定的事件数据。
2.4 事件数据
每个事件都包含一个时间戳以及对该特定事件唯一的其他键和值。
稍后当我们探索Ractor时,您将学习如何使用事件标签和数据来定制响应。
3、附加事件以及自定义Salt事件
除了内置事件之外,您还可以在Salt系统中启用一些其他事件,并生成自定义的事件。
3.1 On presence在场事件
启用on presence事件后,会导致Salt Master周期性地查找主动连接的minions。 在事件总线上以固定时间间隔显示出minions的on presence状态信息事件,以及带有新连接或断开的minions列表信息的事件。
这需要在Salt Master的配置文件中启动以下参数,默认值为False:
presence_events: True
3.2 SALT STATE执行进度事件
启用Salt状态执行进度事件会导致Salt Minions发送State状态的进度事件,Salt状态运行中执行的每个函数在执行完成后都会触发此类事件。
进度事件信息的格式是: salt/job/<JID>/prog/<MID>/<RUN NUM>.
该功能默认未启用,需要在Salt Master中修改以下参数来打开这个进度事件信息的功能:
state_events: True
3.3 在State状态完成时触发一个事件
如果您有一个包含多个Salt状态的配置作业,则可以通过添加fire_event参数在每个Salt状态完成时触发一个事件:
nano installed:
pkg.installed:
- name: nano
- fire_event: True
或者,如果您愿意,也可以用一个自定义的事件字符串替换掉True,该字符串将被附加到触发的事件上:
nano installed:
pkg.installed:
- name: nano
- fire_event: nano/installed
3.4 发送一个自定义事件
您还可以使用自定义的事件标记和事件数据直接从命令行触发事件。
尝试从你的一个Salt Minion运行以下命令:
salt-call event.send /my/test/event '{"data": "my event test"}'
这会导致生成一个类似于以下情况的事件:
/my/test/event {
"_stamp": "2016-02-05T18:24:47.001310",
"cmd": "_minion_event",
"data": {
"__pub_fun": "event.send",
"__pub_jid": "20160205182446924651",
"__pub_pid": 1933,
"__pub_tgt": "salt-call",
"data": "my event test"
},
"id": "minion1",
"tag": "/my/test/event"
}
4、Salt 信标
到目前为止,我们已经学会了如何监控Salt相关事件的事件总线,以及如何启用一些附加事件。 在这一点上,你可能会想:"既然我已经建立了一个动态的通信基础设施,可以实时监控Salt事件并做出反应,也许我还可以使用该系统监视其他事物, 如系统登录、磁盘使用情况和我的数据库服务。"
信标可让您监视与Salt无关的事件,并为之生成一个通知事件。 信标系统允许minion进入各种系统进程并持续监控这些进程。当监视的活动在系统进程中发生时,就会在Salt事件总线上发送事件。
Salt beacons目前可以监视和发送Salt事件以用于许多系统活动,包括:
- 文件系统更改
- 系统负载
- 服务状态
- shell活动,例如用户登录
- 网络和磁盘使用情况
4.1 启用信标
Salt信标不需要对正在监视的系统进程进行任何更改,所有内容都使用Salt进行配置。
通常通过在minion配置文件中放置顶层信标配置段落来启用信标功能:
beacons:
inotify:
home/user/importantfile:
mask:
- modify
4.2 信标监测间隔
默认情况下,信标会以1秒为间隔进行监视。 如果要设置不同的时间间隔,请为信标提供interval时间间隔参数。
以下信标是分别以5秒和10秒的间隔运行:
beacons:
inotify:
/etc/httpd/conf.d: {}
/opt: {}
interval: 5
load:
- 1m:
- 0.0
- 2.0
- 5m:
- 0.0
- 1.5
- 15m:
- 0.1
- 1.0
- interval: 10
在配置了信标后,它会像其他Salt进程一样触发事件。
4.3 添加一个信标
我们将添加一个监视文件更改的信标。 为此,我们将使用inotify beacon和python-pyinotify软件包。 由于这个软件包不在我们的Salt版本中,我们首先使用Salt来安装它。
安装PYINOTIFY并启动事件运行器
打开我们在前面章节中安装的模拟测试环境,通过一个命令行提示符窗口进入salt-vagrant-demo 目录,然后执行以下命令登录到Salt Master中:
vagrant ssh master
在minion1上安装 python-pyinotify软件包:
sudo salt 'minion1' pkg.install python-pyinotify
你应该会看到类似下面的信息输出:
[email protected]:~$ sudo salt 'minion1' pkg.install python-pyinotify
minion1:
----------
python-pyinotify:
----------
new:
0.9.4-1build1
old:
python2.7-pyinotify:
----------
new:
1
old:
因为我们稍后要生成一个事件,所以在这里继续保持登录到Salt Master中的状态,并启动Salt 事件运行器,以便于观察后续生成的事件信息:
salt-run state.event pretty=True
保持这个终端窗口,暂时不要退出或关闭它。
4.4 设置一个信标
再打开一个命令行提示符窗口,进入salt-vagrant-demo 目录,然后执行以下命令ssh登录到Salt minion1中:
vagrant ssh minion1
在minion1上,编辑/etc/salt/minion文件并在底部添加以下内容:
beacons:
inotify:
/home/vagrant/importantfile:
mask:
- modify
保存这个变更,并重启salt minion服务:
sudo service salt-minion restart
信标现在被保存并启用。 接下来,我们可以创建我们要监视更改的文件。 在/home/vagrant/目录中,创建importantfile文件:
touch importantfile
echo "some content" > importantfile
回到你的Salt Master上,你应该已经收到一个类似于以下的事件:
salt/beacon/minion1/inotify//home/vagrant/importantfile {
"_stamp": "2016-02-03T22:32:09.592113",
"data": {
"change": "IN_MODIFY",
"id": "minion1",
"path": "/home/vagrant/importantfile"
},
"tag": "salt/beacon/minion1/inotify//home/vagrant/importantfile"
}
请记住,必须在修改文件之前就启动事件运行器,否则您将看不到该事件的信息。
5、Salt Event Reactor 事件反应器
Salt的Reactor系统让您能够触发任何事件的响应行为。 您不仅可以在作业和任务完成时触发操作,还可以在服务关闭、用户登录、文件更改以及可以发送自定义事件的任何位置触发操作(构建脚本结束、cron作业等等)。
5.1 反应器的配置
通过向/etc/salt/master或/etc/salt/master.d/reactor.conf中添加top-level反应器部分(只允许有一个反应器配置段落)来配置反应器。
以下是与minion开始事件、云资源销毁事件和自定义事件字符串匹配的reactor配置示例:
reactor: # Salt master config section "reactor"
- 'salt/minion/*/start': # Match tag "salt/minion/*/start"
- /srv/reactor/start.sls # Things to do when a minion starts
- /srv/reactor/monitor.sls # Other things to do
- 'salt/cloud/*/destroyed': # Globs can be used to match tags
- /srv/reactor/destroy/*.sls # Globs can be used to match file names
- 'myco/custom/event/tag': # React to custom event tags
- salt://reactor/mycustom.sls # Put reactor files under file_roots
反应器配置特别的简单。 反应器部分的唯一工作就是将事件标记与反应器SLS文件关联起来运行。 因为这个反应器是单线程的,所以应该在反应器SLS文件中去处理那些繁重的工作(反应器SLS文件是从单独的进程中分离出来运行的,并且可以根据需要尽可能长时间的运行)。
反应器SLS文件支持YAML和Jinja的全部功能,因此您可以使用事件标签和事件数据执行过滤和测试。
让我们在演示环境中添加一个反应器,以便我们可以看到系统是如何运行的。
打开salt-vagrant-demo/saltstack/etc/master文件并添加一个reactor部分:
这告诉Salt master,只要它看到包含my/custom/event/标签的事件,就调用customevent.sls文件。
在我们了解反应器SLS文件后,我们将在下一节创建customevent.sls文件。现在,重新启动salt-master服务以使配置生效,然后继续。
5.2 反应器的SLS文件
您已经熟悉Salt State SLS文件,Salt反应器SLS文件与之有许多相似之处。 Salt状态和Salt反应器SLS文件都是使用YAML和Jinja编写的,但由于它们有一些语法差异并用于不同的目的,所以它们应该保存在Salt文件服务器的不同位置(例如,反应器可以存放在/srv/salt/reactors目录)。
由于Salt反应器SLS文件是在Salt Master上执行的,因此请将它们更多地视为salt和salt-run命令的入口点,而不是作为在Salt minion上执行的Salt状态系统的入口点。
5.3 反应器的类型
Salt反应器可以触发下列系统之一:
- 远程执行:在目标minions运行execution模块。 这是通过调用salt命令(包括应用state或highstate)可以做的任何事情。
- Salt Runners:这些是你开始使用salt-run的任务。 例如,HTTP runner可以触发webhook。
- Wheel:Wheel命令管理您的Salt环境,执行诸如接受**和更新配置设置等任务。 其中一些功能是由salt-key基础工具提供的。
5.4 远程执行命令
该接口直接调用的Salt执行模块。
如果从使用salt命令的命令行工具触发远程执行命令的方式考虑这一点,您会知道salt远程执行命令需要三件事情:
- 目标 target
- 功能 function
-
参数 args
在Salt反应器中远程执行命令同样也需要使用YAML格式的相同信息,但格式规范是像下面这样:
<section id>:
local.<function>:
- tgt: <target>
- arg:
<arguments>
请注意,您要调用的执行模块函数是由local开头。
让我们看看您可能从命令行执行的简单软件包安装:
salt 'myminion' pkg.install cowsay
在一个reactor SLS中,达到同样功能所需的配置类似下面这样:
install cowsay on myminion:
local.pkg.install:
- tgt: 'myminion'
- arg:
- cowsay
掌握这一点了吗? 请记住,由于反应器SLS文件在Master服务器上运行并调用salt执行模块,因此需要指定minions目标以运行execution模块。 这个参数被称为tgt,意思是“目标”。 另外,要传递给模块的参数也使用arg或kwarg(而不是kwargs)参数传递。
如果你希望使用其它的匹配minions的方法,可以这样做:
clean_tmp:
local.cmd.run:
- tgt: 'os:Ubuntu'
- expr_form: grain
- arg:
- rm -rf /tmp/*
通过expr_form参数,指明使用grain来作为tgt的匹配规则。
5.5 RUNNER 和 WHEEL 模块
从Reactor调用Runner模块和Wheel模块使用了更直接的语法,因为该函数就是在本地执行,而不是需要将命令发送到远程系统。 也没有arg或kwarg参数(除非Runner函数或Wheel函数接受带有这两个名称的参数)。
clear_the_grains_cache_for_all_minions:
runner.cache.clear_grains
spin_up_more_web_machines:
runner.cloud.profile:
- prof: centos_6
- instances:
- web11 # These VM names would be generated via Jinja in a
- web12 # real-world example.
这里有一个wheel的例子,它自动接受一个minion的**(在生产中你会想要增加额外的完整性检查,所以你不会接受不确认的minions)。
accept_new_minion:
wheel.key.accept:
- match: {{ data['id'] }}
5.6 更多的例子
以下反应器SLS可能用于对salt/cloud/*/created事件作出反应:
new vm alert:
local.pagerduty.create_event:
- tgt: minion
- kwarg:
description: "New VM {{ data['name'] }}"
details: "New VM on {{ data['provider'] }}: {{ data['name'] }}"
service_key: 1162ee51ed6e46239265c969729c48eb
profile: my-pagerduty-account
注意我们如何使用事件数据结构来定制事件消息了吗? 大多数事件的信息中包括作为data['id']的Minion ID,因此您可以使用它在触发该事件的minion上直接采取行动。 例如,在上面的安装cowsay示例中,myminion可以替换为data ['id']。
如果您将构建系统设置为在构建完成时触发自定义事件,则可以把以下状态结果通知slack channel:
spam slack:
local.slack_notify.post_message
- tgt: buildserver
- kwarg:
channel: "Development"
api_key: peWcBiMOS9HrZG15peWcBiMOS9HrZG15"
message: "Build {{ data['build_id'] }} finished with status: {{ data['status'] }}"
build_id和status将是您在触发事件时插入的自动获取到的事件数据。
5.7 SALT STATES
Salt的状态执行模块可以在反应器SLS文件中用于应用salt state或触发salt highstate。 您还可以使用Jinja替换变量值并执行测试和过滤:
{% if data['id'] == 'mysql1' %}highstate_run:
local.state.highstate:
- tgt: mysql1
{% endif %}
5.8 让我们试试吧
现在您已经了解了Salt reactor SLS文件,让我们做更多的试验来熟悉这个功能吧。
创建salt-vagrant-demo/saltstack/salt/reactor目录,然后在该目录中创建一个名为customevent.sls的文件。 接下来,添加本节中的一个反应器SLS示例,或者创建自己的示例。 确保更新目标以定位其中一个系统,例如选择使用minion1。
从您的Salt Master主机上的命令行中,触发以下自定义事件:
sudo salt-call event.send 'my/custom/event/tag'
这个事件会被Salt reactor监测到并触发你创建的customevent.sls文件。