当我们服务器数量只有1台,2台,几台时,我们部署软件工具可以逐台登录服务器操作,但随着企业服务器数量不但增多,显然逐台登录部署已经变得不现实。这时自动化运维管理工具就闪亮登场了,目前比较流行的工具有puppet,ansible,saltstack。我曾经使用过ansible和saltstack,当机器数量较多时,ansible执行比saltstack慢很多,今天主要介绍下saltstack。

1. saltstack介绍

saltstack是由python编写的采用c/s架构的自动化运维工具,由master和minion组成,使用ZeroMQ消息队列pub/sub方式通信,使用SSL证书签发的方式进行认证管理,本身是支持多master的。saltstack除了可以通过在节点安装客户端进行管理还支持直接通过ssh进行管理。运行模式为master端下发指令,客户端接收指令执行。采用yaml格式编写配置文件,支持api及自定义python模块,能轻松实现功能扩展。
saltstack有一个saltstack master,而很多saltstack minon在初始化时会连接到该master上。初始化时,minion会交换一个秘钥建立握手,然后建立一个持久的加密的TCP连接。通常,命令起始于master的命令行中,master将命令分发minion上。saltstack master可以同时连接很多minion而无需担心过载,这都归功于ZeroMQ。由于minion和master之间建立了持久化连接,所以master上的命令能很快的到达minion上。minion也可以缓存多种数据,以便加速执行。

2.安装过程

2.1 环境准备

机器名称 机器系统 机器ip
saltstack-master centos7.6 10.20.3.10
saltstack-monion1 centos7.6 10.20.3.11
saltstack-monion2 centos7.6 10.20.3.12

2.2 安装saltstack

master机器

1.加载saltstack库和密钥

[root@saltstack-master ~]# yum install -y https://repo.saltstack.com/yum/redhat/salt-repo-latest.el7.noarch.rpm

2.清除缓存

[root@saltstack-master ~]# yum clean expire-cache

3.安装salt-master服务

[root@saltstack-master ~]# yum install -y salt-master

4.启动master服务

[root@saltstack-master ~]#  systemctl enable salt-master
[root@saltstack-master ~]#  systemctl start salt-master

minion机器

1.加载saltstack库和密钥

[root@saltstack-minion1 ~]# yum install -y https://repo.saltstack.com/yum/redhat/salt-repo-latest.el7.noarch.rpm
[root@saltstack-minion2 ~]# yum install -y https://repo.saltstack.com/yum/redhat/salt-repo-latest.el7.noarch.rpm

2.清除缓存

[root@saltstack-minion1 ~]# yum clean expire-cache
[root@saltstack-minion2 ~]# yum clean expire-cache

3.安装salt-minion

[root@saltstack-minion1 ~]# yum install -y salt-minion
[root@saltstack-minion2 ~]# yum install -y salt-minion

4.启动minion

[root@saltstack-minion1 ~]# systemctl enable salt-minion
[root@saltstack-minion1 ~]# systemctl start salt-minion
[root@saltstack-minion2 ~]# systemctl enable stal-minion
[root@saltstack-minion2 ~]# systemctl start salt-minion

服务配置

以下minion配置只以一个讲解,另外一个同理操作
1.master默认在所有网卡监听4505、4506端口,修改配置文件将服务监听在唯一地址

[root@saltstack-master ~]# vim /etc/salt/master
interface: 10.20.3.10
[root@saltstack-master ~]# systemctl restart salt-master

2.修改minion配置文件,加入master地址

[root@saltstack-minion1 ~]# vim /etc/salt/minion
master: 10.20.3.10
[root@saltstack-minion1 ~]# systemctl restart salt-minion

3.建立mater和minion通信秘钥
minion 启动之后会请求 master 为其发送证书,证书签发完成后,表示 master可以加入该 minion

[root@saltstack-master ~]# salt-key -L

saltstack小试牛刀
可以看到两个 minion 客户端已经和服务端建立了联系,并且 master 已经获取了 minion 的公钥,但master还未接受minion的key,正在等待更多进一步有关是否接受该 minion 的指令

使master接受minion的key

[root@saltstack-master ~]# salt-key -a saltstack-minion1
[root@saltstack-master ~]# salt-key -a saltstack-minion2

此时再查看,master已经接受minion的key
saltstack小试牛刀

也可以使用如下命令一次接受所有minion的key
salt-key -A -y

4.简单测试
master ping minion

[root@saltstack-master ~]# salt '*' test.ping

saltstack小试牛刀

查看minion机器负载

[root@saltstack-master ~]# salt '*' cmd.run 'uptime'

saltstack小试牛刀

至此saltstack搭建完毕

3.saltstack使用

3.1 salt常用命令

salt-key 秘钥管理

