简介
简单介绍
- 一个配置管理系统,能够维护预定义状态的远程节点。(比如,确保指定的软件被安装,指定的服务在运行)
 - 一个分布式远程执行系统,用来在远程节点(可以是单个节点,也可以是任意规则挑选出来的节点)上执行命令和查询数据。
 - 开发其的目的是为:远程执行提供最好的解决方案,并使远程执行变得更好,更快,更简单。
 - SaltStack是使用Python语言开发的,同时提供Rest API方便二次开发以及和其它平台进行集成。
 
参考学习
1  | https://www.cnblogs.com/wangxu01/tag/saltstack/  | 
常用网址
• 官方网站:http://www.saltstack.com
• 官方文档:http://docs.saltstack.com
• GitHub:https://github.com/saltstack
• 中国SaltStack⽤户组:http://www.saltstack.cn
四大功能
- 配置管理
 - 远程执行
 - 云管理
 - 事件驱动
 
基础架构
• Saltstack基于C/S架构
    – 服务端:Master
    – 客户端:Minion
• 可以实现传统处理方式,即:客户端发送请求给服务器,服务器收到请求后处理请求,再将结果返回
• 也可以使用消息队列中的发布与订阅(pub/sub)服务模式

工作原理
- 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库中,locate salt | grep /usr/ 可以看到salt自带的所有东西。
 - 这些模块是python写成的文件,里面会有好多函数,如cmd.run,当我们执行salt ‘*’ cmd.run ‘uptime’的时候,
master下发任务匹配到的minion上去,minion执行模块函数,并返回结果。
master监听4505和4506端口,4505对应的是ZMQ的PUB system,用来发送消息,4506对应的是REP system是来接受消息的。 
运行流程
- Salt stack的Master与Minion之间通过ZeroMq进行消息传递,使用了ZeroMq的发布-订阅模式,连接方式包括tcp,ipc
 - salt命令,将cmd.run ls命令从salt.client.LocalClient.cmd_cli发布到master,获取一个Jobid,根据jobid获取命令执行结果。
 - master接收到命令后,将要执行的命令发送给客户端minion。
 - minion从消息总线上接收到要处理的命令,交给minion._handle_aes处理
 - minion._handle_aes发起一个本地线程调用cmdmod执行ls命令。线程执行完ls后,调用minion._return_pub方法,将执行结果通过消息总线返回给master
 - master接收到客户端返回的结果,调用master._handle_aes方法,将结果写的文件中。
 - salt.client.LocalClient.cmd_cli通过轮询获取Job执行结果,将结果输出到终端。
 
通信端口
master端:4505,4506
minion端:4506
工作方式
- Local
 - Master/Minion
 - Salt SSH
 
- 最传统的运行方式还是C/S模式,管理端安装Master,被管理节点上安装Minion客户端
 
安装和配置
实验环境
• CentOS6 10.0.0.200 linux-node1 master/minion
• CentOS6 10.0.0.201 linux-node2 minion
关闭 Selinux
1  | 查看selinux状态  | 
安装
1  | curl -o /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo  | 
Salt Master安装
1  | [root@linux-node1 yum.repos.d]# yum install -y salt-master salt-minion  | 
Salt Minion安装
1  | [root@linux-node2 ~]# yum install -y salt-minion  | 
启动 salt-master
1  | systemctl start salt-master  | 
查看目录
1  | [root@linux-node1 salt]# pwd  | 
客户端修改配置文件
1  | # 修改minion配置文件:告诉master是谁  | 
启动 salt-minion
1  | systemctl start salt-minion  | 
查看客户端目录
1  | # 客户端启动后创建自己的公钥和私钥  | 
1  | # 客户端ID文件  | 
配置认证 salt-key
- 在启动minion后,会将自己的公钥发送给master
 
1  | [root@linux-node1 pki]# tree /etc/salt/pki/master  | 
- 通过命令同意公钥,让 master 管理 minions
 
