一、Satlstack的概述

  Saltstack是什么?

  Salt是一种和以往不同的基础设施管理方法,它是建立在大规模系统高速通讯能力可以大幅提升的想法上。这种方法使得Salt成为一个强大的能够解决基础设施中许多特定问题的多任务系统。远程执行引擎是Salt的核心,它能够为多组系统创建高速、安全的双向通讯网络。基于这个通讯系统,Salt提供了一个非常快速、灵活并且容易使用的配置管理系统,称之为"Salt States"。

  The backbone of Salt is the remote execution engine, which creates a high-speed, secure and bi-directional communication net for groups of systems. On top of this communication system, Salt provides an extremely fast, flexible, and easy-to-use configuration management system called Salt States.

二、选择Saltstack的原因

  目前市场上主流的开源自动化配置公里工具有puppet、ansible、saltstack。为什么选择saltstack呢?

  先来看一下他们的对比图:

  对于puppet由于不支持二次开发,后续一些需求将无法满足,而且puppet有其复杂的、有将近10000行代码的代码库。而使用saltstack和ansible,用1000行左右的代码就能复制puppet的架构。

  现在脱颖而出的是saltstack和ansible,再来看一下两者的比较:

  一、易用性:

  saltstack负载的文档结构和密集的文字,使得其学习曲线更为陡峭。虽然ansible的文档对初学者而言更简单易读,但随着项目规模的增大,saltstack的文档对开发者的帮助更大。深入分析配置文件(ansible中称为playbooks,saltstack称为stat definitions)突显了二者的区别。Saltstack保持了输入、输出、配置文件的一致性,所有文件均使用YAML格式,而ansible则使用不同的文件格式(INI、YAML)。循环和条件的实现方式也不同。ansible将逻辑部分内嵌在DSL中,而saltstack使用Jinja(一个python模板引擎)。

  二、成熟度:

  在成熟度方面,ansible和saltstack都能提供所有必要的性能和足够的成熟度。不过saltstack有更丰富的特性:可以以不同的文件格式输出到不同的位置;可以从不同的来源加载pillars(其本质是一种数据结构);如果以代理模式运行,可以通过reactor系统触发本地事件。

  三:性能:

  性能方面,saltstack速度更快,尤其是在no-change运行模式下:

  

  在相同的应用场景下saltstack的运行速度远远快于ansible。

  四、技术支持

  在开发社区,saltstack更为友好,开发者数量也更多。

  基于以上原因所以才选择saltstack。

三、saltstack的深入理解

  SaltStack采用C/S模式,server端就是salt的master,client端就是minion,minion与master之间通过ZeroMQ消息队列通信minion上线后先与master端联系,把自己的pub key发过去,这时master端通过salt-key –L命令就会看到minion的key,接受该minion-key后,也就是master与minion已经互信master可以发送任何指令让minion执行了,salt有很多可执行模块,比如说cmd模块,在安装minion的时候已经自带了,它们通常位于你的python库中,下图可以看到salt自带的所有东西。

  这些模块是python写成的文件,里面会有好多函数,如cmd.run,当我们执行下图命令的时候,

  Master下发任务匹配到的minion上去,minion执行模块函数,并返回结果。Master监听4505和4506端口,4505对应的是ZMQ的PUB system,用来发送消息,4506对应的是REP system是来接受消息的。

  具体步骤如下:

  1. Saltstack的Master与Minion之间通过ZeroMQ进行消息传递,使用了ZeroMQ的发布-订阅模式,连接方式包括tcp,ipc;
  2. Salt命令,将cmd.run ls 命令从salt.client.LocalClient.cmd_cli发布到master,获取一个Jobid,根据jobid获取命令执行结果;
  3. Master接收到命令后,将要执行的命令发送给客户端minion;
  4. Minion从消息总线上接收到要处理的命令,交给minion._handle_aes处理;
  5. Minion._handle_aes发起一个本地线程调用cmdmod执行ls命令。线程执行完ls后,调用minion._return_pub方法,将执行结果通过消息总线返回给master;
  6. Master接收到客户端返回的结果,调用master._handle_aes方法,将结果写到文件中;
  7. Salt.client.LocalClient.cmd_cli通过轮询获取Job执行结果,将结果输出到终端。

  通过上面的讲解,我们已经了解到salt-master与salt-minion的通信原理,那下面来了解一下saltstack的功能:

  

  一、Dashboard仪表盘

  Salt目前没有图形化的界面。

  二、Targeting批量操作

  当你知道一批主机的IP,想要执行uptime命令,这个时候就可以提现批量操作的功能

  例如:

  

  上面的例子都是对多个节点进行批量操作,另外还可以使用通配符"'*'"对所有注册的节点进行操作。Salt支持多种方式对节点id(minion id)进行匹配。包括:

  默认:通配符(globbing)

  * E :正则表达式(Regular Expression)

  * L :列表

  * N:分组(group)

  * C:复合匹配

  三、api二次开发

  saltstack官方提供有rest api格式的salt-api项目,将使salt与第三方系统集成变得尤为简单。

  在这里演示一下python调用salt-api的例子:

#!/usr/bin/env python
# -*- coding=utf8 -*- import urllib2, urllib, json, re class saltAPI:
def __init__(self):
self.__url = 'http://192.168.11.125:8081' #salt-api监控的地址和端口如:'https://192.168.11.125:8081'
self.__user = 'salt' #salt-api用户名
self.__password = '' #salt-api用户密码
self.__token_id = self.salt_login() def salt_login(self):
params = {'eauth': 'pam', 'username': self.__user, 'password': self.__password}
encode = urllib.urlencode(params)
obj = urllib.unquote(encode)
headers = {'X-Auth-Token':''}
url = self.__url + '/login'
req = urllib2.Request(url, obj, headers)
opener = urllib2.urlopen(req)
content = json.loads(opener.read())
try:
token = content['return'][0]['token']
return token
except KeyError:
raise KeyError def postRequest(self, obj, prefix='/'):
# prefix='/minions'
url = self.__url + prefix
headers = {'X-Auth-Token' : self.__token_id}
req = urllib2.Request(url, obj, headers)
opener = urllib2.urlopen(req)
content = json.loads(opener.read())
return content['return'] def saltCmd(self, params):
obj = urllib.urlencode(params)
obj, number = re.subn("arg\d", 'arg', obj)
res = self.postRequest(obj)
return res def main():
params = {'client':'local', 'fun':'test.ping','tgt':'192.168.11.121,192.168.11.122','expr_form':'list'}
value = sapi.saltCmd(params)
print value if __name__ == '__main__':
main()

  执行效果如下:

    

四、Grains节点信息

  grains是salt内置的一个非常有用的模块。在用salt进行管理客户端的时候或者写state的时候都可以引用grains的变量。

  grains的基本使用举例如下:

#查看grains分类
salt '*' grains.ls #查看grains所有信息
salt '*' grains.items #查看grains某个信息
salt '*' grains.items osrelease

  五、pillar模块

  Pillar是salt用来分发全局变量到所有minions的一个接口。不像是state tree,pillar只对匹配类型的minion有效。这使它为特定的minion存储敏感数据非常有用。

  六、Group节点分组

  上面批量操作确实很爽,但是每次都输入匹配规则有点麻烦,对于复杂的匹配规则更是如此。salt的group功能可以将常用的匹配规则保存下来(称之为minion的分组)。批量操作是,只需要使用L标记指定要操作的group名字即可。groups定义在master的配置文件/etc/salt/master中。

  group的定义可以使用各种匹配规则,比如:

  group1: 'L@hadoop1.com,hadoop2.com,hadoop3.com'

  group2: 'G@os:Redhat and hadoop1.com'

  七、state状态管理

  状态配置管理是salt中非常重要的内容之一。salt通过内置的state模块支持配置管理所需的功能。

  salt可以定义节点的目标状态,称之为state。state对应配置管理中的配置,可以对其进行标识、变更控制、变更识别、状态报告、跟踪和归档以及审计等一些管理行为。

  八、scheduling任务调度

  schedule任务调度系统,可以将其理解为类似于linux系统上的crontab,可以执行任何的执行函数在minion上或者在master上任何的runner。

  开启schedule,只需要在master或者minion的配置文件中开始schedule参数,或者为minion定义pillar数据指定maxrunning用来开启对某个任务最多执行次数的限制,该值默认为1。

  九、exection命令编排

  salt生来就有命令编排的功能。据说,salt最先实现的是远程执行技术,然后才添加的配置管理功能。salt使用ZeroMQ来响应消息,安装配置简单,并且性能非常高。

  salt即可以批量执行命令,也可以单机执行。通常单机执行用于测试:

  1. 单机(立即)执行。使用salt-call命令单机执行;

  2. 批量(立即)执行。最常用的操作。使用salt命令,对匹配的minion节点执行操作。

  salt可以执行命令可以分为两种:

  1.系统命令,使用cmd.run执行

  2.salt模块,将常用的命令/批处理封装到内置的salt模块(module),使用模块名.功能名的方式执行。

  十、returner返回数据

  By default the return values of the commands sent to the Salt minions are returned to the Salt master, however anything at all can be done with the results data.

  By using a Salt returner, results data can be redirected to external data-stores for analysis and archival.

  Returners pull their configuration values from the Salt minions. Returners are only configured once, which is generally at load time.

  The returner interface allows the return data to be sent to any system that can receive data. This means that return data can be sent to a Redis server, a MongoDB server, a MySQL server, or any system.

  在这里演示一个将结果返回给本地的demo:

  创建一个_returners目录:

  

  将local_return同步到minion:

  

  运行:

  #--return后面跟的参数是returners里面指定__virtual__这个方法返回

  

  查看minion端的日志文件:

  已经成功写入文件。

  想要了解更多的例子,请点击:官方的例子

  十一、modules操作模板

  salt已经内置了大量的模块,这些模块涵盖了日常管理任务的主要任务,包括:

  1. 通过的管理任务,比如apt,at,cp,cron,disk,extfs,file,grains,hosts,iptables,mount,network,pam,parted,pkg,ps,selinux,shadow,ssh,test等等。

  2. 针对特定软件的任务,比如apache,cassandra,djangomod,git,mongodb,mysql,nginx,nova,postgres,solr,sqlite3和tomcat。

  而且,自己开发salt模块也非常简单,称之为自定义模块,例如:

  

  十二、call单机调试

   salt-call该命令通常在minion上执行,minion自己执行可执行模块,不是通过master下发job:

  salt-call [options] <function> [arguments]

  salt-call test.ping

  salt-call cmd.run 'ifconfig'

  利用上面写get_ip.py模块,在minion上执行:

  

  十三、salt-syndic

  salt 在0.9.0版本中增加了syndic特性。syndic建立在中心master和minion之间,并允许多层分级syndic,使salt拓扑可以变得更为灵活,详细介绍见系统架构图。

  十四、salt-broker

  salt-broker是轻量级的salt-proxy解决方案,只做数据转发,不做额外的处理。具体设计架构如下图:

  其实salt还有好多功能,这里只是例举了一些,想要了解更多请点击:https://saltstack.com/

四、系统架构图

  一个基本的salt配置方式是一个master指挥一群minion,为了不再有假设使用任何单一拓扑结构,另外当minion数量达到2000以上以后salt的执行速度就会降低,在新的saltstack版本中有一个salt-syndic,主控master可以控制一群master,通过syndic将操作命令传输给受控master,受控master来完成对自己旗下minion的管理,并将结果传回主控master,从而实现了主控master对所有minion的间接管理。

  目前采用的架构图如下:

  

  后续将对该架构图进行调整,中心master将进行双master模式,syndic节点也将使双syndic,另外考虑到syndic在网络链路不好的情况下,syndic架构将变得不可控,后期会对比一下salt-broker,或者另外再开发一个salt proxy。

 五、总结:

  本篇文章主要介绍了运维平台的底层服务器批量管理的软件、选型和简单原理,后续会逐步介绍完整的架构以及实现方式。

  对此有兴趣的同学欢迎一起交流 。