salt-key -L # 查看所有minion的key状态
salt-key -a <节点id> # 接受某个minion的key
salt-key -A # 接受所有minion的key
salt-key -d <节点id> # 删除某个minion的key
salt-key -D # 删除所有minion的key

salt-run 执行runner函数

salt-run [option] [runner.func]

salt-run manage.status # 查看所有minion的状态
salt-run manage.down # 查看down掉的minion
salt-run manage.up # 查看up的minion

saltstack小试牛刀

salt-cp 分发文件

salt-cp option 'target' source_file dest_file

[root@saltstack-master ~]# salt-cp '*' test.txt /root/
[root@saltstack-master ~]# salt-cp '*' test.txt /root/test1.txt
[root@saltstack-minion1 ~]# ls
test1.txt  test.txt

target 命令作用目标

salt '*' test.ping   # 所有minion
salt '*1' test.ping # 定向匹配
salt -E 'saltstack-(minion1|minion2)' test.ping #正则匹配
salt -L 'saltstack-minion1,saltstack-minion2' test.ping # 列表匹配
salt -G 'os:CentOS' test.ping # grains匹配

saltstack小试牛刀

3.2 cmd模块

saltstack有许多模块,可以使用salt sys.list_modules查看所有模块
saltstack小试牛刀
可以看到模块多达162个之多,每个模块又有多个函数方法。如前面我们测试minion连通性的时候经常用到的test.ping,test就是经常用到的一个模块,而ping是test的一个函数。
这里介绍的cmd模块也是用的比较多的一个模块,cmd也有很多函数,可以使用命令salt sys.lis_functions cmd 列出cmd的所有函数
saltstack小试牛刀

cmd的run函数

run函数可以用来执行shell命令

[root@saltstack-master ~]# salt '*' cmd.run 'free -m'
[root@saltstack-master ~]# salt '*' cmd.run 'uptime'

saltstack小试牛刀

cmd.run使用awk,则$符前面需要加转义符
saltstack小试牛刀

cmd.run可以使用stdin作为标准输入
saltstack小试牛刀

cmd的run_bg函数,可以使程序后台执行

saltstack小试牛刀

cmd的script函数,可以推送脚本并执行

[root@saltstack-master ~]# vim /srv/salt/test.sh
echo "hello.world!"

saltstack小试牛刀

推送带参数的脚本

[root@saltstack-master ~]# vim /srv/salt/test1.sh 
echo $1

saltstack小试牛刀

3.3 cp模块

cp模块可以用来传输文件和目录,前面讲到过salt-cp命令,该命令可以从master推送文件到minion,但是不能传输目录,也不支持从minion。这里讲到的cp模块,支持传输目录,既可以从master推送到minion,也支持从minion拉取到master。
cp模块有很多函数方法,可以使用sys.list_function查看。
saltstack小试牛刀

cp的get_file函数,从master推送文件到minion

创建一个测试文件
[root@saltstack-master ~]# vim /srv/salt/test.txt
hello,world!

saltstack小试牛刀

从master推送文件到minion指定目录时,如果minion目录不存在则会报错,可以加上参数makedis=true解决
saltstack小试牛刀

cp的get_dir函数,从master推送目录到minion

注意推送目录里面必须有文件存在,如果推送空目录时不成功的

创建测试目录
[root@saltstack-master ~]# mkdir /srv/salt/python

saltstack小试牛刀
可以看到推送空目录是不成功的

在python里面创建文件,使目录不为空
[root@saltstack-master ~]# touch /srv/salt/python/{1,2,3}.py
[root@saltstack-master ~]# ls /srv/salt/python/
1.py  2.py  3.py

saltstack小试牛刀

cp的push函数,master从minion拉取文件

默认从minion上拉取是禁用的,需修改配置文件

[root@saltstack-master ~]# vim /etc/salt/master
file_recv: True
[root@saltstack-master ~]# systemctl restart salt-master
在minion1上创建测试文件
[root@saltstack-minion1 ~]# touch yanfa.txt
[root@saltstack-minion1 ~]# touch yunwei.txt
[root@saltstack-minion1 ~]# touch ceshi.txt
[root@saltstack-minion1 ~]# ls
ceshi.txt  yanfa.txt  yunwei.txt
在minion2上创建测试文件
[root@saltstack-minion2 ~]# touch yanfa.txt
[root@saltstack-minion2 ~]# touch yunwei.txt
[root@saltstack-minion2 ~]# touch yunying.txt
[root@saltstack-minion2 ~]# ls
yanfa.txt  yunwei.txt  yunying.txt

saltstack小试牛刀
拉取文件默认保存在/var/cache/salt/master/minions/下面
saltstack小试牛刀

cp的push_dir函数,拉取目录