1  | # 查看minion salt-key -L  | 
1  | salt-key -A # 同意所有minion  | 
1  | [root@linux-node1 pki]# salt-key -L  | 

- 查看 minion 目录,master 会把公钥发过来
 
1  | [root@linux-node1 pki]# tree /etc/salt/pki/  | 
- 查看 master目录,原来是在 minions_pre 现在到了minions,说明master可以管理
 
1  | [root@linux-node1 pki]# tree /etc/salt/pki/  | 
验证通信
1  | # 返回true为正常  | 

1  | # 如果出现salt '*' test.ping出错Minion did not return. [Not connected]  | 
1  | # 单独验证  | 
查看端口
- 服务端与客户端发送消息 通过 消息队列 zeromq
 - 所有的minion 都连接到 slat的 4505端口上
 
1  | # master  | 
1  | # -n 不做域名解析  | 
1  | # 返回消息 发送给4506  | 
端口开启
1  | # master使用两个端口和minion通信,要确保这两个端口通信正常。  | 
1  | # 可以关闭掉防火墙,或者将端口添加至INPUT链表。  | 
普通用户使用saltstack
修改minion_ID
1  | 停止minion服务  | 
Salt 远程执行命令
基础语法
- 执行salt的基本语法:
 
1  | salt '<target>' <function> [arguments]  | 
1  | # 在所有客户端上执行uptime命令  | 
选择目标
1  | https://docs.saltstack.com/en/latest/topics/targeting/index.html  | 
和 minion_ID 相关的
- 通配符
 
1  | salt '*' test.version  | 
- 正则
 
1  | [root@linux-node1 base]# salt -E 'linux-node(1|2)' test.ping  | 
- 列表
 
1  | salt -L 'linux-node1,linux-node2' test.version  | 
- minion ID设置方案:IP地址、根据业务来进行设置
 
1  | redis-node1 # redis第一个节点  | 
和 minion_ID 无关的
- GRAINS匹配
 
1  | salt -G 'os:CentOS' test.version  | 
- IP地址
 
1  | salt -S 10.0.0.0/24 test.version  | 
- 批处理
 
1  | slat并发改成串行 每次自行10个  | 
执行模块
- 远程执行三大组件
 
1  | 1. 选择目标:通配符、正则、list  | 
1  | 虚拟模块:针对不同的操作系统 调用不同的方法  | 
network
1
2
3salt '*' network.active_tcp
salt '*' network.arp
salt '*' network.connect archlinux.org 8service
1  | # 如果所有的服务器都是统一的操作系统 比如CentOS7 那么可以使用cmd.run 执行命令  | 
- state
 
1  | https://www.unixhot.com/docs/saltstack/ref/modules/all/salt.modules.state.html#module-salt.modules.state  | 
1  | # 常用  | 
Salt 配置管理
YAML
YAML 是一个可读性高,用来表达数据序列化的格式。
在使用YANL编辑配置文件时,需要注意:
- 格式: 两个空格缩进
 - 冒号后面要后空格
 -代表列表,-后面有空格
数据结构可以用类似大纲的缩排方式呈现,结构通过缩进来表示,连续的项目通过减号“-”来表示,
map结构里面的key/value对用冒号“:”来分隔。
样例如下:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15house:
  family:
	name: Doe
	parents:
	  - John
	  - Jane
	children:
	  - Paul
	  - Mark
	  - Simone
  address:
	number: 34
	street: Main Street
	city: Nowheretown
	zipcode: 1234
Salt 状态管理
- 什么叫状态管理
状态是对minion的一种描述和定义,管理人员可以不关心具体部署任务时如何完成的,只需要描述minion要达到什么状态,底层由salt的状态模块来完成功能 
创建状态配置文件目录
- 告诉 master 状态文件放在哪个位置
 
1  | # 编辑master配置文件  | 
- 创建目录
 
1  | [root@linux-node1 ~]# mkdir -p /srv/salt/{base,dev,test,prod}  | 
- 重启master,改完配置就要重启
 
