白话saltstack在私有云上的应用

杨兆飞 360云计算

女主宣言

saltstack是一种常见的集群管理解决方案。本文主要讲了hulk私有云平台在实践集群管理过程中,根据自身产品特点和定制需求做了相应优化,同时向大家普及一些saltstack在执行命令时内部的一些原理。 PS:丰富的一线技术、多元化的表现形式,尽在“HULK一线技术杂谈”,点关注哦!

saltstack是一种常见的集群管理解决方案,大家常用它作为批量执行命令的工具。原生saltstack架构如图所示(盗图勿究)。 saltstack分为master和minion两部分,master和minion之间保持tcp长连接,通信消息用AES加密,命令下发采用zeromq的发布-订阅模式,master负责分发命令,minion负责执行和返回结果。saltstack简单易用,虽然手动执行也很方便,但是面对成千上万台机器,手动变得不可取。 hulk作为支撑数字公司90%业务线的私有云平台,自然会根据自身需求对saltstack做优化。那么hulk的命令执行系统在原生saltstack结构基础上进行包装和优化,总体分为三个部分:

集成在hulk管理后台里的命令系统;

1)管理预制的任务脚本 2)查看任务执行状态与结果,失败任务重做 3)保存任务执行历史

hulk为自己量身定制开发的任务模块;

1)用来拉取执行和返回执行结果 2)检测和上报各minion主机的可控状态

原生的salt-master和salt-minion+定制的perl脚本;

1)定制的perl脚本会检查任务脚本是否是最新版,是则执行,不是则更新任务脚本后执行 2)检查任务是否执行超时,超时则关闭任务

              ![](https://s4.51cto.com/images/blog/202103/22/7dee043c2031e0f4c868414b5b3df93f.png?x-oss-process=image/watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_30,g_se,x_10,y_10,shadow_20,type_ZmFuZ3poZW5naGVpdGk=)

为了将任务产生和执行分开,更好地异步处理,我们在一和二之间选用redis做数据交互,一将要执行的机器和命令写到redis,二则到redis取这些数据然后调用三执行命令。 模拟一条任务执行的过程可以帮助我们更好了解这套命令系统的工作原理:

1

在hulk命令系统中选中要执行的主机,系统对主机名校验,检查这些主机在系统中是否存在,还有任务模块上报的是否可控的状态;

2

命令系统到redis里查询主机所属saltstack集群,将可执行主机和命令发到所属集群的redis队列里;

3

每个saltstack集群的任务模块会去redis拉自己集群队列的消息,然后调用salt-master;同时redis队列被取走后,命令系统将任务状态标记为执行中;

4

master拿到主机和命令,用master私钥对消息进行签名,然后通过zeromq无差别发布给所有minion主机;

5

minion接收到消息后,用master公钥对消息解密,确认消息来自master后,对比消息中主机和自己的id,如果是自己则起子进程执行命令,不是自己则不管;

6

minion命令执行结束,将执行结果用返回结果给master,任务控制模块拿到结果然后将每台主机结果写到redis;如果在设置的超时时间内未运行完毕,perl脚本将kill掉命令进程,命令系统标记任务为超时;

7

命令系统在redis拿到任务结果后整理展示,将结果相同的主机合并。 目前这套命令系统在线上以99%的成功率稳定运行。但我们并不满足,通过研究saltstack源码和原理,发现saltstack中存在的问题,比如zeromq的pub/sub不可靠传输、任务同时下发给所有minion很浪费网络资源、任务失败或超时后的处理机制缺乏等等。为了解决这些问题,我们开发了全新的命令系统,在以后会和大家分享,请拭目以待。新的命令系统真的→