分别在minion1和minion2上创建测试文件
[root@saltstack-minion1 ~]# mkdir go
[root@saltstack-minion1 ~]# touch go/{a,b,c}.go
[root@saltstack-minion1 ~]# ls go/
a.go  b.go  c.go
[root@saltstack-minion2 ~]# mkdir go
[root@saltstack-minion2 ~]# touch go/{a,b,c}.go
[root@saltstack-minion2 ~]# ls go/
a.go  b.go  c.go

saltstack小试牛刀saltstack小试牛刀
查看可以看到目录和目录里的文件都拉取过来了
saltstack小试牛刀

如果只想拉取目录里的相同类型的文件,而不是拉取整个目录的文件,可以加上glob参数

在minion1和minion2上创建另外一个测试目录
[root@saltstack-minion1 ~]# mkdir python
[root@saltstack-minion1 ~]# touch python/{a,b,c}.py
[root@saltstack-minion1 ~]# touch python/{a,b,c}.txt
[root@saltstack-minion1 ~]# ls python/
a.py  a.txt  b.py  b.txt  c.py  c.txt
[root@saltstack-minion2 ~]# mkdir python
[root@saltstack-minion2 ~]# touch python/{aaa,bbb,ccc}.py
[root@saltstack-minion2 ~]# touch python/{aaa,bbb,ccc}.txt
You have new mail in /var/spool/mail/root
[root@saltstack-minion2 ~]# ls python/
aaa.py  aaa.txt  bbb.py  bbb.txt  ccc.py  ccc.txt

saltstack小试牛刀
可以看到只拉取了.py的文件

3.4 grains模块

该模块采集的是系统的静态信息,包括cpu、操作系统、文件系统、硬盘等
显示所有的minion的grians信息

[root@saltstack-master ~]# salt '*' grains.ls

列出所有的minion的grains详细信息

[root@saltstack-master ~]# salt '*' grains.items

grains使用场景

1.查看各minion的操作系统

[root@saltstack-master ~]# salt '*' grains.item os

saltstack小试牛刀
2.分类查找
如找出cpu架构是x86的机器,查看cpu核数
可以使用-G参数来表示使用grains中变量信息来匹配minion

[root@saltstack-master ~]#  salt -G 'cpuarch:x86_64' grains.item num_cpus

saltstack小试牛刀

可以自定义grains

这里我们自定义minion1的grains
1 修改/etc/salt/minion文件

[root@saltstack-minion1 ~]# vim /etc/salt/minion
grains:
  services:
    - webserver
    - redis
  site: beijing1
  department: yanfa
[root@saltstack-minion1 ~]# systemctl restart salt-minion

这是再在master查看,可以看到我们自己定义的属性
saltstack小试牛刀

2 也可以修改/etc/salt/grains文件

[root@saltstack-minion1 ~]# vim /etc/salt/grains
 services:
   - webserver
   - redis
 site: beijing1
 department: yanfa

3 也可以在master上自己写grains模块

[root@saltstack-master ~]# vim /srv/salt/_grains/test.py
def use():
    useage = {}
    useage['use'] = 'docker'
    return useage
同步到minion上
[root@saltstack-master ~]# salt '*' saltutil.sync_grains

查看
saltstack小试牛刀

master分发的文件可以在minion /var/cache/salt/minion/files/base/ 里看到

3.5 pillar模块

pillar可以指定一些信息发送到指定的minion上,保存的数据可以是动态的,pillar以sls来写,格式是键值对。
不同于grains模块,grains在master是同步到所有minion上,而pillar只同步到指定minion上。
实现一个pillar流程

创建pillar目录
[root@saltstack-master ~]# mkdir /srv/pillar
创建一个pillar数据文件
[root@saltstack-master ~]# vim /srv/pillar/test.sls
pod: '09'
disk: 'ssd'
创建top file文件(指定哪些minion到pillar数据文件,即需要分发的节点)
base:
  'saltstack-minion1':
    - test
刷新pillar数据
[root@saltstack-master ~]# salt '*' saltutil.refresh_pillar

查看,可以看到只有我们指定的minion收到了数据
saltstack小试牛刀

下面在结合grains,利用jinja语法实现另一个pillar流程

创建一个pillar数据文件
[root@saltstack-master ~]# mkdir /srv/pillar/web
[root@saltstack-master ~]# vim /srv/pillar/web/apache.sls
{% if grains['os_family'] == 'RedHat' %}
apache: httpd
{% elif grains['os_family'] == 'RedHat' %}
apache: apache2
{% endif %}
创建top file文件
[root@saltstack-master ~]# vim /srv/pillar/top.sls
base:
  '*':
    - web.apache
刷新pillar数据
[root@saltstack-master ~]# salt '*' saltutil.refresh_pillar

查看,minion1和minion2都为centos系统所有web都是httpd
saltstack小试牛刀

4.参考文档

https://repo.saltstack.com/#rhel