1  | [root@linux-node1 ~]# systemctl restart salt-master  | 
- 查看日志
 
1  | vim /etc/salt/master  | 
简单状态管理 自动化安装apache并启动
- 编写状态文件需要注意
 
1  | 所有的状态文件 都需要以.sls结尾 --> Salt State  | 
- CentOS7 服务管理
 
1  | 1.启动、终止、重启  | 
apache.sls
1  | [root@linux-node1 base]# cd /srv/salt/base/  | 
1  | [root@linux-node1 base]# vim apache.sls  | 
单独执行
1  | # salt '*' state.sls apache  | 
1  | # 去node2看看是否在yum安装httpd  | 
- 查看node1的执行状态
 

1  | # 需要关注的执行状态  | 
- 查看node2上的服务和端口状态
 

- 可以将node2的httpd关闭 再执行测试
 
1  | [root@linux-node2 ~]# systemctl stop httpd  | 

1  | 使用彩色输出时,颜色代码如下:  | 
分类
- 分类
所有的sls文件都存放在base目录下,在生产项目中会相当难找到,所以需要根据软件的功能进行目录分类 
1  | # 创建分类目录  | 
- 多级目录执行
 
1  | # base是基准目录  | 
高级状态管理 top.sls
- 编辑top.sls
如果我们有很多的sls文件,但是这些文件只能单独执行,如果批量执行呢?
这个时候我们可以使用top.sls,他相当于任务编排 
1  | [root@linux-node1 base]# vim /etc/salt/master  | 
1  | # top.sls默认放在base环境下  | 
1  | [root@linux-node1 base]# vim /srv/salt/base/top.sls  | 
- 执行
 
1  | [root@linux-node1 base]# salt '*' state.highstate  | 

常用的状态模块
- 服务的基本要求: 安装、配置、启动
 

pkg
- 功能:管理软件包状态
 - 常用方法:
 
1  | • pkg.installed # 确保软件包已安装. 如果没有安装就安装  | 
- 官方文档:
 
- https://docs.saltstack.cn/ref/states/all/index.html
 - https://docs.saltstack.cn/ref/states/all/salt.states.pkg.html#module-salt.states.pkg
 
1  | # pkg是虚拟模块,在CentOS上调用 yum安装  | 
1  | lamp-install:  | 
file
- 功能:管理文件状态
 - 常用方法:
 
1  | • file.managed # 保证文件存在并且为对应的状态  | 
- 官方文档:
 
1  | name # 在客户端的位置  | 
1  | apache-config:  | 
1  | # 其他模块方法  | 
service
- 功能:管理服务状态
 - 常用方法:
 
1  | • service.running # 确保服务处于运行状态,如果没有行就启动  | 
- 官方文档:
 
1  | httpd-service:  | 
1  | # 执行成功日志  | 

- salt缓存
 
1  | [root@linux-node1 salt]# cd /var/cache/salt/minion/  | 
状态间关系
file.recurse 管理多个配置文件
- 功能: 通过主目录上的子目录递归,并将所述子目录复制到指定的路径
 
1  | httpd管理多个配置文件:  | 
1  | [root@linux-node1 files]# pwd  | 
- 添加管理语句
 
1  | [root@linux-node1 web]# vim lamp.sls  | 
watch 和 watch_in 处理状态之间的关系
- 功能 如果我的配置文件变更,服务就自动reload
 
1  | • watch # 我关注某个状态  | 
1  | # file 是要监控的状态模块 apache-conf 是状态的ID  | 
1  | httpd-service:  | 
- 文件的状态被关注
 
- wacth # 服务关注什么
 - watch_in # 文件被什么所关注
 - 目录有更新 就执行重启
 
1  | apache-conf:  | 

require和 require_in依赖某个状态
- 功能: 比如安装某个软件没有成功,就不往下走了
 
1  | • require # 我依赖某个状态  | 
- lamp-install 如果安装不成功,就不会向下执行
 