Saltstack的更多相关文章

  1. saltstack初探

    salt-key -y -d linux-node1 #删除linux-node1节点的认证 salt -G 'cpuarch:x86_64' grains.item num_cpus >> ...

  2. saltstack命令执行过程

    saltstack命令执行过程 具体步骤如下 Salt stack的Master与Minion之间通过ZeroMq进行消息传递,使用了ZeroMq的发布-订阅模式,连接方式包括tcp,ipc salt ...

  3. Saltstack之salt-master的打开文件数问题

    一.引言: 单个salt-master下的minion数已经达到2101个了,所以在master日志有如下的提示: 2016-09-09 11:36:22,221 [salt.utils.verify ...

  4. python virtualenv 安装运行saltstack

    需求产生场景:      1.python的virtualenv虚拟环境非常的好用.      2.saltstack作为运维自动化的一个重要组件也挺好用的. 但是:      1.saltsatck ...

  5. 自动化运维:网站svn代码上线更新(flask+saltstack)

    阶段性总结:      跌跌撞撞的用了一周左右的时间做完了网站自动升级功能,中间遇到了很多的问题,也学到了很多,在此做一个总结.   1.整体架构: 后台:nginx+uwsgi  #nginx提供w ...

  6. saltstack安装配置(halite)

    saltstack官方提供了一个简单的web UI--halite.但是给出的安装配置方法实在没法实现,在网上找了几篇博客,见文章末尾的参考链接,可以用起来了.但是功能有点简单.这篇文章记录安装配置h ...

  7. Saltstack异步执行命令(十三)

    Saltstack异步执行命令 salt执行命令有时候会有超时的问题,就是命令下发下去了,部分主机没有返回信息,这时候就很难判断命令或任务是否执行成功.因此,salt提供异步执行的功能,发出命令后立即 ...

  8. Saltstack之SSH(十一)

    Saltstack之SSH 安装 yum install -y salt-ssh 官方文档  https://docs.saltstack.com/en/latest/topics/ssh/index ...

  9. Saltstack之Syndic(十)

    Saltstack之Syndic 使用条件: 1.salt syndic必须运行在一台master上 2.salt syndic必须依赖更高级的master 安装 yum install -y sal ...

随机推荐

  1. insert操作卡死的处理过程

    insert操作卡死的处理过程 先看看insert为什么被卡死 SQL> select sql_id from v$sql where sql_text like 'delete from st ...

  2. Android Unable to instantiate activity: Didn't find class on path

    Android Unable to instantiate activity: Didn't find class on path After i spend a while on this prob ...

  3. SQL语句 - MERGE INTO 、Cross/Outer Apply用法理解

    MERGE INTO 语法: MERGE INTO table_name alias1 USING (table|view|sub_query) alias2ON (join condition) W ...

  4. 关于(object sender, EventArgs e)

      sender是事件源 就是指发起这个事件的对象(控件)//表示触发事件的那个控件比如说你按下按钮,那么sender就是按钮 又如:textboxchange,sender就是该textbox,在事 ...

  5. 在asp.net WebForms中使用路由Route

    1.新建WebForms应用程序 2.打开Global.asax文件代码如下: public class Global : System.Web.HttpApplication { protected ...

  6. scp使用

    从82服务器复制文件 scp -P 50028 -r root@***.**.**.82:/data/upload.tar / -P:指定非ftp22端口

  7. 制作自己的嵌入式Linux电脑_转

    制作自己的嵌入式Linux电脑 http://os.51cto.com/art/201409/450334.htm 原文链接:http://blog.jobbole.com/75414/ 包含器件选择 ...

  8. iar调试

    我们可以自己建立自己的工程了,但这一步只是开发中的第一小步.今天就来说说开发中举足轻重的另外一件事:调试. 其实调试本身也并不难,楼主总结,调试关键在于两件事,一是运行,二是观察,为了更好的实现这两者 ...

  9. Leetcode: Validate IP Address

    In this problem, your job to write a function to check whether a input string is a valid IPv4 addres ...

  10. 解决:IntelliJ IDEA 编译错误,提示 Compilation failed: internal java compiler error

    原因可能是项目指定的JDK与当前环境JDK不符合,解决办法:File->Setting->Compiler->Java Compiler, 在相应的module中选择合适的JDK版本 ...