SaltStack

SaltStack

SaltStack RESTful API的调用

运维技术chris 发表了文章 • 0 个评论 • 843 次浏览 • 2016-04-27 21:15 • 来自相关话题

如果需要通过第三方来调用SaltStack时,使用SaltStack自带的Python API并不能很好的满足需求。可以通过使用SaltStack基于RESTful风格的HTTP API。该API模块并不是内置的,需要单独安装。

Salt REST API简介
这里简单的说明下,SaltStack官方支持三种REST API,分别是rest_cherry; rest_tonado和rest_wsgi
[]rest_cherry和rest_tonado两个模块支持监听所有IP的指定端口接收请求[/]
shell> lsof -i:1559
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
salt-api 13443 root 14u IPv4 21888585 0t0 TCP *:web2host (LISTEN)

[]rest_wsgi只支持本机访问,只绑定了127.0.0.1[/]
shell> lsof -i:1559
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
salt-api 13443 root 14u IPv4 21888585 0t0 TCP 127.0.0.1:web2host (LISTEN)



本文选择使用rest_cherry模块来实现SaltStack的HTTP API
 
安装Salt-API服务
一般情况下,salt-api会使用HTTPS,首次配置成功后,使用用户名和密码登陆,获得Token,Token创建后,默认有效期是12小时,在有效期之内,使用该Token可以代替使用用户名和密码来访问API(该有效时间可在salt-master配置文件中修改)
 
必备安装包
shell> yum -y install gcc make python-devel libffi-devel
shell> pip install pyOpenSSL==0.15.1借助salt工具来生成证书​
shell> salt-call --local tls.create_self_signed_cert
local:
Created Private Key: "/etc/pki/tls/certs/localhost.key." Created Certificate: "/etc/pki/tls/certs/localhost.crt."alt-call是salt-minion的工具,如果没有这个命令,可以在master端安装minion,然后再执行以上命令
 
安装salt-api
shell> yum -y install salt-api配置用户及权限
shell> useradd -M -s /sbin/nologin sa
shell> echo "sapassword" | passwd sa --stdin在salt-master的配置文件最后添加如下配置
external_auth:
pam: #认证模式,pam指的是用Linux本身的用户认证模式
sa: #Linux系统中真实存在的用户名
- '[i]': #设置用户的权限,允许该用户操作哪些主机,[/i]代表全部
- test.* #允许操作的模块及方法
- cmd.*其他认证模式可以参考官方文档:http://docs.saltstack.com/en/latest/topics/eauth/index.html​
 
配置示例一:多用户(官方文档)
external_auth:
pam:
thatch:
- 'web*':
- test.*
- network.*
steve:
- .*配置示例二:指定用户组(官方文档)
external_auth:
pam:
admins%:
- '*':
- 'pkg.*'使用%来表示用户组
 
配置示例三:操作模块组(官方文档)
external_auth:
pam:
thatch:
- '@wheel' # to allow access to all wheel modules
- '@runner' # to allow access to all runner modules
- '@jobs' # to allow access to the jobs runner and/or wheel module查看wheel modules完整列表         查看runner modules完整列表
 
配置salt-api服务
在salt-master的配置文件最后添加如下配置
rest_cherrypy:
port: 1559 #默认监听所有IP的1559端口
ssl_crt: /etc/pki/tls/certs/localhost.crt #引用的正是前面创建的证书
ssl_key: /etc/pki/tls/certs/localhost.key其他配置参数可以参考官方文档:https://docs.saltstack.com/en/latest/ref/netapi/all/salt.netapi.rest_cherrypy.html
 
启动服务
shell> service salt-api start登陆获得Token
url -sSk https://www.20150509.cn:1559/login \
-H 'Accept: application/x-yaml' \
-d username=sa \
-d password=sapassword \
-d eauth=pam复制得到的Token
curl -sSk https://localhost:8000 \
-H 'Accept: application/x-yaml' \
-H 'X-Auth-Token: 697adbdc8fe971d09ae4c2a3add7248859c87079'\
-d client=local \
-d tgt='*' \
-d fun=test.ping除了支持Token以外还支持使用cookies.txt文件来访问API,详情可查看官方文档
 
使用Python脚本来访问API
在salt-api官方文档中,对python访问API给出了如下的格式要求
[{
"client": "local",
"tgt": "*",
"fun": "test.fib",
"arg": ["10"]
},
{
"client": "runner",
"fun": "jobs.lookup_jid",
"jid": "20130603122505459265"
}]以上的JSON代码中,指定了API去执行两个命令,一个模块命令,一个runner命令。Python代码实现如下:
import json
import urllib
import urllib2

#在python2.6x中,以下两行不是必须的
import ssl
ssl._create_default_https_context = ssl._create_unverified_context

url='https://www.20150509.cn:1559' #salt-api所在的“坐标”

def test():
pre_data = [{"client":"local", "tgt":"*", "fun":"test.ping"}] #根据上面官方文档的要求组成数组嵌套字典的形式
json_data = json.dumps(pre_data) #将其转化为json格式

header = {"Content-Type":"application/json", "Accept":"application/json", "X-Auth-Token":"697adbdc8fe971d09ae4c2a3add7248859c87079"}
#这里说明下,Content-Type是声明传递给API的数据是什么格式的,这里指定了json,是因为上面的pre_data数据被我转化成了json格式
#Accept是声明返回结果以什么样的格式显示,这里也指定了json格式来显示返回结果

request = urllib2.Request(url, json_data, header) #构造一次请求
response = urllib2.urlopen(request) #构造一次HTTP访问

html = response.read()
print html