1  | apache-config:  | 
unless 状态判断
添加info.php页面
1  | [root@linux-node2 conf]# cd /var/www/html/  | 
访问admin的时候输入用户名和密码
1  | [root@linux-node2 admin]# vim /etc/httpd/conf/httpd.conf  | 
修改状态文件
1  | [root@linux-node1 web]# vim /srv/salt/base/web/files/httpd.conf  | 
1  | # 保证要有用到的命令  | 
状态判断 unless
1  | # 很多命令只需要执行一次,unless 通过判断 0 和 1  | 
1  | apache-auth:  | 
1  | # 执行测试  | 
lamp.sls 最终版
1  | [root@linux-node1 web]# vim lamp.sls  | 
源码安装 Tomcat和 JDK
- 需求:判断minion有没有安装jdk和tomcat,没有就分别源码安装,并以普通用户启动。
 
上传软件包
1  | [root@linux-node1 tools]# pwd  | 
1  | # 安装执行步骤  | 
编写 tomcat.sls
1  | [root@linux-node1 web]# mkdir tools  | 
grains 和 pillar 数据收集

grains 收集静态数据
Grains是saltstack的组件,用于收集salt-minion在启动时候的信息,又称为静态信息。
Grains是服务器的一系列粒子信息,也就是服务器的一系列物理,软件环境信息。
在执行salt的sls时候可以根据Grains信息的不同对服务器进行匹配分组,例如可以根据系统是centos服务器跟系统是redhat环境的安装不同的软件包。
- 功能:
 
- 负责minion第一次启动的时候采集的静态数据,可以用在salt的模块和其他组件中。每次的minion启动(重启)的时候都会采集。
 - 收集资产信息,信息查询
 - 静态数据,当Minion启动的时候收集的MInion本地的相关信息。(包含操作系统版本、内核版本、CPU、内存、硬盘、设备型号等)
备注:不重启minion,这些信息数据是不会改变的。 
1  | Grains可以在state系统中使用,用于配置管理模块  | 
目标选择
1  | # grains 匹配所有CentOS的机器 执行test.ping  | 
信息采集
1  | salt 'linux-node2' grains.ls # 列出ID为linux-node2的主机,grains的所有key  | 
1  | # 需要配置好 vim /etc/hosts 主机名与IP解析  | 
jinja2 模板
1  | 文档:http://docs.jinkan.org/docs/jinja2/  | 
使用 jinja2 和 grains
- 修改配置文件httpd 本机IP:PORT
 
1  | [root@linux-node1 web]# vim lamp.sls  | 
1  | [root@linux-node1 web]# vim files/httpd.conf  | 
1  | [root@linux-node1 web]# salt 'linux-node2' state.sls web.lamp  | 


日常管理
生产建议
1  | 1. 不建议使用salt的FILE模块进行代码部署  | 
include
- 功能:有时候我们写了很多的sls文件,这些文件可以被复用
 
备份
1  | [root@linux-node1 salt]# zip -r base.zip base/  | 
复制lamp中安装部分,写到httpd.sls里面
1  | [root@linux-node1 web]# vim httpd.sls  | 
1  | # 修改lamp.sls,引入  | 
1  | # 执行  | 
常用命令
1  | # 查看状态  | 
无 master 架构
1  | 1. salt本地管理  | 
日志入库 job cache
1  | job cache:  | 
安装mysql,建库建表
1  | [root@linux-node1 base]# yum -y install mariadb mariadb-server mariadb-client  | 
1  | # 建库建表语句  | 
1  | [root@linux-node1 base]# mysql -h 10.0.0.250 -usalt -psalt  | 
安装 MySQL-python
1  | [root@linux-node1 base]# yum install -y MySQL-python  | 
配置 master
1  | [root@linux-node1 base]# vim /etc/salt/master  | 
1  | # 重启服务  | 
执行 test.ping 查看cache 是否入库
1  | [root@linux-node1 base]# salt '*' test.ping  | 
1  | # 显示 jid 执行  | 

