Event 事件组件
Salt 事件组件用于触发事件,使第三方应用程序或外部进程能够对 Salt 中的行为做出反应。 事件系统使用发布 - 订阅模式,或称为 pub/sub。
Event Bus - 事件总线
Event 系统由两个主要组件组成,它们构成了事件总线的概念:
事件套接字,用于发布事件
事件库,它可以侦听事件并将事件发送到 Salt 系统
事件被发布到事件总线上,事件总线的订阅者则侦听已发布的事件。
事件总线既用于进程间通信,又用于 Salt 中的网络传输。 通过 UNIX 域套接字(UDX)提供进程间通信。
Salt Master 和每个 Salt Minion 都有自己的事件总线。
监测 salt 事件
Salt 提供了一个 runner 方法,可以在 Salt Master 收到它们时实时显示出事件信息,命令如下:
salt-run state.event pretty=True
pretty=True 参数可以增加输出的可读性。
注意,该命令会一直占用终端,当它接收到事件信息的时候会打印出来。
事件信息的格式
Event 由两个主要部分组成:
识别被触发事件的标记
包含有关事件详细信息的数据
所有的 salt 事件都以 salt/ 为前缀,并根据事件类型添加其他级别。 例如,作业事件的前缀为 salt/job/。 每个事件的部分都使用 / 分隔以提供简单的命名空间。 这是标识符,被称为事件标签,并且通常包含特定的详细信息,如 job ID 或 minion ID。
每个事件都包含一个时间戳以及对该特定事件唯一的其他键和值。 后期当我们使用 Ractor 时,将学习如何使用事件标签和数据来定制响应。
除了内置事件之外,我们还可以在 Salt 系统中启用一些其他事件,并生成自定义的事件。
发送测试事件
我们既可以在 minions 的本地总线上触发事件,也可以在 Salt Master 节点上触发事件。
要从 minion 的命令行本地触发一个本地的事件,需要调用 event.fire 执行函数,格式如下:
salt-call event.fire '{"data": "message to be sent in the event"}' 'tag'
现在让我们来发送一个测试事件,首先启动事件监听。
salt-run state.event pretty=True
新开一个终端,切换到 root 执行:
salt-call event.fire '{"data": "message to be sent in the event"}' 'tag'
查看事件输出。
我们可以看到,事件已经被捕获,同时也接收到事件传递进来的数据。
要触发一个从 minion 发送到 master 的事件,调用 event.send 执行函数。 另外,可以在 CLI 的函数参数中使用 YAML。
salt-call event.send 'myco/mytag/success' '{success: True, message: "It works!"}'
同样可以看到事件监控程序捕获的事件及数据。
On presence 事件
启用 on presence 事件后,会导致 Salt Master 周期性地查找主动连接的 minions。 在事件总线上以固定时间间隔显示出 minions 的 on presence 状态信息事件,以及带有新连接或断开的 minions 列表信息的事件。
这需要在 Salt Master 的配置文件中启动以下参数,默认值为 False:
# /etc/salt/master 文件添加
presence_events: True
查看事件
salt/presence/present 由 salt master 周期性连接 minion 触发,所以执行该命令后稍微等一段时间才能看到事件。
SALT STATE 执行进度事件
启用 Salt 状态执行进度事件会导致 Salt Minions 发送 State 状态的进度事件,Salt 状态运行中执行的每个函数在执行完成后都会触发此类事件。 进度事件信息的格式是: salt/job//prog//.
该功能默认未启用,需要在 Salt Master 中修改以下参数来打开这个进度事件信息的功能:
# /etc/salt/master 文件添加
state_events: True
测试方法,先建一个 sls 任务文件,路径 /etc/salt/srv/salt/base/state_event.sls 。
# 该 sls 文件用来安装 redis 服务,只为测试 fire_event
redis installed:
pkg.installed:
- name: redis-server
- fire_event: redis-server/已安装
如果设置为 - fire_event: True,就可以发送 state Event,我们在文件里使用 redis-server/已安装 指定了特定的事件字符串。
我们先开启事件监听,salt-run state.event pretty=True,然后在另一个终端执行 salt '*' state.apply state_event,可以在监听终端开到执行 state 完成后的事件。
Grains 组件
Grains 是 SaltStack 收集的有关底层管理系统的静态信息。 SaltStack 收集的 Grains 信息包括操作系统版本、域名、IP 地址、内核、操作系统类型、内存以及许多其他系统属性。
我们可以将自定义的 grains 添加到 Salt Minion 的 /etc/salt/grains 文件中,或放置在 Grains 部分下的 Salt Minion 配置文件中。 例如,许多用户为每个 Salt Minion 添加一个称为角色的定制 grain 来描述系统的功能。
我们可以使用 grains.ls 命令来列出 Salt Minion 的所有 grains:
Salt 提供了一个接口,用于获取被管理系统的有关信息。 这被称为 grains interface,因为它为 salt 提供 grains 信息。 Grains 信息涉及操作系统、域名、IP 地址、内核、操作系统类型、内存和许多其他系统属性。
Salt 模块和组件可以利用 grain 接口,以在正确的系统上自动地获得正确的 salt minion 命令参数。
Grains 数据是相对静态的,但如果系统信息发生变化(例如,如果网络设置发生变化),或者如果将新值分配给自定义 grain,那么 grains 数据将会被刷新。
注意: Grains 被统一解析为小写字母。 例如,FOO 和 foo 指的是同一个 grain。
salt '*' grains.ls
查看 grains 列表
查看 grains 具体数据
salt '*' grains.items
在 state 文件中使用 grains
在 sls 文件中使用 grains 时,类似 {{ grains.id }}。
下面来看一个例子,新建文件 /etc/salt/srv/salt/base/test_grains.sls
# 文件/etc/salt/srv/salt/base/test_grains.sls
echo 服务器ID:{{ grains.id }}: cmd.run
执行:
salt '*' state.apply test_grains
自定义 Grains
新建文件: /etc/salt/grains
roles:
- webserver
- redis
- mysql
以上文件为该服务器添加 grains 数据,名称为 roles,对应了一个包含三个元素的列表。
将 grains 数据同步。
salt '*' saltutil.refresh_modules
现在查看跟新后的 grains 数据。
salt '*' grains.item roles
在 top 文件中使用
创建文件:/etc/salt/srv/salt/base/top.sls
base:
'roles:mysql':
- match: grain
- mysql
新增文件:/etc/salt/srv/salt/base/mysql.sls
echo '这是一个安装mysql的模块': cmd.run
执行命令:
salt '*' state.apply
可以看到,top.sls 文件中 roles.mysql 可以匹配到本机并且执行了mysql.sls
Pillar
Pillar 是 Salt 的一个旨在提供可以分发给 minions 全局数值的功能接口。 pillar 数据的管理方式与 Salt State 树类似。
pillar 数据是在 master 上编译,提供给指定 minion 的 pillar 数据只能由其在 pillar 配置中设定为目标的 minion 访问。 所以 pillar 可用于为特定 minion 存储其特有的敏感数据。
Salt Master 服务器维护一个 pillar_roots 设置,该设置与 Salt 文件服务器中使用的 file_roots 的结构相匹配。 与 file_roots 类似,pillar_roots 选项将环境映射到目录。 然后根据 top file 文件中的匹配器将 pillar 数据映射到 minions,该 top file 文件使用与 state top file 文件相同的方式布局。 Pillar 可以使用与标准 top file 文件相同的匹配器类型。
Pillar 的典型使用场景有:
高度敏感的数据: 通过 pillar 传输的信息保证仅提供给目标对象,使 Pillar 适合管理安全信息,如加密密钥和密码。
Minion 配置: Minion 模块,例如执行模块、状态和 returners 之类的通常可以通过存储在 pillar 中的数据来配置。
使用变量: 需要分配给特定 minions 或 minions 组的变量可以在 pillar 中定义,然后在 sls 公式和模板文件中访问。
任意数据: Pillar 可以包含字典格式的任何基本数据结构,因此可以定义一组 键/值 存储,然后在 sls 公式中轻松迭代它。
查看 pillar 数据
salt '*' pillar.items
设置 pillar_roots 路径
修改文件 /etc/salt/master
pillar_roots:
base:
- /etc/salt/srv/pillar
修改完 master 配置文件需要重启 master
pkill salt-master
salt-master -d -l info
创建对应的文件夹,mkdir /etc/salt/srv/pillar,salt 将从该路径读取 pillar 数据。
Pillar 系统的自定义变量和数据
Salt Pillar 是使 Salt state 可重复使用的必不可少的成分, 所以我们需要先从写 Salt state 的状态文件来设置它。
Salt Pillar 使用 top file 文件将 Salt Pillar 数据与 Salt Minions 配对。top file 的写法与 salt state 非常像。
top file 作为 pillar 的入口文件,salt 从该文件加载 pillar 的数据。我们现在创建该文件,路径 /etc/salt/srv/pillar/top.sls。
base:
"*":
- users
该文件表示所有 minions 主机都会使用 users 这个 pillar 数据。
新建 /etc/salt/srv/pillar/users 目录,并创建文件 /etc/salt/srv/pillar/users/init.sls 文件,内容如下:
users:
user1: 1011
user2: 1012
user3: 1013
该文件定义了一个 名字为 users 的数据字典,包含 3 个 user,该文件与 /etc/salt/srv/pillar/users.sls 等同,pillar 组件会查找 引用组件.sls 和 引用组件/init.sls 导入数据。
当 Salt Pillar 数据更新时, 每个 Salt Minions 都与 top.sls 文件中列出的目标匹配。当一个 Salt Minion 与目标匹配上时, 它会接受在该目标下方列表中定义的所有 Salt Pillar SLS 文件。
使用如下命令更新 pillar 数据:
salt '*' saltutil.refresh_pillar
现在查看下 pillar 数据:
salt '*' pillar.items
最后,我们使用这个数据。
新建 state 文件,路径文件 /etc/salt/srv/salt/base/users.sls,内容如下
{% for user, uid in pillar.get('users', {}).items() %}
{{user}}:
user.present:
- uid: {{uid}}
{% endfor %}
这个 state 文件通过 pillar.get 获取 pillar 数据,使用 for 循环,调用 user.present 模块创建了 3 个用户,并指定的用户 uid。具体 state 用法我们会专门讲到。
现在我们执行这个 state。
salt '*' state.apply users
pillar 其他写法
可以在 state 状态文件中访问 pillar 数据,以定制每个 minion 的行为。适用于每个 minion 的所有 pillar(和 grain)数据,在运行之前通过模板替换为最终可执行的 state 状态文件。比较典型的用途包括设置适合 minion 的配置目录和跳过不适用的 states 状态。
新建文件 /etc/salt/srv/pillar/pkgs.sls
pkgs:
{% if grains['os_family'] == 'RedHat' %}
apache: httpd
{% elif grains['os_family'] == 'Debian' %}
apache: apache2
{% elif grains['os'] == 'Arch' %}
apache: apache
{% endif %}
如上面文件,我们定义了一个名为 pkgs 的变量,里面又包含了一个 apache 的变量,但在不同操作系统下,其对应的值是不一样的。
现在修改 /etc/salt/srv/pillar/top.sls,将我们新定义的 pkg 变量包含到 top 文件中。
base:
'*':
- users
- pkgs
同样,我们新建一个使用 pkgs 变量的 state 文件。
文件名 /etc/salt/srv/salt/base/apache.sls
apache:
pkg.installed:
- name: {{ pillar['pkgs']['apache'] }}
上面的 state 文件要求安装一个 pkg 包,软件包名使用 pillar 数据。
现在刷新 pillar 数据
salt '*' saltutil.refresh_pillar
执行 apache state 文件任务
salt '*' state.apply apache
如图,我们看到,salt 已经通过系统识别到 apache 对应的软件包名称为 apache2。