Saltstack

一、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 = '123456'          #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("argd", '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。

 五、总结:

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

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

原文地址:https://www.cnblogs.com/Richardzhu/p/5790286.html