if __name__=="__main__":
test()指定Accept为application/json执行结果如下:
shell> python sa.py
{"return": [{"vm3.salt.com": true, "vm2.salt.com": true, "ph1.salt.com": true, "ph2.salt.com": true, "vm1.salt.com": true, "vm4.salt.com": true, "localhost": true, "vm7.salt.com": true}]}
#指定Accept为application/x-yaml执行结果如下:
shell> python sa.py
return:
[list]
[*]localhost: true[/*]
[/list] ph1.salt.com: true
ph2.salt.com: true
vm1.salt.com: true
vm2.salt.com: true
vm3.salt.com: true
vm4.salt.com: true
vm7.salt.com: true参考文档
salt-api:https://github.com/saltstack/salt-api 
rest_cherrypy:https://docs.saltstack.com/en/latest/ref/netapi/all/salt.netapi.rest_cherrypy.html 
认证模式:http://docs.saltstack.com/en/latest/topics/eauth/index.html
分享阅读原文:http://docs.20150509.cn/2016/03/21/SaltStack-RESTful-API%E7%9A%84%E8%B0%83%E7%94%A8-salt-api/ 查看全部


如果需要通过第三方来调用SaltStack时,使用SaltStack自带的Python API并不能很好的满足需求。可以通过使用SaltStack基于RESTful风格的HTTP API。该API模块并不是内置的,需要单独安装。


Salt REST API简介
这里简单的说明下,SaltStack官方支持三种REST API,分别是rest_cherry; rest_tonado和rest_wsgi
    []rest_cherry和rest_tonado两个模块支持监听所有IP的指定端口接收请求[/]

shell> lsof -i:1559
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
salt-api 13443 root 14u IPv4 21888585 0t0 TCP *:web2host (LISTEN)

    []rest_wsgi只支持本机访问,只绑定了127.0.0.1[/]

shell> lsof -i:1559
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
salt-api 13443 root 14u IPv4 21888585 0t0 TCP 127.0.0.1:web2host (LISTEN)
Snip.png

本文选择使用rest_cherry模块来实现SaltStack的HTTP API
 
安装Salt-API服务
一般情况下,salt-api会使用HTTPS,首次配置成功后,使用用户名和密码登陆,获得Token,Token创建后,默认有效期是12小时,在有效期之内,使用该Token可以代替使用用户名和密码来访问API(该有效时间可在salt-master配置文件中修改)
 
必备安装包
shell> yum -y install gcc make python-devel libffi-devel
shell> pip install pyOpenSSL==0.15.1
借助salt工具来生成证书​
shell> salt-call --local tls.create_self_signed_cert
local:
Created Private Key: "/etc/pki/tls/certs/localhost.key." Created Certificate: "/etc/pki/tls/certs/localhost.crt."
alt-call是salt-minion的工具,如果没有这个命令,可以在master端安装minion,然后再执行以上命令
 
安装salt-api
shell> yum -y install salt-api
配置用户及权限
shell> useradd -M -s /sbin/nologin sa
shell> echo "sapassword" | passwd sa --stdin
在salt-master的配置文件最后添加如下配置
external_auth:
pam: #认证模式,pam指的是用Linux本身的用户认证模式
sa: #Linux系统中真实存在的用户名
- '[i]': #设置用户的权限,允许该用户操作哪些主机,[/i]代表全部
- test.* #允许操作的模块及方法
- cmd.*
其他认证模式可以参考官方文档:http://docs.saltstack.com/en/latest/topics/eauth/index.html​
 
配置示例一:多用户(官方文档)
external_auth:
pam:
thatch:
- 'web*':
- test.*
- network.*
steve:
- .*
配置示例二:指定用户组(官方文档)
external_auth:
pam:
admins%:
- '*':
- 'pkg.*'
使用%来表示用户组
 
配置示例三:操作模块组(官方文档)
external_auth:
pam:
thatch:
- '@wheel' # to allow access to all wheel modules
- '@runner' # to allow access to all runner modules
- '@jobs' # to allow access to the jobs runner and/or wheel module
查看wheel modules完整列表         查看runner modules完整列表
 
配置salt-api服务
在salt-master的配置文件最后添加如下配置
rest_cherrypy:
port: 1559 #默认监听所有IP的1559端口
ssl_crt: /etc/pki/tls/certs/localhost.crt #引用的正是前面创建的证书
ssl_key: /etc/pki/tls/certs/localhost.key
其他配置参数可以参考官方文档:https://docs.saltstack.com/en/latest/ref/netapi/all/salt.netapi.rest_cherrypy.html
 
启动服务
shell> service salt-api start
登陆获得Token
url -sSk https://www.20150509.cn:1559/login \
-H 'Accept: application/x-yaml' \
-d username=sa \
-d password=sapassword \
-d eauth=pam
复制得到的Token
curl -sSk https://localhost:8000 \
-H 'Accept: application/x-yaml' \
-H 'X-Auth-Token: 697adbdc8fe971d09ae4c2a3add7248859c87079'\
-d client=local \
-d tgt='*' \
-d fun=test.ping
除了支持Token以外还支持使用cookies.txt文件来访问API,详情可查看官方文档
 
使用Python脚本来访问API
在salt-api官方文档中,对python访问API给出了如下的格式要求
[{
"client": "local",
"tgt": "*",
"fun": "test.fib",
"arg": ["10"]
},
{
"client": "runner",
"fun": "jobs.lookup_jid",
"jid": "20130603122505459265"
}]
以上的JSON代码中,指定了API去执行两个命令,一个模块命令,一个runner命令。Python代码实现如下:
import json
import urllib
import urllib2

#在python2.6x中,以下两行不是必须的
import ssl
ssl._create_default_https_context = ssl._create_unverified_context

url='https://www.20150509.cn:1559' #salt-api所在的“坐标”

def test():
pre_data = [{"client":"local", "tgt":"*", "fun":"test.ping"}] #根据上面官方文档的要求组成数组嵌套字典的形式
json_data = json.dumps(pre_data) #将其转化为json格式

header = {"Content-Type":"application/json", "Accept":"application/json", "X-Auth-Token":"697adbdc8fe971d09ae4c2a3add7248859c87079"}
#这里说明下,Content-Type是声明传递给API的数据是什么格式的,这里指定了json,是因为上面的pre_data数据被我转化成了json格式
#Accept是声明返回结果以什么样的格式显示,这里也指定了json格式来显示返回结果

request = urllib2.Request(url, json_data, header) #构造一次请求
response = urllib2.urlopen(request) #构造一次HTTP访问

html = response.read()
print html


if __name__=="__main__":
test()
指定Accept为application/json执行结果如下:
shell> python sa.py 
{"return": [{"vm3.salt.com": true, "vm2.salt.com": true, "ph1.salt.com": true, "ph2.salt.com": true, "vm1.salt.com": true, "vm4.salt.com": true, "localhost": true, "vm7.salt.com": true}]}
#
指定Accept为application/x-yaml执行结果如下:
shell> python sa.py 
return:
[list]
[*]localhost: true[/*]
[/list] ph1.salt.com: true
ph2.salt.com: true
vm1.salt.com: true
vm2.salt.com: true
vm3.salt.com: true
vm4.salt.com: true
vm7.salt.com: true
参考文档
salt-api:https://github.com/saltstack/salt-api 
rest_cherrypy:https://docs.saltstack.com/en/latest/ref/netapi/all/salt.netapi.rest_cherrypy.html 
认证模式:http://docs.saltstack.com/en/latest/topics/eauth/index.html
分享阅读原文:http://docs.20150509.cn/2016/03/21/SaltStack-RESTful-API%E7%9A%84%E8%B0%83%E7%94%A8-salt-api/

SaltStack介绍和架构解析

运维技术Ansible 发表了文章 • 0 个评论 • 3078 次浏览 • 2015-11-15 21:09 • 来自相关话题

简介

SaltStack是一种新的基础设施管理方法开发软件,简单易部署,可伸缩的足以管理成千上万的服务器,和足够快的速度控制,与他们交流,以毫秒为单位。SaltStack提供了一个动态基础设施通信总线用于编排,远程执行、配置管理等等。SaltStack项目于2011年启动,年增长速度较快,五年期固定基础设施编制和配置管理的开源项目。SaltStack社区致力于保持盐项目集中、友好、健康、开放。 简单来说它的两大基础功能就是:配置管理、远程命令执行。剩下就是根据你的需求自由组合,实现更复杂的功能和系统管理。

SaltStack学习过程

大概步骤如下:
[]安装和配置SaltStack[/][]远程执行命令所有管理系统[/][]设计、开发和部署系统配置[/][]用SaltStack反应器来自动化基础设施[/][]协调使用SaltStack编排复杂的管理操作[/]





SaltStack组件

1、SaltStack  Master
中央管理系统\服务端,这个系统是用来发送命令和配置到SaltStack Minion上运行。




 
2、SaltStack Minion
接受受管理系统\客户端,该系统接收来自SaltStack Master命令和配置。




 
3、执行模块过程
特别对一个或多个命令从命令行执行受管理系统。 适用于:
[]实时监控、状态和库存[/][]一次性命令和脚本[/][]部署关键更新[/]




 
4、规则(States)
声明或命令式表示一个系统的配置。




 
5、Grains
系统变量, Grains是静态信息基础管理系统,包括操作系统、内存和许多其他的系统属性,您还可以定义定制的Grains为任何系统。




 
6、Pillar
用户定义的变量,这些安全变量定义和存储在Salt Master,然后“分配”到一个或多个下属,Pillar数据存储值,文件路径,配置参数,和密码。




 
7、Top File
数据匹配公式




 
8、Runners
模块执行SaltStack Master执行支持任务,Runners报告的工作状态、连接状态读取数据从外部api,查询连接Salt Minions,和更多。
例如,安排Runners在许多系统之间协调配置部署。




 
9、Returners
SaltStack Minion返回的数据发送到另一个系统,如数据库,Returners可以运行在Salt Minion或Salt Minion。




 
10、Reactor
SaltStack环境中触发事件发生时的反应。




 
11、Salt Cloud / Salt Virt
云提供商提供系统/管理程序并立即把他们管理下。




 
12、SaltStack SSH
SaltStack使用ssh运行命令,在没有Salt Minion的情况下。





到这里SaltStack组件和构成架构体系就介绍到这里,还有一些比如高可用没有介绍
参考:docs.saltstack.com 查看全部


简介


SaltStack是一种新的基础设施管理方法开发软件,简单易部署,可伸缩的足以管理成千上万的服务器,和足够快的速度控制,与他们交流,以毫秒为单位。SaltStack提供了一个动态基础设施通信总线用于编排,远程执行、配置管理等等。SaltStack项目于2011年启动,年增长速度较快,五年期固定基础设施编制和配置管理的开源项目。SaltStack社区致力于保持盐项目集中、友好、健康、开放。 
简单来说它的两大基础功能就是:配置管理、远程命令执行。剩下就是根据你的需求自由组合,实现更复杂的功能和系统管理。


SaltStack学习过程


大概步骤如下:
    []安装和配置SaltStack[/][]远程执行命令所有管理系统[/][]设计、开发和部署系统配置[/][]用SaltStack反应器来自动化基础设施[/][]协调使用SaltStack编排复杂的管理操作[/]

saltstack_arch.png


SaltStack组件


1、SaltStack  Master
中央管理系统\服务端,这个系统是用来发送命令和配置到SaltStack Minion上运行。
salt_master.png

 
2、SaltStack Minion
接受受管理系统\客户端,该系统接收来自SaltStack Master命令和配置。
salt_minion.png

 
3、执行模块过程
特别对一个或多个命令从命令行执行受管理系统。 适用于:
    []实时监控、状态和库存[/][]一次性命令和脚本[/][]部署关键更新[/]

remote_execution.png

 
4、规则(States)
声明或命令式表示一个系统的配置。
salt_states.png

 
5、Grains
系统变量, Grains是静态信息基础管理系统,包括操作系统、内存和许多其他的系统属性,您还可以定义定制的Grains为任何系统
salt_grains.png

 
6、Pillar
用户定义的变量,这些安全变量定义和存储在Salt Master,然后“分配”到一个或多个下属,Pillar数据存储值,文件路径,配置参数,和密码。
salt_pillar.png

 
7、Top File
数据匹配公式
salt_topfile.png

 
8、Runners
模块执行SaltStack Master执行支持任务,Runners报告的工作状态、连接状态读取数据从外部api,查询连接Salt Minions,和更多。
例如,安排Runners在许多系统之间协调配置部署。
salt_runners.png

 
9、Returners
SaltStack Minion返回的数据发送到另一个系统,如数据库,Returners可以运行在Salt Minion或Salt Minion。
salt_returners.png

 
10、Reactor
SaltStack环境中触发事件发生时的反应。
salt_reactor.png

 
11、Salt Cloud / Salt Virt
云提供商提供系统/管理程序并立即把他们管理下。
salt_cloud.png

 
12、SaltStack SSH
SaltStack使用ssh运行命令,在没有Salt Minion的情况下。
salt_ssh.png


到这里SaltStack组件和构成架构体系就介绍到这里,还有一些比如高可用没有介绍
参考:docs.saltstack.com


Saltstack高可用架构漫谈

运维技术采菊篱下 发表了文章 • 0 个评论 • 1458 次浏览 • 2015-11-14 11:09 • 来自相关话题

起因

鄙人折腾Salt也已经一年有余了,从最开始Linux运维的基础知识,包括啥叫配置管理都一无所知,事到如今好歹也做了一些事情,虽然没啥功劳,也埋了一些坑,但是总归在自动化方面贡献了一些微薄的力量。

为什么要搞Salt高可用架构呢? 起因是因为公司内部对于Salt的要求从工具上升到了基础架构组件的层面,要求在响应时间和服务可用性方面有一些更高的要求,简单来说,就是内部的一些重要组件依赖于它来完成一些事情。而Salt原生是默认的单点Master - Minion结构,其Salt-API也是Daemon方式的裸奔运行,我们踩了很多坑,发现实在是痛的不行,鄙人向领导反馈了这一严重隐患,终于也就有了这样的一次折腾。
 
至今,我们研究的成果已经推广到了生产环境,虽然它还是有很多的问题,然而之所以写下这篇博客,实在只是为了聊以纪念一下整个项目团队几个月来的共同努力。

启发

Salt 高可用架构方面的文档和参考案例还是相当稀少的,直到今年(2015)的5月份左右的样子,才看到官方有整理出一篇高可用相关的文档:http://docs.saltstack.com/en/latest/topics/highavailability/index.html
 
而这里面讲的也还是比较宽泛,可以选择的架构以及对应的优缺点信息都比较稀少。好在开源大牛们从来都不缺乏分享的精神,鄙人挖了一下SaltConf15上一些成功的案例分享,最主要的当然是Linkedin的Thomas Jackson大牛的分享,最终通过反复研究,有些收获(期间多亏Kenny的几次指点,真的非常感谢)。
 
MultiSyndic、MultiMaster、Failover Minion、Ext Job Cache
我们这边最后采用的架构采用了MultiSyndic + MultiMaster + Failover Minion这几个salt原生的重要特性,为了不让读者们困惑,这里先首先讲解下这几个特性。

MultiSyndic

MultiSyndic 是 2014.7版本以后才引入的一个重要特性,它使得SYndic架构变得更加灵活,即一台SYndic可以同时被多台MOfM管理(你可以理解为MultiSyndic的MultiMaster),官方文档这方面做的还不是很完善,只是简单的介绍了一下该如何配置,大家可以看看:https://docs.saltstack.com/en/latest/topics/topology/syndic.html。
 
具体的源码则是放到了minion.py的这一块,本身原理便是MultiSYndic会去复用一些Syndic的功能,然后做一些转发的处理。
 
MultiSyndic的配置其实有点综合MultiMaster,你需要设置syndic本身的一些配置,包括每台syndic设置syndic_master为一个list mofm,另外Key等文件做共享配置,其次写入一些必要的syndic本身的配置,由于过于细节,这里不再赘述。

Failover Minion(Or MultiMinion)

Failover Minion 则是Salt引入的一个Minion端实现的特性,它允许minion定期的去探测当前master的存活性,一旦发现master不可用,可以在一定时间内做出切换,从而提高整体服务调用的可用性,具体的配置文档也可以参见官方文档,需要注意的是配置MultiMaster 亦或是 MultiMaster PKI都可以使用failover特性,这一点已经由官方强调过,minion配置内容如下:# multi-master
master:
- 172.16.0.10
- 172.16.0.11
- 172.16.0.12

# 设置为failover minion
master_type: failover

# 设置启动时随机选择一台master
master_shuffle: True

# 探测master是否存活的schedule job
# 即使用salt schedule特性实现的功能
master_alive_interval: <seconds>

Ext Job Cache

如何分解出master的压力?一方面,可以做负载均衡,将minion分散到不同的Master去管理,另外一方面,跑salt-job的主要需求还是获取job结果,为了减轻查询结果方面的压力,也为了提高整体架构的并发能力,鄙人推荐了引入ext job cache的特性。

实际上,使用ext_job_cache配置搭配合适的returner便可以让salt-master默认将job数据写入到指定的存储,然而这样带来的坏处是一旦你存储的组件挂掉了,比如配的redis returner,redis一旦挂掉,那么job便根本无法下发(因为job下发的时候便会将job load写入到cache,即这次job的执行参数和命中的具体minion数据),为了规避这一个坑,鄙人改造了绿肥同学基于Salt Event系统构建Master端returner这篇博客里讲解的监听event并写入job数据的方案,通过配置额外的服务来实现了ext job cache的写入。

几种高可用架构的选择

OK,至此,我们已经了解了一些基本的Salt原生提供的高可用特性,接下来,鄙人将为您分享我个人认为不同的量级和场景下推荐的Salt高可用架构方案。

备注:这里统一建议一下salt-master的配置性能,我个人之前使用的salt-master是2C6G的低配虚拟机,踩了非常多的坑,包括Auth风暴等等,1k台机器之后使用起来体验也相当糟糕,所以个人建议salt-master配置至少> 8C的计算能力~
 
方案1: Single Master With Warm Backup适用场景:< 1k Minion的小规模应用
Salt版本限制:印象中至少0.17已经支持了这个特性

问题:我个人也没有在生产具体应用过该架构,但是
SaltConf15上已有这样的用例,应该是完备的一方案~Salt 原生支持salt-master指向配置成DNS域名,它会通过resolv_dns函数来解析具体的master ip,所以在minion发现与master中断后,它会尝试和master重新连接,而可以通过重新解析DNS来实现Master的切换。
 
方案2:MultiMaster适用场景: 1k ~ 4k,调用强度集中于小规模机器鄙人也和几位业内的运维交流了salt的一些心得,应该目前来说,MultiMaster算是最常见的应用架构,它足够的简单,并且Salt原生的支持也相对比较成熟,个人也推荐在中等规模及一般使用的情况下可以使用这样的一个架构来满足需求。
 
方案3:MultiMaster + MultiSYndic + FailoverMinion(linkedin分享的架构#5)适用场景:并发调用强度相对较高,并且分多套salt各自维护(比如UAT和PROD不是一个团队的人来维护这样一个情况),
对于salt服务的SLA以及性能方面有较高要求的场景,机器数量方面可以通过横向扩展来解决,
一般来说,建议 ~10k 及以上的规模采用此架构方案(并且鄙人尝试配置过官方原生的这个架构,
貌似有很多的坑,我们这边是通过修改了MultiSyndic的部分代码才使得整体架构可用)话不多说,一图胜千言,实际上,我们内部用的就是linkedin分享的第5套架构,可能有人会问,为啥不用第6套架构呢? 我个人测试过,第6套架构是可行的,但是貌似只能跑两台master互为master\syndic,一旦配成三台便会出现event loop,这个我们内部分析过,应该是一个合理的逻辑,不知道为啥linkedin最终是推荐的这个架构?




采用这一架构的话,首先一点,我们可以在MofM这一层架设Salt-API,并设置负载均衡,这样一来的话,能实现API这一层的负载均衡及横向扩展。另外一方面,MultiSyndic这一层,由于每台minion实际一个时刻只由一台SYndic Master管理,因此Syndic Master的压力被分散到了每台机器上,再者,MofM由于可以和所有的SYndic通信,因而上层的Salt-API可以ping通全量的Minion!值得补充的是,我们将syndic的job event额外吐到了统一的redis job cache,这样一来,通过调整salt api的调用方式(从同步改成异步),即可极大的减轻Master的负载,将压力均摊到了redis cache(减少了大量的find_job任务,当然,问题即在于你必须给出一个大致的超时时间,因为问询salt-minion是否完成的逻辑改成了query job cache,所以无法感知minion实际是否真的在执行与否)。

如此一来,即实现了负载均衡 + 高可用 + 可横向扩展的Salt架构方案!Success!

当前架构的利与弊

通过生产环境的线上实际体验,我们也获知了我们当前采取的#5架构的一些具体的利弊所在,不敢私藏,在此分享一二。
利:这一架构的优势在于高并发的爆发能力和可扩展的负载均衡能力。

首先,我们用nginx + UWSGI将salt-api封装了一层,使得其并发能力和稳定性有了一定的提高。

另外, 这个架构下,上层MofM只负责下发Job并且可以横向扩展,这便实现了强大的API高并发的可能,另外, Syndic每台管理1/n的minion机器,相对的负载被分散到了各台机器上,理论上来说它可以支撑的minion机器规模是足够数量级的。弊:诶,这个架构目前的劣势也是相当的明显,成也MultiSyndic,败也MultiSyndic, Syndic的逻辑是处理完结果后会把job数据回吐给MofM,而MofM理论上是可以ping通所有minion的,所以一旦执行类似Salt * test.ping命令的时候,MofM就等于承受了一次短时间的数据流量的冲击,所有Syndic会在短时间内把job result回吐给MofM,1w台minion便是1w条minion job数据,再加上find_job任务,后果不堪设想..

因此,我们如今也在推动整改成异步调用的方式,并且也在思考如何优化这一层的处理,实际上,用户如何使用也是一个很大的哲学。

结语

这篇文章是鄙人今天整理这几个月的感受仓促而成,很多的细节还没有完全的揭露,实际上,生产环境的线上考验仍然不够充分,然而,毕竟还是完成了一个小小的milestone,写出这篇文章,也是为了分享一下个人的踩坑记。Salt的确很坑,有很多的问题, 但是,在决定使用它并将其作为基础架构组件的情况下,抱怨变得毫无意义,如何有方法的具体的去实施,去解决问题才是我们实际需要考虑的事情。

在这几个月的过程中,从最开始的茫然,焦躁,到在Kenny带领下研究架构的方案,再到找上Dingw大哥一起研究和改动MultiSYndic的代码,实在是成长了很多,多亏了几位大哥的帮扶,尤其是Kenny, Dingw,Bshu, JY 几位大哥,在架构和代码二次开发方面出了很多力气,鄙人也算是在几位大哥的carry下算是一起完成了这件事情罢。目前,只是完成了新架构的生产切换,未来可能还会有很多的挑战,鄙人很遗憾后续无法更多的参与,但是很感恩与团队里的同事们一起攻克问题的这几个月的经历。

这个架构是否可以完全适应我们公司内部的使用也有待进一步的考验,也相信我们项目团队会进一步的优化和改善Salt的使用,最终促成一个健壮的Salt基础架构组件服务!!

分享原文作者:jacky
分享原文地址:http://devopstarter.info/saltstack-ha-arch/ 查看全部


起因


鄙人折腾Salt也已经一年有余了,从最开始Linux运维的基础知识,包括啥叫配置管理都一无所知,事到如今好歹也做了一些事情,虽然没啥功劳,也埋了一些坑,但是总归在自动化方面贡献了一些微薄的力量。

为什么要搞Salt高可用架构呢? 起因是因为公司内部对于Salt的要求从工具上升到了基础架构组件的层面,要求在响应时间和服务可用性方面有一些更高的要求,简单来说,就是内部的一些重要组件依赖于它来完成一些事情。而Salt原生是默认的单点Master - Minion结构,其Salt-API也是Daemon方式的裸奔运行,我们踩了很多坑,发现实在是痛的不行,鄙人向领导反馈了这一严重隐患,终于也就有了这样的一次折腾。
 
至今,我们研究的成果已经推广到了生产环境,虽然它还是有很多的问题,然而之所以写下这篇博客,实在只是为了聊以纪念一下整个项目团队几个月来的共同努力。


启发


Salt 高可用架构方面的文档和参考案例还是相当稀少的,直到今年(2015)的5月份左右的样子,才看到官方有整理出一篇高可用相关的文档:http://docs.saltstack.com/en/latest/topics/highavailability/index.html
 
而这里面讲的也还是比较宽泛,可以选择的架构以及对应的优缺点信息都比较稀少。好在开源大牛们从来都不缺乏分享的精神,鄙人挖了一下SaltConf15上一些成功的案例分享,最主要的当然是Linkedin的Thomas Jackson大牛的分享,最终通过反复研究,有些收获(期间多亏Kenny的几次指点,真的非常感谢)。
 
MultiSyndic、MultiMaster、Failover Minion、Ext Job Cache
我们这边最后采用的架构采用了MultiSyndic + MultiMaster + Failover Minion这几个salt原生的重要特性,为了不让读者们困惑,这里先首先讲解下这几个特性。


MultiSyndic


MultiSyndic 是 2014.7版本以后才引入的一个重要特性,它使得SYndic架构变得更加灵活,即一台SYndic可以同时被多台MOfM管理(你可以理解为MultiSyndic的MultiMaster),官方文档这方面做的还不是很完善,只是简单的介绍了一下该如何配置,大家可以看看:https://docs.saltstack.com/en/latest/topics/topology/syndic.html
 
具体的源码则是放到了minion.py的这一块,本身原理便是MultiSYndic会去复用一些Syndic的功能,然后做一些转发的处理。
 
MultiSyndic的配置其实有点综合MultiMaster,你需要设置syndic本身的一些配置,包括每台syndic设置syndic_master为一个list mofm,另外Key等文件做共享配置,其次写入一些必要的syndic本身的配置,由于过于细节,这里不再赘述。


Failover Minion(Or MultiMinion)


Failover Minion 则是Salt引入的一个Minion端实现的特性,它允许minion定期的去探测当前master的存活性,一旦发现master不可用,可以在一定时间内做出切换,从而提高整体服务调用的可用性,具体的配置文档也可以参见官方文档,需要注意的是配置MultiMaster 亦或是 MultiMaster PKI都可以使用failover特性,这一点已经由官方强调过,minion配置内容如下:
# multi-master
master:
- 172.16.0.10
- 172.16.0.11
- 172.16.0.12

# 设置为failover minion
master_type: failover

# 设置启动时随机选择一台master
master_shuffle: True

# 探测master是否存活的schedule job
# 即使用salt schedule特性实现的功能
master_alive_interval: <seconds>


Ext Job Cache


如何分解出master的压力?一方面,可以做负载均衡,将minion分散到不同的Master去管理,另外一方面,跑salt-job的主要需求还是获取job结果,为了减轻查询结果方面的压力,也为了提高整体架构的并发能力,鄙人推荐了引入ext job cache的特性。

实际上,使用ext_job_cache配置搭配合适的returner便可以让salt-master默认将job数据写入到指定的存储,然而这样带来的坏处是一旦你存储的组件挂掉了,比如配的redis returner,redis一旦挂掉,那么job便根本无法下发(因为job下发的时候便会将job load写入到cache,即这次job的执行参数和命中的具体minion数据),为了规避这一个坑,鄙人改造了绿肥同学基于Salt Event系统构建Master端returner这篇博客里讲解的监听event并写入job数据的方案,通过配置额外的服务来实现了ext job cache的写入。


几种高可用架构的选择


OK,至此,我们已经了解了一些基本的Salt原生提供的高可用特性,接下来,鄙人将为您分享我个人认为不同的量级和场景下推荐的Salt高可用架构方案。

备注:这里统一建议一下salt-master的配置性能,我个人之前使用的salt-master是2C6G的低配虚拟机,踩了非常多的坑,包括Auth风暴等等,1k台机器之后使用起来体验也相当糟糕,所以个人建议salt-master配置至少> 8C的计算能力~
 
方案1: Single Master With Warm Backup
适用场景:< 1k Minion的小规模应用
Salt版本限制:印象中至少0.17已经支持了这个特性

问题:我个人也没有在生产具体应用过该架构,但是
SaltConf15上已有这样的用例,应该是完备的一方案~
Salt 原生支持salt-master指向配置成DNS域名,它会通过resolv_dns函数来解析具体的master ip,所以在minion发现与master中断后,它会尝试和master重新连接,而可以通过重新解析DNS来实现Master的切换。
 
方案2:MultiMaster
适用场景: 1k ~ 4k,调用强度集中于小规模机器
鄙人也和几位业内的运维交流了salt的一些心得,应该目前来说,MultiMaster算是最常见的应用架构,它足够的简单,并且Salt原生的支持也相对比较成熟,个人也推荐在中等规模及一般使用的情况下可以使用这样的一个架构来满足需求。
 
方案3:MultiMaster + MultiSYndic + FailoverMinion(linkedin分享的架构#5)
适用场景:并发调用强度相对较高,并且分多套salt各自维护(比如UAT和PROD不是一个团队的人来维护这样一个情况),
对于salt服务的SLA以及性能方面有较高要求的场景,机器数量方面可以通过横向扩展来解决,
一般来说,建议 ~10k 及以上的规模采用此架构方案(并且鄙人尝试配置过官方原生的这个架构,
貌似有很多的坑,我们这边是通过修改了MultiSyndic的部分代码才使得整体架构可用)
话不多说,一图胜千言,实际上,我们内部用的就是linkedin分享的第5套架构,可能有人会问,为啥不用第6套架构呢? 我个人测试过,第6套架构是可行的,但是貌似只能跑两台master互为master\syndic,一旦配成三台便会出现event loop,这个我们内部分析过,应该是一个合理的逻辑,不知道为啥linkedin最终是推荐的这个架构?
salt_arch.png

采用这一架构的话,首先一点,我们可以在MofM这一层架设Salt-API,并设置负载均衡,这样一来的话,能实现API这一层的负载均衡及横向扩展。另外一方面,MultiSyndic这一层,由于每台minion实际一个时刻只由一台SYndic Master管理,因此Syndic Master的压力被分散到了每台机器上,再者,MofM由于可以和所有的SYndic通信,因而上层的Salt-API可以ping通全量的Minion!值得补充的是,我们将syndic的job event额外吐到了统一的redis job cache,这样一来,通过调整salt api的调用方式(从同步改成异步),即可极大的减轻Master的负载,将压力均摊到了redis cache(减少了大量的find_job任务,当然,问题即在于你必须给出一个大致的超时时间,因为问询salt-minion是否完成的逻辑改成了query job cache,所以无法感知minion实际是否真的在执行与否)。

如此一来,即实现了负载均衡 + 高可用 + 可横向扩展的Salt架构方案!Success!


当前架构的利与弊


通过生产环境的线上实际体验,我们也获知了我们当前采取的#5架构的一些具体的利弊所在,不敢私藏,在此分享一二。
利:
这一架构的优势在于高并发的爆发能力和可扩展的负载均衡能力。

首先,我们用nginx + UWSGI将salt-api封装了一层,使得其并发能力和稳定性有了一定的提高。

另外, 这个架构下,上层MofM只负责下发Job并且可以横向扩展,这便实现了强大的API高并发的可能,另外, Syndic每台管理1/n的minion机器,相对的负载被分散到了各台机器上,理论上来说它可以支撑的minion机器规模是足够数量级的。
弊:
诶,这个架构目前的劣势也是相当的明显,成也MultiSyndic,败也MultiSyndic, Syndic的逻辑是处理完结果后会把job数据回吐给MofM,而MofM理论上是可以ping通所有minion的,所以一旦执行类似Salt * test.ping命令的时候,MofM就等于承受了一次短时间的数据流量的冲击,所有Syndic会在短时间内把job result回吐给MofM,1w台minion便是1w条minion job数据,再加上find_job任务,后果不堪设想..

因此,我们如今也在推动整改成异步调用的方式,并且也在思考如何优化这一层的处理,实际上,用户如何使用也是一个很大的哲学。


结语


这篇文章是鄙人今天整理这几个月的感受仓促而成,很多的细节还没有完全的揭露,实际上,生产环境的线上考验仍然不够充分,然而,毕竟还是完成了一个小小的milestone,写出这篇文章,也是为了分享一下个人的踩坑记。Salt的确很坑,有很多的问题, 但是,在决定使用它并将其作为基础架构组件的情况下,抱怨变得毫无意义,如何有方法的具体的去实施,去解决问题才是我们实际需要考虑的事情。

在这几个月的过程中,从最开始的茫然,焦躁,到在Kenny带领下研究架构的方案,再到找上Dingw大哥一起研究和改动MultiSYndic的代码,实在是成长了很多,多亏了几位大哥的帮扶,尤其是Kenny, Dingw,Bshu, JY 几位大哥,在架构和代码二次开发方面出了很多力气,鄙人也算是在几位大哥的carry下算是一起完成了这件事情罢。目前,只是完成了新架构的生产切换,未来可能还会有很多的挑战,鄙人很遗憾后续无法更多的参与,但是很感恩与团队里的同事们一起攻克问题的这几个月的经历。

这个架构是否可以完全适应我们公司内部的使用也有待进一步的考验,也相信我们项目团队会进一步的优化和改善Salt的使用,最终促成一个健壮的Salt基础架构组件服务!!


分享原文作者:jacky
分享原文地址:http://devopstarter.info/saltstack-ha-arch/


CentOS部署 salt报错

运维技术Ansible 回复了问题 • 2 人关注 • 1 个回复 • 1000 次浏览 • 2015-08-21 21:05 • 来自相关话题

CentOS部署 salt报错

回复

运维技术Ansible 回复了问题 • 2 人关注 • 1 个回复 • 1000 次浏览 • 2015-08-21 21:05 • 来自相关话题

SaltStack RESTful API的调用

运维技术chris 发表了文章 • 0 个评论 • 843 次浏览 • 2016-04-27 21:15 • 来自相关话题

如果需要通过第三方来调用SaltStack时,使用SaltStack自带的Python API并不能很好的满足需求。可以通过使用SaltStack基于RESTful风格的HTTP API。该API模块并不是内置的,需要单独安装。

Salt REST API简介
这里简单的说明下,SaltStack官方支持三种REST API,分别是rest_cherry; rest_tonado和rest_wsgi
[]rest_cherry和rest_tonado两个模块支持监听所有IP的指定端口接收请求[/]
shell> lsof -i:1559
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
salt-api 13443 root 14u IPv4 21888585 0t0 TCP *:web2host (LISTEN)

[]rest_wsgi只支持本机访问,只绑定了127.0.0.1[/]
shell> lsof -i:1559
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
salt-api 13443 root 14u IPv4 21888585 0t0 TCP 127.0.0.1:web2host (LISTEN)



本文选择使用rest_cherry模块来实现SaltStack的HTTP API
 
安装Salt-API服务
一般情况下,salt-api会使用HTTPS,首次配置成功后,使用用户名和密码登陆,获得Token,Token创建后,默认有效期是12小时,在有效期之内,使用该Token可以代替使用用户名和密码来访问API(该有效时间可在salt-master配置文件中修改)
 
必备安装包
shell> yum -y install gcc make python-devel libffi-devel
shell> pip install pyOpenSSL==0.15.1借助salt工具来生成证书​
shell> salt-call --local tls.create_self_signed_cert
local:
Created Private Key: "/etc/pki/tls/certs/localhost.key." Created Certificate: "/etc/pki/tls/certs/localhost.crt."alt-call是salt-minion的工具,如果没有这个命令,可以在master端安装minion,然后再执行以上命令
 
安装salt-api
shell> yum -y install salt-api配置用户及权限
shell> useradd -M -s /sbin/nologin sa
shell> echo "sapassword" | passwd sa --stdin在salt-master的配置文件最后添加如下配置
external_auth:
pam: #认证模式,pam指的是用Linux本身的用户认证模式
sa: #Linux系统中真实存在的用户名
- '[i]': #设置用户的权限,允许该用户操作哪些主机,[/i]代表全部
- test.* #允许操作的模块及方法
- cmd.*其他认证模式可以参考官方文档:http://docs.saltstack.com/en/latest/topics/eauth/index.html​
 
配置示例一:多用户(官方文档)
external_auth:
pam:
thatch:
- 'web*':
- test.*
- network.*
steve:
- .*配置示例二:指定用户组(官方文档)
external_auth:
pam:
admins%:
- '*':
- 'pkg.*'使用%来表示用户组
 
配置示例三:操作模块组(官方文档)
external_auth:
pam:
thatch:
- '@wheel' # to allow access to all wheel modules
- '@runner' # to allow access to all runner modules
- '@jobs' # to allow access to the jobs runner and/or wheel module查看wheel modules完整列表         查看runner modules完整列表
 
配置salt-api服务
在salt-master的配置文件最后添加如下配置
rest_cherrypy:
port: 1559 #默认监听所有IP的1559端口
ssl_crt: /etc/pki/tls/certs/localhost.crt #引用的正是前面创建的证书
ssl_key: /etc/pki/tls/certs/localhost.key其他配置参数可以参考官方文档:https://docs.saltstack.com/en/latest/ref/netapi/all/salt.netapi.rest_cherrypy.html
 
启动服务
shell> service salt-api start登陆获得Token
url -sSk https://www.20150509.cn:1559/login \
-H 'Accept: application/x-yaml' \
-d username=sa \
-d password=sapassword \
-d eauth=pam复制得到的Token
curl -sSk https://localhost:8000 \
-H 'Accept: application/x-yaml' \
-H 'X-Auth-Token: 697adbdc8fe971d09ae4c2a3add7248859c87079'\
-d client=local \
-d tgt='*' \
-d fun=test.ping除了支持Token以外还支持使用cookies.txt文件来访问API,详情可查看官方文档
 
使用Python脚本来访问API
在salt-api官方文档中,对python访问API给出了如下的格式要求
[{
"client": "local",
"tgt": "*",
"fun": "test.fib",
"arg": ["10"]
},
{
"client": "runner",
"fun": "jobs.lookup_jid",
"jid": "20130603122505459265"
}]以上的JSON代码中,指定了API去执行两个命令,一个模块命令,一个runner命令。Python代码实现如下:
import json
import urllib
import urllib2

#在python2.6x中,以下两行不是必须的
import ssl
ssl._create_default_https_context = ssl._create_unverified_context

url='https://www.20150509.cn:1559' #salt-api所在的“坐标”

def test():
pre_data = [{"client":"local", "tgt":"*", "fun":"test.ping"}] #根据上面官方文档的要求组成数组嵌套字典的形式
json_data = json.dumps(pre_data) #将其转化为json格式

header = {"Content-Type":"application/json", "Accept":"application/json", "X-Auth-Token":"697adbdc8fe971d09ae4c2a3add7248859c87079"}
#这里说明下,Content-Type是声明传递给API的数据是什么格式的,这里指定了json,是因为上面的pre_data数据被我转化成了json格式
#Accept是声明返回结果以什么样的格式显示,这里也指定了json格式来显示返回结果

request = urllib2.Request(url, json_data, header) #构造一次请求
response = urllib2.urlopen(request) #构造一次HTTP访问

html = response.read()
print html


if __name__=="__main__":
test()指定Accept为application/json执行结果如下:
shell> python sa.py
{"return": [{"vm3.salt.com": true, "vm2.salt.com": true, "ph1.salt.com": true, "ph2.salt.com": true, "vm1.salt.com": true, "vm4.salt.com": true, "localhost": true, "vm7.salt.com": true}]}
#指定Accept为application/x-yaml执行结果如下:
shell> python sa.py
return:
[list]
[*]localhost: true[/*]
[/list] ph1.salt.com: true
ph2.salt.com: true
vm1.salt.com: true
vm2.salt.com: true
vm3.salt.com: true
vm4.salt.com: true
vm7.salt.com: true参考文档
salt-api:https://github.com/saltstack/salt-api 
rest_cherrypy:https://docs.saltstack.com/en/latest/ref/netapi/all/salt.netapi.rest_cherrypy.html 
认证模式:http://docs.saltstack.com/en/latest/topics/eauth/index.html
分享阅读原文:http://docs.20150509.cn/2016/03/21/SaltStack-RESTful-API%E7%9A%84%E8%B0%83%E7%94%A8-salt-api/ 查看全部


如果需要通过第三方来调用SaltStack时,使用SaltStack自带的Python API并不能很好的满足需求。可以通过使用SaltStack基于RESTful风格的HTTP API。该API模块并不是内置的,需要单独安装。


Salt REST API简介
这里简单的说明下,SaltStack官方支持三种REST API,分别是rest_cherry; rest_tonado和rest_wsgi
    []rest_cherry和rest_tonado两个模块支持监听所有IP的指定端口接收请求[/]

shell> lsof -i:1559
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
salt-api 13443 root 14u IPv4 21888585 0t0 TCP *:web2host (LISTEN)

    []rest_wsgi只支持本机访问,只绑定了127.0.0.1[/]

shell> lsof -i:1559
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
salt-api 13443 root 14u IPv4 21888585 0t0 TCP 127.0.0.1:web2host (LISTEN)
Snip.png

本文选择使用rest_cherry模块来实现SaltStack的HTTP API
 
安装Salt-API服务
一般情况下,salt-api会使用HTTPS,首次配置成功后,使用用户名和密码登陆,获得Token,Token创建后,默认有效期是12小时,在有效期之内,使用该Token可以代替使用用户名和密码来访问API(该有效时间可在salt-master配置文件中修改)
 
必备安装包
shell> yum -y install gcc make python-devel libffi-devel
shell> pip install pyOpenSSL==0.15.1
借助salt工具来生成证书​
shell> salt-call --local tls.create_self_signed_cert
local:
Created Private Key: "/etc/pki/tls/certs/localhost.key." Created Certificate: "/etc/pki/tls/certs/localhost.crt."
alt-call是salt-minion的工具,如果没有这个命令,可以在master端安装minion,然后再执行以上命令
 
安装salt-api
shell> yum -y install salt-api
配置用户及权限
shell> useradd -M -s /sbin/nologin sa
shell> echo "sapassword" | passwd sa --stdin
在salt-master的配置文件最后添加如下配置
external_auth:
pam: #认证模式,pam指的是用Linux本身的用户认证模式
sa: #Linux系统中真实存在的用户名
- '[i]': #设置用户的权限,允许该用户操作哪些主机,[/i]代表全部
- test.* #允许操作的模块及方法
- cmd.*
其他认证模式可以参考官方文档:http://docs.saltstack.com/en/latest/topics/eauth/index.html​
 
配置示例一:多用户(官方文档)
external_auth:
pam:
thatch:
- 'web*':
- test.*
- network.*
steve:
- .*
配置示例二:指定用户组(官方文档)
external_auth:
pam:
admins%:
- '*':
- 'pkg.*'
使用%来表示用户组
 
配置示例三:操作模块组(官方文档)
external_auth:
pam:
thatch:
- '@wheel' # to allow access to all wheel modules
- '@runner' # to allow access to all runner modules
- '@jobs' # to allow access to the jobs runner and/or wheel module
查看wheel modules完整列表         查看runner modules完整列表
 
配置salt-api服务
在salt-master的配置文件最后添加如下配置
rest_cherrypy:
port: 1559 #默认监听所有IP的1559端口
ssl_crt: /etc/pki/tls/certs/localhost.crt #引用的正是前面创建的证书
ssl_key: /etc/pki/tls/certs/localhost.key
其他配置参数可以参考官方文档:https://docs.saltstack.com/en/latest/ref/netapi/all/salt.netapi.rest_cherrypy.html
 
启动服务
shell> service salt-api start
登陆获得Token
url -sSk https://www.20150509.cn:1559/login \
-H 'Accept: application/x-yaml' \
-d username=sa \
-d password=sapassword \
-d eauth=pam
复制得到的Token
curl -sSk https://localhost:8000 \
-H 'Accept: application/x-yaml' \
-H 'X-Auth-Token: 697adbdc8fe971d09ae4c2a3add7248859c87079'\
-d client=local \
-d tgt='*' \
-d fun=test.ping
除了支持Token以外还支持使用cookies.txt文件来访问API,详情可查看官方文档
 
使用Python脚本来访问API
在salt-api官方文档中,对python访问API给出了如下的格式要求
[{
"client": "local",
"tgt": "*",
"fun": "test.fib",
"arg": ["10"]
},
{
"client": "runner",
"fun": "jobs.lookup_jid",
"jid": "20130603122505459265"
}]
以上的JSON代码中,指定了API去执行两个命令,一个模块命令,一个runner命令。Python代码实现如下:
import json
import urllib
import urllib2

#在python2.6x中,以下两行不是必须的
import ssl
ssl._create_default_https_context = ssl._create_unverified_context

url='https://www.20150509.cn:1559' #salt-api所在的“坐标”

def test():
pre_data = [{"client":"local", "tgt":"*", "fun":"test.ping"}] #根据上面官方文档的要求组成数组嵌套字典的形式
json_data = json.dumps(pre_data) #将其转化为json格式

header = {"Content-Type":"application/json", "Accept":"application/json", "X-Auth-Token":"697adbdc8fe971d09ae4c2a3add7248859c87079"}
#这里说明下,Content-Type是声明传递给API的数据是什么格式的,这里指定了json,是因为上面的pre_data数据被我转化成了json格式
#Accept是声明返回结果以什么样的格式显示,这里也指定了json格式来显示返回结果

request = urllib2.Request(url, json_data, header) #构造一次请求
response = urllib2.urlopen(request) #构造一次HTTP访问

html = response.read()
print html


if __name__=="__main__":
test()
指定Accept为application/json执行结果如下:
shell> python sa.py 
{"return": [{"vm3.salt.com": true, "vm2.salt.com": true, "ph1.salt.com": true, "ph2.salt.com": true, "vm1.salt.com": true, "vm4.salt.com": true, "localhost": true, "vm7.salt.com": true}]}
#
指定Accept为application/x-yaml执行结果如下:
shell> python sa.py 
return:
[list]
[*]localhost: true[/*]
[/list] ph1.salt.com: true
ph2.salt.com: true
vm1.salt.com: true
vm2.salt.com: true
vm3.salt.com: true
vm4.salt.com: true
vm7.salt.com: true
参考文档
salt-api:https://github.com/saltstack/salt-api 
rest_cherrypy:https://docs.saltstack.com/en/latest/ref/netapi/all/salt.netapi.rest_cherrypy.html 
认证模式:http://docs.saltstack.com/en/latest/topics/eauth/index.html
分享阅读原文:http://docs.20150509.cn/2016/03/21/SaltStack-RESTful-API%E7%9A%84%E8%B0%83%E7%94%A8-salt-api/

SaltStack介绍和架构解析

运维技术Ansible 发表了文章 • 0 个评论 • 3078 次浏览 • 2015-11-15 21:09 • 来自相关话题

简介

SaltStack是一种新的基础设施管理方法开发软件,简单易部署,可伸缩的足以管理成千上万的服务器,和足够快的速度控制,与他们交流,以毫秒为单位。SaltStack提供了一个动态基础设施通信总线用于编排,远程执行、配置管理等等。SaltStack项目于2011年启动,年增长速度较快,五年期固定基础设施编制和配置管理的开源项目。SaltStack社区致力于保持盐项目集中、友好、健康、开放。 简单来说它的两大基础功能就是:配置管理、远程命令执行。剩下就是根据你的需求自由组合,实现更复杂的功能和系统管理。

SaltStack学习过程

大概步骤如下:
[]安装和配置SaltStack[/][]远程执行命令所有管理系统[/][]设计、开发和部署系统配置[/][]用SaltStack反应器来自动化基础设施[/][]协调使用SaltStack编排复杂的管理操作[/]





SaltStack组件

1、SaltStack  Master
中央管理系统\服务端,这个系统是用来发送命令和配置到SaltStack Minion上运行。




 
2、SaltStack Minion
接受受管理系统\客户端,该系统接收来自SaltStack Master命令和配置。




 
3、执行模块过程
特别对一个或多个命令从命令行执行受管理系统。 适用于:
[]实时监控、状态和库存[/][]一次性命令和脚本[/][]部署关键更新[/]




 
4、规则(States)
声明或命令式表示一个系统的配置。




 
5、Grains
系统变量, Grains是静态信息基础管理系统,包括操作系统、内存和许多其他的系统属性,您还可以定义定制的Grains为任何系统。




 
6、Pillar
用户定义的变量,这些安全变量定义和存储在Salt Master,然后“分配”到一个或多个下属,Pillar数据存储值,文件路径,配置参数,和密码。




 
7、Top File
数据匹配公式




 
8、Runners
模块执行SaltStack Master执行支持任务,Runners报告的工作状态、连接状态读取数据从外部api,查询连接Salt Minions,和更多。
例如,安排Runners在许多系统之间协调配置部署。




 
9、Returners
SaltStack Minion返回的数据发送到另一个系统,如数据库,Returners可以运行在Salt Minion或Salt Minion。




 
10、Reactor
SaltStack环境中触发事件发生时的反应。




 
11、Salt Cloud / Salt Virt
云提供商提供系统/管理程序并立即把他们管理下。




 
12、SaltStack SSH
SaltStack使用ssh运行命令,在没有Salt Minion的情况下。





到这里SaltStack组件和构成架构体系就介绍到这里,还有一些比如高可用没有介绍
参考:docs.saltstack.com 查看全部


简介


SaltStack是一种新的基础设施管理方法开发软件,简单易部署,可伸缩的足以管理成千上万的服务器,和足够快的速度控制,与他们交流,以毫秒为单位。SaltStack提供了一个动态基础设施通信总线用于编排,远程执行、配置管理等等。SaltStack项目于2011年启动,年增长速度较快,五年期固定基础设施编制和配置管理的开源项目。SaltStack社区致力于保持盐项目集中、友好、健康、开放。 
简单来说它的两大基础功能就是:配置管理、远程命令执行。剩下就是根据你的需求自由组合,实现更复杂的功能和系统管理。


SaltStack学习过程


大概步骤如下:
    []安装和配置SaltStack[/][]远程执行命令所有管理系统[/][]设计、开发和部署系统配置[/][]用SaltStack反应器来自动化基础设施[/][]协调使用SaltStack编排复杂的管理操作[/]

saltstack_arch.png


SaltStack组件


1、SaltStack  Master
中央管理系统\服务端,这个系统是用来发送命令和配置到SaltStack Minion上运行。
salt_master.png

 
2、SaltStack Minion
接受受管理系统\客户端,该系统接收来自SaltStack Master命令和配置。
salt_minion.png

 
3、执行模块过程
特别对一个或多个命令从命令行执行受管理系统。 适用于:
    []实时监控、状态和库存[/][]一次性命令和脚本[/][]部署关键更新[/]

remote_execution.png

 
4、规则(States)
声明或命令式表示一个系统的配置。
salt_states.png

 
5、Grains
系统变量, Grains是静态信息基础管理系统,包括操作系统、内存和许多其他的系统属性,您还可以定义定制的Grains为任何系统
salt_grains.png

 
6、Pillar
用户定义的变量,这些安全变量定义和存储在Salt Master,然后“分配”到一个或多个下属,Pillar数据存储值,文件路径,配置参数,和密码。
salt_pillar.png

 
7、Top File
数据匹配公式
salt_topfile.png

 
8、Runners
模块执行SaltStack Master执行支持任务,Runners报告的工作状态、连接状态读取数据从外部api,查询连接Salt Minions,和更多。
例如,安排Runners在许多系统之间协调配置部署。
salt_runners.png

 
9、Returners
SaltStack Minion返回的数据发送到另一个系统,如数据库,Returners可以运行在Salt Minion或Salt Minion。
salt_returners.png

 
10、Reactor
SaltStack环境中触发事件发生时的反应。
salt_reactor.png

 
11、Salt Cloud / Salt Virt
云提供商提供系统/管理程序并立即把他们管理下。
salt_cloud.png

 
12、SaltStack SSH
SaltStack使用ssh运行命令,在没有Salt Minion的情况下。
salt_ssh.png


到这里SaltStack组件和构成架构体系就介绍到这里,还有一些比如高可用没有介绍
参考:docs.saltstack.com


Saltstack高可用架构漫谈

运维技术采菊篱下 发表了文章 • 0 个评论 • 1458 次浏览 • 2015-11-14 11:09 • 来自相关话题

起因

鄙人折腾Salt也已经一年有余了,从最开始Linux运维的基础知识,包括啥叫配置管理都一无所知,事到如今好歹也做了一些事情,虽然没啥功劳,也埋了一些坑,但是总归在自动化方面贡献了一些微薄的力量。

为什么要搞Salt高可用架构呢? 起因是因为公司内部对于Salt的要求从工具上升到了基础架构组件的层面,要求在响应时间和服务可用性方面有一些更高的要求,简单来说,就是内部的一些重要组件依赖于它来完成一些事情。而Salt原生是默认的单点Master - Minion结构,其Salt-API也是Daemon方式的裸奔运行,我们踩了很多坑,发现实在是痛的不行,鄙人向领导反馈了这一严重隐患,终于也就有了这样的一次折腾。
 
至今,我们研究的成果已经推广到了生产环境,虽然它还是有很多的问题,然而之所以写下这篇博客,实在只是为了聊以纪念一下整个项目团队几个月来的共同努力。

启发

Salt 高可用架构方面的文档和参考案例还是相当稀少的,直到今年(2015)的5月份左右的样子,才看到官方有整理出一篇高可用相关的文档:http://docs.saltstack.com/en/latest/topics/highavailability/index.html
 
而这里面讲的也还是比较宽泛,可以选择的架构以及对应的优缺点信息都比较稀少。好在开源大牛们从来都不缺乏分享的精神,鄙人挖了一下SaltConf15上一些成功的案例分享,最主要的当然是Linkedin的Thomas Jackson大牛的分享,最终通过反复研究,有些收获(期间多亏Kenny的几次指点,真的非常感谢)。
 
MultiSyndic、MultiMaster、Failover Minion、Ext Job Cache
我们这边最后采用的架构采用了MultiSyndic + MultiMaster + Failover Minion这几个salt原生的重要特性,为了不让读者们困惑,这里先首先讲解下这几个特性。

MultiSyndic

MultiSyndic 是 2014.7版本以后才引入的一个重要特性,它使得SYndic架构变得更加灵活,即一台SYndic可以同时被多台MOfM管理(你可以理解为MultiSyndic的MultiMaster),官方文档这方面做的还不是很完善,只是简单的介绍了一下该如何配置,大家可以看看:https://docs.saltstack.com/en/latest/topics/topology/syndic.html。
 
具体的源码则是放到了minion.py的这一块,本身原理便是MultiSYndic会去复用一些Syndic的功能,然后做一些转发的处理。
 
MultiSyndic的配置其实有点综合MultiMaster,你需要设置syndic本身的一些配置,包括每台syndic设置syndic_master为一个list mofm,另外Key等文件做共享配置,其次写入一些必要的syndic本身的配置,由于过于细节,这里不再赘述。

Failover Minion(Or MultiMinion)

Failover Minion 则是Salt引入的一个Minion端实现的特性,它允许minion定期的去探测当前master的存活性,一旦发现master不可用,可以在一定时间内做出切换,从而提高整体服务调用的可用性,具体的配置文档也可以参见官方文档,需要注意的是配置MultiMaster 亦或是 MultiMaster PKI都可以使用failover特性,这一点已经由官方强调过,minion配置内容如下:# multi-master
master:
- 172.16.0.10
- 172.16.0.11
- 172.16.0.12

# 设置为failover minion
master_type: failover

# 设置启动时随机选择一台master
master_shuffle: True

# 探测master是否存活的schedule job
# 即使用salt schedule特性实现的功能
master_alive_interval: <seconds>

Ext Job Cache

如何分解出master的压力?一方面,可以做负载均衡,将minion分散到不同的Master去管理,另外一方面,跑salt-job的主要需求还是获取job结果,为了减轻查询结果方面的压力,也为了提高整体架构的并发能力,鄙人推荐了引入ext job cache的特性。

实际上,使用ext_job_cache配置搭配合适的returner便可以让salt-master默认将job数据写入到指定的存储,然而这样带来的坏处是一旦你存储的组件挂掉了,比如配的redis returner,redis一旦挂掉,那么job便根本无法下发(因为job下发的时候便会将job load写入到cache,即这次job的执行参数和命中的具体minion数据),为了规避这一个坑,鄙人改造了绿肥同学基于Salt Event系统构建Master端returner这篇博客里讲解的监听event并写入job数据的方案,通过配置额外的服务来实现了ext job cache的写入。

几种高可用架构的选择

OK,至此,我们已经了解了一些基本的Salt原生提供的高可用特性,接下来,鄙人将为您分享我个人认为不同的量级和场景下推荐的Salt高可用架构方案。

备注:这里统一建议一下salt-master的配置性能,我个人之前使用的salt-master是2C6G的低配虚拟机,踩了非常多的坑,包括Auth风暴等等,1k台机器之后使用起来体验也相当糟糕,所以个人建议salt-master配置至少> 8C的计算能力~
 
方案1: Single Master With Warm Backup适用场景:< 1k Minion的小规模应用
Salt版本限制:印象中至少0.17已经支持了这个特性

问题:我个人也没有在生产具体应用过该架构,但是
SaltConf15上已有这样的用例,应该是完备的一方案~Salt 原生支持salt-master指向配置成DNS域名,它会通过resolv_dns函数来解析具体的master ip,所以在minion发现与master中断后,它会尝试和master重新连接,而可以通过重新解析DNS来实现Master的切换。
 
方案2:MultiMaster适用场景: 1k ~ 4k,调用强度集中于小规模机器鄙人也和几位业内的运维交流了salt的一些心得,应该目前来说,MultiMaster算是最常见的应用架构,它足够的简单,并且Salt原生的支持也相对比较成熟,个人也推荐在中等规模及一般使用的情况下可以使用这样的一个架构来满足需求。
 
方案3:MultiMaster + MultiSYndic + FailoverMinion(linkedin分享的架构#5)适用场景:并发调用强度相对较高,并且分多套salt各自维护(比如UAT和PROD不是一个团队的人来维护这样一个情况),
对于salt服务的SLA以及性能方面有较高要求的场景,机器数量方面可以通过横向扩展来解决,
一般来说,建议 ~10k 及以上的规模采用此架构方案(并且鄙人尝试配置过官方原生的这个架构,
貌似有很多的坑,我们这边是通过修改了MultiSyndic的部分代码才使得整体架构可用)话不多说,一图胜千言,实际上,我们内部用的就是linkedin分享的第5套架构,可能有人会问,为啥不用第6套架构呢? 我个人测试过,第6套架构是可行的,但是貌似只能跑两台master互为master\syndic,一旦配成三台便会出现event loop,这个我们内部分析过,应该是一个合理的逻辑,不知道为啥linkedin最终是推荐的这个架构?




采用这一架构的话,首先一点,我们可以在MofM这一层架设Salt-API,并设置负载均衡,这样一来的话,能实现API这一层的负载均衡及横向扩展。另外一方面,MultiSyndic这一层,由于每台minion实际一个时刻只由一台SYndic Master管理,因此Syndic Master的压力被分散到了每台机器上,再者,MofM由于可以和所有的SYndic通信,因而上层的Salt-API可以ping通全量的Minion!值得补充的是,我们将syndic的job event额外吐到了统一的redis job cache,这样一来,通过调整salt api的调用方式(从同步改成异步),即可极大的减轻Master的负载,将压力均摊到了redis cache(减少了大量的find_job任务,当然,问题即在于你必须给出一个大致的超时时间,因为问询salt-minion是否完成的逻辑改成了query job cache,所以无法感知minion实际是否真的在执行与否)。

如此一来,即实现了负载均衡 + 高可用 + 可横向扩展的Salt架构方案!Success!

当前架构的利与弊

通过生产环境的线上实际体验,我们也获知了我们当前采取的#5架构的一些具体的利弊所在,不敢私藏,在此分享一二。
利:这一架构的优势在于高并发的爆发能力和可扩展的负载均衡能力。

首先,我们用nginx + UWSGI将salt-api封装了一层,使得其并发能力和稳定性有了一定的提高。

另外, 这个架构下,上层MofM只负责下发Job并且可以横向扩展,这便实现了强大的API高并发的可能,另外, Syndic每台管理1/n的minion机器,相对的负载被分散到了各台机器上,理论上来说它可以支撑的minion机器规模是足够数量级的。弊:诶,这个架构目前的劣势也是相当的明显,成也MultiSyndic,败也MultiSyndic, Syndic的逻辑是处理完结果后会把job数据回吐给MofM,而MofM理论上是可以ping通所有minion的,所以一旦执行类似Salt * test.ping命令的时候,MofM就等于承受了一次短时间的数据流量的冲击,所有Syndic会在短时间内把job result回吐给MofM,1w台minion便是1w条minion job数据,再加上find_job任务,后果不堪设想..

因此,我们如今也在推动整改成异步调用的方式,并且也在思考如何优化这一层的处理,实际上,用户如何使用也是一个很大的哲学。

结语

这篇文章是鄙人今天整理这几个月的感受仓促而成,很多的细节还没有完全的揭露,实际上,生产环境的线上考验仍然不够充分,然而,毕竟还是完成了一个小小的milestone,写出这篇文章,也是为了分享一下个人的踩坑记。Salt的确很坑,有很多的问题, 但是,在决定使用它并将其作为基础架构组件的情况下,抱怨变得毫无意义,如何有方法的具体的去实施,去解决问题才是我们实际需要考虑的事情。

在这几个月的过程中,从最开始的茫然,焦躁,到在Kenny带领下研究架构的方案,再到找上Dingw大哥一起研究和改动MultiSYndic的代码,实在是成长了很多,多亏了几位大哥的帮扶,尤其是Kenny, Dingw,Bshu, JY 几位大哥,在架构和代码二次开发方面出了很多力气,鄙人也算是在几位大哥的carry下算是一起完成了这件事情罢。目前,只是完成了新架构的生产切换,未来可能还会有很多的挑战,鄙人很遗憾后续无法更多的参与,但是很感恩与团队里的同事们一起攻克问题的这几个月的经历。

这个架构是否可以完全适应我们公司内部的使用也有待进一步的考验,也相信我们项目团队会进一步的优化和改善Salt的使用,最终促成一个健壮的Salt基础架构组件服务!!

分享原文作者:jacky
分享原文地址:http://devopstarter.info/saltstack-ha-arch/ 查看全部


起因


鄙人折腾Salt也已经一年有余了,从最开始Linux运维的基础知识,包括啥叫配置管理都一无所知,事到如今好歹也做了一些事情,虽然没啥功劳,也埋了一些坑,但是总归在自动化方面贡献了一些微薄的力量。

为什么要搞Salt高可用架构呢? 起因是因为公司内部对于Salt的要求从工具上升到了基础架构组件的层面,要求在响应时间和服务可用性方面有一些更高的要求,简单来说,就是内部的一些重要组件依赖于它来完成一些事情。而Salt原生是默认的单点Master - Minion结构,其Salt-API也是Daemon方式的裸奔运行,我们踩了很多坑,发现实在是痛的不行,鄙人向领导反馈了这一严重隐患,终于也就有了这样的一次折腾。
 
至今,我们研究的成果已经推广到了生产环境,虽然它还是有很多的问题,然而之所以写下这篇博客,实在只是为了聊以纪念一下整个项目团队几个月来的共同努力。


启发


Salt 高可用架构方面的文档和参考案例还是相当稀少的,直到今年(2015)的5月份左右的样子,才看到官方有整理出一篇高可用相关的文档:http://docs.saltstack.com/en/latest/topics/highavailability/index.html
 
而这里面讲的也还是比较宽泛,可以选择的架构以及对应的优缺点信息都比较稀少。好在开源大牛们从来都不缺乏分享的精神,鄙人挖了一下SaltConf15上一些成功的案例分享,最主要的当然是Linkedin的Thomas Jackson大牛的分享,最终通过反复研究,有些收获(期间多亏Kenny的几次指点,真的非常感谢)。
 
MultiSyndic、MultiMaster、Failover Minion、Ext Job Cache
我们这边最后采用的架构采用了MultiSyndic + MultiMaster + Failover Minion这几个salt原生的重要特性,为了不让读者们困惑,这里先首先讲解下这几个特性。


MultiSyndic


MultiSyndic 是 2014.7版本以后才引入的一个重要特性,它使得SYndic架构变得更加灵活,即一台SYndic可以同时被多台MOfM管理(你可以理解为MultiSyndic的MultiMaster),官方文档这方面做的还不是很完善,只是简单的介绍了一下该如何配置,大家可以看看:https://docs.saltstack.com/en/latest/topics/topology/syndic.html
 
具体的源码则是放到了minion.py的这一块,本身原理便是MultiSYndic会去复用一些Syndic的功能,然后做一些转发的处理。
 
MultiSyndic的配置其实有点综合MultiMaster,你需要设置syndic本身的一些配置,包括每台syndic设置syndic_master为一个list mofm,另外Key等文件做共享配置,其次写入一些必要的syndic本身的配置,由于过于细节,这里不再赘述。


Failover Minion(Or MultiMinion)


Failover Minion 则是Salt引入的一个Minion端实现的特性,它允许minion定期的去探测当前master的存活性,一旦发现master不可用,可以在一定时间内做出切换,从而提高整体服务调用的可用性,具体的配置文档也可以参见官方文档,需要注意的是配置MultiMaster 亦或是 MultiMaster PKI都可以使用failover特性,这一点已经由官方强调过,minion配置内容如下:
# multi-master
master:
- 172.16.0.10
- 172.16.0.11
- 172.16.0.12

# 设置为failover minion
master_type: failover

# 设置启动时随机选择一台master
master_shuffle: True

# 探测master是否存活的schedule job
# 即使用salt schedule特性实现的功能
master_alive_interval: <seconds>


Ext Job Cache


如何分解出master的压力?一方面,可以做负载均衡,将minion分散到不同的Master去管理,另外一方面,跑salt-job的主要需求还是获取job结果,为了减轻查询结果方面的压力,也为了提高整体架构的并发能力,鄙人推荐了引入ext job cache的特性。

实际上,使用ext_job_cache配置搭配合适的returner便可以让salt-master默认将job数据写入到指定的存储,然而这样带来的坏处是一旦你存储的组件挂掉了,比如配的redis returner,redis一旦挂掉,那么job便根本无法下发(因为job下发的时候便会将job load写入到cache,即这次job的执行参数和命中的具体minion数据),为了规避这一个坑,鄙人改造了绿肥同学基于Salt Event系统构建Master端returner这篇博客里讲解的监听event并写入job数据的方案,通过配置额外的服务来实现了ext job cache的写入。


几种高可用架构的选择


OK,至此,我们已经了解了一些基本的Salt原生提供的高可用特性,接下来,鄙人将为您分享我个人认为不同的量级和场景下推荐的Salt高可用架构方案。

备注:这里统一建议一下salt-master的配置性能,我个人之前使用的salt-master是2C6G的低配虚拟机,踩了非常多的坑,包括Auth风暴等等,1k台机器之后使用起来体验也相当糟糕,所以个人建议salt-master配置至少> 8C的计算能力~
 
方案1: Single Master With Warm Backup
适用场景:< 1k Minion的小规模应用
Salt版本限制:印象中至少0.17已经支持了这个特性

问题:我个人也没有在生产具体应用过该架构,但是
SaltConf15上已有这样的用例,应该是完备的一方案~
Salt 原生支持salt-master指向配置成DNS域名,它会通过resolv_dns函数来解析具体的master ip,所以在minion发现与master中断后,它会尝试和master重新连接,而可以通过重新解析DNS来实现Master的切换。
 
方案2:MultiMaster
适用场景: 1k ~ 4k,调用强度集中于小规模机器
鄙人也和几位业内的运维交流了salt的一些心得,应该目前来说,MultiMaster算是最常见的应用架构,它足够的简单,并且Salt原生的支持也相对比较成熟,个人也推荐在中等规模及一般使用的情况下可以使用这样的一个架构来满足需求。
 
方案3:MultiMaster + MultiSYndic + FailoverMinion(linkedin分享的架构#5)
适用场景:并发调用强度相对较高,并且分多套salt各自维护(比如UAT和PROD不是一个团队的人来维护这样一个情况),
对于salt服务的SLA以及性能方面有较高要求的场景,机器数量方面可以通过横向扩展来解决,
一般来说,建议 ~10k 及以上的规模采用此架构方案(并且鄙人尝试配置过官方原生的这个架构,
貌似有很多的坑,我们这边是通过修改了MultiSyndic的部分代码才使得整体架构可用)
话不多说,一图胜千言,实际上,我们内部用的就是linkedin分享的第5套架构,可能有人会问,为啥不用第6套架构呢? 我个人测试过,第6套架构是可行的,但是貌似只能跑两台master互为master\syndic,一旦配成三台便会出现event loop,这个我们内部分析过,应该是一个合理的逻辑,不知道为啥linkedin最终是推荐的这个架构?
salt_arch.png

采用这一架构的话,首先一点,我们可以在MofM这一层架设Salt-API,并设置负载均衡,这样一来的话,能实现API这一层的负载均衡及横向扩展。另外一方面,MultiSyndic这一层,由于每台minion实际一个时刻只由一台SYndic Master管理,因此Syndic Master的压力被分散到了每台机器上,再者,MofM由于可以和所有的SYndic通信,因而上层的Salt-API可以ping通全量的Minion!值得补充的是,我们将syndic的job event额外吐到了统一的redis job cache,这样一来,通过调整salt api的调用方式(从同步改成异步),即可极大的减轻Master的负载,将压力均摊到了redis cache(减少了大量的find_job任务,当然,问题即在于你必须给出一个大致的超时时间,因为问询salt-minion是否完成的逻辑改成了query job cache,所以无法感知minion实际是否真的在执行与否)。

如此一来,即实现了负载均衡 + 高可用 + 可横向扩展的Salt架构方案!Success!


当前架构的利与弊


通过生产环境的线上实际体验,我们也获知了我们当前采取的#5架构的一些具体的利弊所在,不敢私藏,在此分享一二。
利:
这一架构的优势在于高并发的爆发能力和可扩展的负载均衡能力。

首先,我们用nginx + UWSGI将salt-api封装了一层,使得其并发能力和稳定性有了一定的提高。

另外, 这个架构下,上层MofM只负责下发Job并且可以横向扩展,这便实现了强大的API高并发的可能,另外, Syndic每台管理1/n的minion机器,相对的负载被分散到了各台机器上,理论上来说它可以支撑的minion机器规模是足够数量级的。
弊:
诶,这个架构目前的劣势也是相当的明显,成也MultiSyndic,败也MultiSyndic, Syndic的逻辑是处理完结果后会把job数据回吐给MofM,而MofM理论上是可以ping通所有minion的,所以一旦执行类似Salt * test.ping命令的时候,MofM就等于承受了一次短时间的数据流量的冲击,所有Syndic会在短时间内把job result回吐给MofM,1w台minion便是1w条minion job数据,再加上find_job任务,后果不堪设想..

因此,我们如今也在推动整改成异步调用的方式,并且也在思考如何优化这一层的处理,实际上,用户如何使用也是一个很大的哲学。


结语


这篇文章是鄙人今天整理这几个月的感受仓促而成,很多的细节还没有完全的揭露,实际上,生产环境的线上考验仍然不够充分,然而,毕竟还是完成了一个小小的milestone,写出这篇文章,也是为了分享一下个人的踩坑记。Salt的确很坑,有很多的问题, 但是,在决定使用它并将其作为基础架构组件的情况下,抱怨变得毫无意义,如何有方法的具体的去实施,去解决问题才是我们实际需要考虑的事情。

在这几个月的过程中,从最开始的茫然,焦躁,到在Kenny带领下研究架构的方案,再到找上Dingw大哥一起研究和改动MultiSYndic的代码,实在是成长了很多,多亏了几位大哥的帮扶,尤其是Kenny, Dingw,Bshu, JY 几位大哥,在架构和代码二次开发方面出了很多力气,鄙人也算是在几位大哥的carry下算是一起完成了这件事情罢。目前,只是完成了新架构的生产切换,未来可能还会有很多的挑战,鄙人很遗憾后续无法更多的参与,但是很感恩与团队里的同事们一起攻克问题的这几个月的经历。

这个架构是否可以完全适应我们公司内部的使用也有待进一步的考验,也相信我们项目团队会进一步的优化和改善Salt的使用,最终促成一个健壮的Salt基础架构组件服务!!


分享原文作者:jacky
分享原文地址:http://devopstarter.info/saltstack-ha-arch/


SaltStack,一种全新的基础设施管理方式,部署轻松,在几分钟内可运行起来,扩展性好,很容易管理上万台服务器,速度够快,服务器之间秒级通讯。