使用SaltStack Returner将Salt作业信息接入Elasticsearch的实践(踩坑)

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/watermelonbig/article/details/89651226

背景

熟悉SaltStack的都知道,master/minions间所有的交互操作都是通过一个事件总线完成的。从master发出一个管理命令的同时,就生成了一个Job,当minions执行完作业并返回结果数据给master时,则又是以另外一个Job的形式返回的。

因此,我们在排查一些基于salt实现的自动化运维服务故障时,经常要做的一个操作就是登录到master系统,执行salt-run state.event test=True命令,然后观察当执行特定管理或配置任务时,salt底层的事件总线上面究竟是发生了什么,在C/S交互过程中,哪个步骤中有什么错误信息等。

由于以上命令查看的是事件总线上所有的事件交互信息,所以对一个业务繁忙的系统,可能不太容易观察,当你准备进行问题调试时,其它的各种任务产生的事件信息有可能会像刷屏一般地滚过。

把salt jobs信息接入到elasticsearch进行管理还有以下的考虑:

  • salt job缓存数据在使用默认的Default Salt Cache时,只会保存24小时内的数据。由于是通过在master设备本地以文件形式存储的,从很多方面考虑,延长缓存保留时间都会遇到查询性能、空间存储的挑战。
  • 查询salt作业信息时的性能和便利性,通过Kibana查询一个elasticsearch的分布式集群,在使用体验上要强很多。
  • 故障排查要求,有时会遇到一些意料之外的情况,部署的管理或配置任务在运行中出现异常,或是部分主机节点存在异常。这些故障信息需要可以容易被查看、监控和报警出来。
  • 审计要求,是否存在系统管理人员违规使用Salt执行高风险的批量管理命令的行为,是否存在滥用Salt或是错误使用Salt功能的行为。

Salt 提供了十几种开箱即用的Returner模块,像mysql, redis, mongodb这些都有很成熟的接入实践了。此外,参照官网的说明,自己开发一个Returner模块,也很容易,只需要自定义一个Python函数即可。大家有兴趣的可以看下官网的这个链接:https://docs.saltstack.com/en/latest/ref/returners/index.html

将minions的返回结果信息将入到elasticsearch中,很多资料都语焉不详,比较要命的是这篇 elasticsearch_return 官网上介绍elasticsearch return模块的资料已经过时了,此处有坑。

接下来我们,先介绍正确的接入配置方法,再来谈谈哪些官网上介绍的功能或方法是不能使用的。

配置minions向elasticsearch提供作业结果数据的方法

  1. 在salt minion上安装必要的依赖工具包
yum install python27-pip -y
pip2.7 install elasticsearch
  • 我们这里的示例均是在CentOS6/CentOS7系统上配置和测试的
  1. 在minion的配置文件中增加elasticsearch return的配置信息
    我们在这里只给出最简单的一个示例,由于该return模块是基于SALT.MODULES.ELASTICSEARCH二次开发实现的,所以如果有更复杂的使用要求时,可以看一下salt elasticsearch模块的文档,例如使用https加密传输时的证书配置方法。
cat >> /etc/salt/minion << EOF
return: elasticsearch
elasticsearch:
  hosts:
    - "192.168.100.10:9200"
    - "192.168.100.11:9200"
    - "192.168.100.12:9200"
  index_date: True
  number_of_shards: 5
  number_of_replicas: 1
  debug_returner_payload: True
  states_count: True
  states_order_output: True
  states_single_index: True
  functions_blacklist:
    - test.ping
    - saltutil.find_job
    - saltutil.running
EOF
  • number_of_shards,按需设定一个索引分片数量
  • number_of_replicas,设定数据副本数量
  • index_date,使用一个日期格式风格的索引名称 (e.g. -2016.11.29)
  • functions_blacklist,设定哪些模块函数是不需要返回给elasticsearch的
  • 其它可选参数及含义,请参照SALT.RETURNERS.ELASTICSEARCH_RETURN
  1. 重启salt minion服务使配置生效
service salt-minion restart
  1. 验证测试
    我们使用的测试机是gqtest,接入到salt master,同时按前述步骤配置了minion侧的一个elasticsearch return,把作业结果数据向elasticsearch提交一份。
root@sleeper-VirtualBox:~# salt gqtest test.ping
gqtest:
    True
root@sleeper-VirtualBox:~# 

执行以下几个命令,再到kibana上观察下采集到了哪些salt jobs结果数据。

root@sleeper-VirtualBox:~# salt gqtest test.ping
gqtest:
    True
root@sleeper-VirtualBox:~# salt gqtest cmd.run "ls /etc/salt"
gqtest:
    cloud
    cloud.conf.d
    cloud.deploy.d
    cloud.maps.d
    cloud.profiles.d
    cloud.providers.d
    master
    master.d
    minion
    minion.d
    minion.rpmnew
    minion_id
    pki
    proxy
    proxy.d
    proxy.rpmnew
    roster
root@sleeper-VirtualBox:~# salt gqtest saltutil.running
gqtest:
root@sleeper-VirtualBox:~# salt-run jobs.active

打开浏览器,在kibana上创建一个salt-*的index pattern,然后查询已经采集到的数据。
在这里插入图片描述

  • 从上图看到,除了最上面的一条是我们执行cmd模块管理命令产生的作业结果数据外,像其它的test.ping, saltutil.running等因为都在黑名单函数列表中,所以均未被提交给elasticsearch服务。
  • 至于采集到的其他几条数据,从函数名和_index名称可看出,这是因为我们重启salt minion时,重载配置文件内容时执行的几个加载配置文件的命令所产生的。