kill salt 正在执行的任务
1  | https://www.cnblogs.com/shhnwangjian/p/6048891.html  | 
1  | salt '*' saltutil.running # 查看正在运行的任务,找到jid  | 
二次开发建议
1  | 1. master job cache 将所有的job输出保存到mysql  | 
案例实战 zabbix-agent
定义安装目录
1  | [root@linux-node1 base]# mkdir -p init zabbix logstash  | 
init epel源
创建目录获取yum文件
1  | [root@linux-node1 base]# mkdir -p /srv/salt/base/init/files  | 
编写 yum-repo.sls
1  | [root@linux-node1 init]# vim yum-repo.sls  | 
zabbix-agent
模拟安装
1  | [root@linux-node1 files]# yum list|grep zabbix  | 
模板文件
1  | [root@linux-node1 file]# mkdir -p /srv/salt/base/zabbix/file  | 
测试获取主机名
1  | [root@linux-node1 file]# salt '*' grains.item fqdn  | 
编写 zabbix-agent.sls
1  | [root@linux-node1 zabbix]# cd /srv/salt/base/zabbix/  | 
1  | [root@linux-node1 zabbix]# salt 'linux-node2' state.sls zabbix.zabbix-agent test=True  | 

编译安装 redis
创建目录
1  | [root@linux-node1 redis]# mkdir -p /srv/salt/prod/modules/{apache,haproxy,keepalived,mysql,redis}  | 
编辑基础安装文件
1  | [root@linux-node1 redis]# vim redis-install.sls  | 
redis安装
- 根据需求进行安装,可以使单机、主从也可以是集群
 - 只需要导入基础的安装,再进行相应的配置启动就可以了
 - 实现创建好目录和基础配置文件,做好模板
 
1  | [root@linux-node1 redis]# mkdir -p /srv/salt/prod/redis/files  | 
1  | # 模板 比如单机安装的时候我们选择7006为端口  | 
1  | [root@linux-node1 redis]# vim redis-server.sls  | 
1  | # 测试执行  | 

1  | [root@linux-node1 prod]# tree  | 
参考学习
1  | https://github.com/unixhot  | 
salt-ssh
1  | 1.salt-ssh 是 0.17.0 新引入的一个功能,不需要minion对客户端进行管理,也不需要master。  | 
1  | 没有minion如何使用salt,通过salt-ssh  | 
1  | salt-ssh需要一个名单系统来确定哪些执行目标,Salt的0.17.0版本中salt-ssh引入roster系统  | 
安装
1  | # 没有minion如何使用salt,通过salt-ssh,客户端关闭minion  | 
1  | # 定义配置主机: salt-ssh是串行,没有C/S 快  | 
执行
1  | [root@linux-node1 salt]# salt-ssh '*' test.ping -i  | 
总结
1  | 1.salt-ssh 是在salt基础上打了一个python包上传到客户端的默认tmp目录下  | 
salt-api
- 使用条件:1)https调用,或者需要生成证书  2)配置文件 3)使用PAM验证 4)启动salt-api
1
2https://www.unixhot.com/docs/saltstack/topics/api.html
https://www.unixhot.com/docs/saltstack/ref/netapi/all/salt.netapi.rest_cherrypy.html#a-rest-api-for-salt 
安装
1  | [root@linux-node1 salt]# yum install -y salt-api  | 
生成证书
1  | [root@linux-node1 salt]# yum install pyOpenSSL -y  | 
编辑配置文件:
1  | [root@linux-node1 salt]# vim master  | 
1  | [root@linux-node1 master.d]# systemctl restart salt-master  | 
1  | curl -sSk https://10.0.0.251:8000/login \  | 
1  | [root@linux-node1 master.d]# curl -sSk https://10.0.0.251:8000/login \  | 
1  | [root@linux-node1 master.d]# systemctl restart salt-minion  | 
Master高可用
多master
1  | https://www.unixhot.com/docs/saltstack/topics/tutorials/multimaster.html  | 
1  | master 配置文件相同  | 