以上就是将一个salt minion的作业结果数据接入到elasticsearch中所需要的全部配置工作了。

接下来,我们再谈谈在Salt Returnner功能中,目前存在哪些bug或功能不完善之处。针对这些存在问题的功能,需要二次开发补足功能缺陷才能正常使用。

Elasticsearch Returnner 使用在 Salt master-job-cache & ext-job-cache 功能时存在bug

master-job-cache 和 ext-job-cache 是Salt提供的一套可用于替换掉系统默认的Default Job Cache机制的功能插件,通过在master配置文件中进行配置和启用这两个功能。

注意:这里讲的是替换,而不是可以同时存在。而前面我们介绍的returner模块则是属于在Salt 原有机制之上额外增加的负载。这两个功能项,是要替换掉默认的Default Job Cache机制,意味着Salt master/minion将不必再自己缓存和管理作业处理结果数据了。

master-job-cache: elasticsearch
ext-job-cache: elasticsearch

以上两个选项,必须二选一。

  • 在启用master-job-cache时,需要在master上安装elasticsearch-py依赖包,并将下面配置添加在master配置文件中。
  • 在启用ext-job-cache时,需要在minion上安装elasticsearch-py依赖包,并将下面配置添加在minion配置文件中。
elasticsearch:
  hosts:
    - "192.168.100.10:9200"
    - "192.168.100.11:9200"
    - "192.168.100.12:9200"
  index_date: True
  number_of_shards: 5
  number_of_replicas: 1
  debug_returner_payload: True
  states_count: True
  states_order_output: True
  states_single_index: True
  functions_blacklist:
    - test.ping
    - saltutil.find_job
    - saltutil.running
  • 完成以上配置后,重启master/minion服务。

警告:以上两个功能在配置好以后,elasticsearch可以采集到salt jobs处理结果的数据。但是!因为elasticsearch returner插件对master-job-cache, ext-job-cache的功能支持不完善,此时在执行很多其他salt管理模块命令时,如cmd模块,在master日志、minion日志,甚至是执行管理命令的窗口中都会不断得打印报错信息。

下面不区分错误信息出现的位置,只是挑几处典型的报错看一下:

Exception occurred in runner jobs.active: Traceback (most recent call last):
  File "/usr/lib/python2.7/site-packages/salt/client/mixins.py", line 382, in _low
    data['return'] = self.functions[fun](*args, **kwargs)
  File "/usr/lib/python2.7/site-packages/salt/runners/jobs.py", line 71, in active
    data = mminion.returners['{0}.get_jid'.format(returner)](jid)
  File "/usr/lib/python2.7/site-packages/salt/loader.py", line 1114, in __getitem__
    func = super(LazyLoader, self).__getitem__(item)
  File "/usr/lib/python2.7/site-packages/salt/utils/lazy.py", line 101, in __getitem__
    raise KeyError(key)
KeyError: 'elasticsearch.get_jid'

[WARNING ][22475] Returner unavailable: expected string or buffer

CommandExecutionError: Cannot create document in index salt-master-job-cache, server returned code 400 with message mapper_parsing_exception

这些报错让人百思不得其解。

最后不得已翻出来github上的elasticsearch returnner源码找线索,发现错误信息提到的get_jid函数在源码中并不存在!

反复阅读关于master-job-cache, ext-job-cache的技术资料后,发现官网的 Returners页面中,明确指出了,要使用master-job-cache功能,必须在你的插件中实现prep_jid,save_load,get_load三个函数,函数功能大家自行看资料中的介绍:master-job-cache-support

而要使用ext-job-cache功能,必须在returner插件中再实现get_jid,get_fun, get _jids, get_minions这四个函数,详见:external-job-cache-support

而在目前的elasticsearch returner插件中只实现了以上7个函数中的master-job-cache要求的3个,即便这样,在配置和使用master-job-cache: elasticsearch时会报错Returner unavailable: expected string or buffer 。至于ext-job-cache: elasticsearch功能,就完全没有可行性了。

结论:Salt elasticsearch returner 可以作为一个普通returner模块使用,但不能使用像master-job-cache, ext-job-cache这些高级功能。

在分析以上问题的过程中,我也浏览了下 mysql.py , redis_return.py等其它Salt returner模块的源码,发现它们对master-job-cache, ext-job-cache这两个高级管理功能的支持就很完善了,源码详见:https://github.com/saltstack/salt/tree/develop/salt/returners

一点思考:

  • 什么样的场景下适合使用master-job-cache, ext-job-cache这两个高级功能呢。
  • 这两个管理功能是对默认的Default Job Cache机制进行完整地替换,这样做可以获得哪些好处。
  • 当前的elasticsearch returner的源码中还缺少4个用于支持ext-job-cache功能的子函数,如果让你补足短板,可以怎么实现。

注意:当使用master-job-cache, ext-job-cache替换了默认的Default Job Cache时,在master本地就不保存作业缓存数据了,所有作业数据信息的查询和管理都应该是通过salt returner模块读写第三方存储服务来实现的,比如是mysql, redis或elasticsearch 。

展开阅读全文

没有更多推荐了,返回首页