一、saltstack简介
1.saltstack是什么
系统管理员日常会进行大量的重复性操作,例如安装软件,修改配置文件,创建用户,批量执行命令等,如果主机数量庞大,单靠人工维护实在让人难以忍受。
早期运维人员会根据自己的生产环境来写特定脚本完成大量重复性工作,这些脚本复杂且难以维护。系统管理员面临的问题主要是:
系统配置管理
远程执行命令
因此诞生了很多开源软件,系统维护方面有fabric、puppet、chef、ansible、saltstack等,这些软件擅长维护系统状态或方便的对大量主机进行批量的命令执行。
2.saltstack的优势
salt灵活性强大,可以进行大规模部署,也能进行小规模的系统部署。salt的设计架构适用于任意数量的服务器,从少量本地网络系统到跨越数个数据中心,拓扑架构都是c/s模型,配置简单。
不管是几台、几百台、几千台服务器,都可以使用salt在一个中心节点上进行管控,灵活定位任意服务器子集来运行命令。
saltstack是由thomas Hatch于2011年创建的一个开源项目,设计初衷是为了实现一个快速的远程执行系统。
Salt是python编写的,支持用户通过python自定义功能模块,也提供了大量的python API接口,用户可以根据需要进行简单快速的扩展。
3.salt的运行和基本架构
saltstack的运行方式:
Local 本地运行,交付管理
Master/Minion,常用方式
Salt SSH,不需要客户端
saltstack的基本架构
在安装salt之前,先理解salt架构中各个角色,主要区分是salt-master和salt-minion,顾名思义master是中心控制系统,minion是被管理的客户端。
salt架构中的一种就是master > minion
在远程执行系统中,salt用python通过函数调用完成任务。
二、saltstack搭建实战
1.服务器环境准备
1.运行salt有一些依赖包需要安装,分别是python
zeromq
pyzmp
pycrypto
msgpack-python
yaml
jinja2
2.服务器准备
我们准备两个服务器,分别来用作主机和从机
ip地址 | 192.168.16.122 | 1692.168.16.123 |
身份 | master | minion |
软件包 | salt-master | salt-minion |
3.为了能够正确通信,我们配置hosts解析文件,强制进行主机名解析,加速salt的minion查找,分别修改两台服务器上的解析文件。
vim /etc/hosts
# 两个服务器中分别写入如下
192.168.16.122 superdesktop
192.168.16.123 bogon
2.安装saltstack包,配置文件
4.salt软件包需要epel源支持,下载
之前我们已经配好了阿里的yum仓库,直接安装
查看salt包
yum list salt
# 主机上安装
yum install salt-master -y
# 从机上安装
yum install salt-minion -y
5.安装好后,开始配置文件
master服务器中的salt-master
vim /etc/salt/master #打开配置文件,填入如下内容
interface: 0.0.0.0 # 绑定到本地的0.0.0.0地址
publish_port: 4505 # 管理端口,命令发送
user: root #运行salt进程的用户
worker_threads: 5 # salt运行线程数,线程越多处理速度越快,不要超过cpu个数
ret_port: 4506 # 执行结果返回端口
pidfile: /var/run/salt-master.pid # pid文件位置
log_file: /var/log/salt/master # 日志文件地址
#自动接收minion的key
auto_accept: False
minion服务器中的salt-minion
vim /etc/salt/minion
master: superdesktop # 指定mastet的通信地址
master_port: 4506
user: root
id: minion1 # id用于指定minion的身份信息 ,待会可以在master上查看到的
acceptance_wait_time: 10
log_file: /var/log/salt/minion
6.配置好后启动master和minion,查看秘钥的接受情况
salt通信是在minion初次启动的时候,建立新的连接的。
# master服务器
systemctl start salt-master
# minion服务器
systemctl start salt-minion
3.saltstack主机远程操作
master上接受minion秘钥
在minion启动后连接master会请求master为其签发证书,等待证书签发完成后,master可以信任minion,并且minion和master之间的通信是加密的。
在salt-master执行。
salt-key命令用于管理mionion秘钥
[root@superdesktop ~]# salt-key -L
Accepted Keys:
Denied Keys:
Unaccepted Keys:
bogon # 此时已经出现bogon
Rejected Keys:
此时slave已经出现在unaccepted keys中,说明minion已经和master联系,并且master已经获取了minion的公钥,等待下一步指令。
检查秘钥匹配
master执行
[root@superdesktop ~]# salt-key -f bogon
Unaccepted Keys:
bogon: 0a:b9:97:b5:9a:65:b8:49:a1:50:a5:6a:66:ce:33:ea
minion上获取自己的秘钥
[root@bogon ~]# salt-call --local key.finger
local:
0a:b9:97:b5:9a:65:b8:49:a1:50:a5:6a:66:ce:33:ea
master接受minion的秘钥
[root@superdesktop ~]# salt-key -a slave
The following keys are going to be accepted:
Unaccepted Keys:
bogon
Proceed? [n/Y] y
Key for minion bogon accepted.
接受后,可以在次检查minion秘钥是否被接收
[root@superdesktop ~]# salt-key -L
Accepted Keys:
bogon
Denied Keys:
Unaccepted Keys:
Rejected Keys:
salt-key
只有Master接受了Minion Key后,才能进行管理。具体的认证命令为salt-key常用的有如下命令。
[root@superdesktop ~]# salt-key -L
Accepted Keys: # 已经接受的key
Denied Keys: # 拒绝的key
Unaccepted Keys:# 未加入的key
Rejected Keys:# 吊销的key
# 常用参数
-L # 查看KEY状态
-A # 允许所有
-D # 删除所有
-a # 认证指定的key
-d # 删除指定的key
-r # 注销掉指定key(该状态为未被认证)
# 在master端/etc/salt/master配置
auto_accept: True #如果对Minion信任,可以配置master自动接受请求
master远程执行命令
连接好以后,我们就可以愉快的在master上远程执行命令操控minion服务器了。
salt "*" test.ping # 验证salt minion信息是否存活
# 将输出的结果,转化为json信息,可以序列化后,丢给前端渲染
salt "*" test.ping --out=json
salt命令学习
语法:
salt 核心命令
salt 目标从机 你要执行的salt模块
salt命令 参数 目标 salt模块的函数 远程执行的参数
查看salt帮助
salt --help #即可查看salt帮助
常用命令
# 让机器远程返回主机名给我
# 参数解释 --summary显示详细信息
salt --summary '*' cmd.run 'hostname'
cmd超级模块,执行shell命令
# salt的万能模块 cmd.run 代表让minion机器去做些什么事
salt "*" cmd.run "touch /tmp/爱的魔力准quanquan"
salt "*" cmd.run "rm -rf /tmp/*"
# 远程安装软件
#第一个方法 cmd.run
salt "*" cmd.run "yum install nginx -y"
远程安装命令
# salt还提供了更专业的安装软件的命令接口 pkg.install pkg.uninstall就是在调用yum而已
#远程卸载nginx
salt '*' pkg.remove "nginx"
# salt的服务管理模块 service模块,相当于在minion机器上,执行systemctl start nginx
salt '*' service.start "nginx"
salt '*' service.stop "nginx"
salt '*' service.restart "nginx"
#远程安装nginx,并且启动的方式
salt "*" pkg.install 'nginx'
salt "*" service.start 'nginx'
# salt命令的输出格式 有json和yaml两种
# 远程安装redis,并且输出json格式
salt "*" pkg.install "redis" --out=json
salt "*" service.start 'redis' --out=json
salt "*" service.status 'redis' --out=json
4.yaml语法学习
在学习saltstack过程中,第一要点就是States编写技巧,简称SLS文件。这个文件遵循YAML语法。初学者看这玩意很容易懵。
json xml yaml 数据序列化格式,而yaml容易被解析,应用于配置文件
salt的配置文件是yaml配置文件,不能用tab,saltstack,k8s,ansible都用的yaml格式配置文件。
语法规则:
大小写敏感
使用缩进表示层级关系
缩进时禁止tab键,只能空格
缩进的空格数不重要,相同层级的元素左侧对其即可
#
表示注释行
yaml支持的数据结构:
对象: 键值对,也称作映射 mapping 哈希hashes 字典 dict 冒号表示 key: value,key冒号后必须有
数组: 一组按次序排列的值,又称为序列sequence 列表list 短横线 - list1
纯量: 单个不可再分的值
实例演示
yaml
first_key:
second_key:second_value
python
{
'first_key':{
'second_key':'second_value',
}
}
5.state模块定义主机状态
之前执行的远程命令,都是一个过程式的,类似一段shell或者python脚本执行,执行一次触发一次相同的功能。
那么大量的minion上运行远程命令就必须使用salt提供的“状态管理”了,状态是对minion的一种描述和定义,运维不需要关心部署是如何完成的,只需要描述minion需要达到什么状态。
接下来通过state模块部署nginx。
master端
vim /etc/salt/master
# 打开注释,写入以下,必须严格遵循语法,空格
file_roots:
base:
- /srv/salt/base
dev:
- /srv/salt/dev
test:
- /srv/salt/test
prod:
- / srv/salt/prod
# 此步骤在master和minion都需要执行,都需要文件夹,和nginx.sls文件
[root@master ~]$mkdir -p /srv/salt/{base,dev,test,prod}
[root@slave ~]$mkdir -p /srv/salt/{base,dev,test,prod}
这个nginx.sls状态文件,在master和minion上都有
[root@master /srv/salt/base]$cat nginx.sls
nginx-install:
pkg.installed:
- name: nginx
nginx-service:
service.running:
- name: nginx
- enable: True
nginx.sls文件的解释
sls配置文件都遵循YAML语言描述
第一条命令使用了pkg.install安装命令,相对于运行了yum install,而此时state模块会判断nginx是否安装了,如果没有安装就进行安装,安装了就什么都不做。
状态描述都会遵循这个原则,只有检测到真实状态和所需状态不一就会执行此功能,这种性质叫做幂等性。
此时用state模块部署nginx软件,通过我们编写的nginx.sls描述性配置文件,命令行调用state模块的sls函数。
# 启动命令,此时slave已经安装且存活了nginx,进行状态管理
[root@master /srv/salt/base]$salt 'slave' state.sls nginx
可以去slave测试关闭nginx,删除nginx,重新执行命令,一样可以安装启动nginx
通过master检查slave的nginx状态。
[root@master 192.168.199.155 /srv/salt/base]$salt 'slave' cmd.run 'ps -ef|grep nginx'
slave:
root 8543 1 0 Sep14 ? 00:00:00 nginx: master process /usr/sbin/nginx
nginx 8544 8543 0 Sep14 ? 00:00:00 nginx: worker process
root 8592 8591 0 00:03 ? 00:00:00 /bin/sh -c ps -ef|grep nginx
root 8594 8592 0 00:03 ? 00:00:00 /bin/sh -c ps -ef|grep nginx
6.salt采集静态信息之Grains
在工作中,我们可能遇到这种情况,公司领导让你统计300台服务器的相关硬件信息,如果你不会使用salt使用脚本来采集,你是不是的一台台登录查看呢?想起来得有多可怕,我们有更高的办法解决。
Grains 是saltstack组件中非常重要之一,在配置部署时候回经常使用,Grains记录minion的静态信息,比如常用属性,CPU、内存、磁盘、网络信息等。
Minions的Grains信息是Minion启动时采集汇报给Master的 Grains是以 key value形式存储的数据库,可以看做Host的元数据(metadata),Grains保存着收集到的客户端的详细信息
如果slave机器数据变化,grains就过期了,在生产环境中需要自定义Grains,可以通过
Minion配置文件
Grains相关模块定义
Python脚本定义
salt 'slave' sys.doc grains # 查看grains的命令用法
# Grains人为是描述minion本身固有的静态属性数据,列出主机所有Grains数据
[root@master 192.168.16.122 ~]$ salt 'slave' grains.items # 列出所有静态属性
[root@master 192.168.16.122 ~]$ salt 'slave' grains.item os id host # 列出部分静态属性
利用grains静态信息定位主机
# 两种写法:
salt '*' grains.item key1 key2 key3
salt '*' -G
# 定位Cenots的机器
[root@master 192.168.16.122 ~]$salt -G 'os:CentOS' test.ping
slave:
True
# 定位操作系统系统是7系列的机器
[root@master 192.168.16.122 ~]$salt -G 'osrelease:7*' test.ping
slave:
True
# 找出ip地址
salt '*' grains.item fqdn_ip4
因此用grains.items列出所有的数据匹配主机,以及根据单一信息定位数据,Grains还可以自定义来满足不同的需求。
自定义设置grains数据
#设置数据
[root@master 192.168.11.72 ~]$salt 'slave' grains.setval cpu_num 8
slave:
----------
cpu_num:
#查询数据
[root@master 192.168.11.72 ~]$salt 'slave' grains.item cpu_num
slave:
----------
cpu_num:
在master端设置Grains静态数据,原理会将此数据添加到minion服务器的配置文件的/etc/salt/grains
[root@slave 192.168.11.71 ~]$cat /etc/salt/grains
cpu_num: 8
对于复杂的数据结构,可以添加灵活的JSON语法
[root@master 192.168.11.72 ~]$salt 'slave' grains.setval cpu_info '["Intel","Xeon","10"]'
slave:
----------
cpu_info:
- Intel
- Xeon
- 10
[root@master 192.168.11.72 ~]$salt 'slave' grains.item cpu_info
slave:
----------
cpu_info:
- Intel
- Xeon
- 10
此时可以检查minion服务器上的grains文件
[root@slave 192.168.11.71 ~]$cat /etc/salt/grains
cpu_info:
- Intel
- Xeon
- ''
cpu_num: 8
因此Grains数据写入配置文件后,重启salt-minion服务,数据也不会丢失
想要删除可以通过grains.delval命令删除,或者去minion的配置文件删除配置一样完成操作(或者删除文件)
1.方法一,清空值
[root@master 192.168.11.72 ~]$salt 'slave' grains.delval cpu_info
slave:
None
[root@master 192.168.11.72 ~]$salt 'slave' grains.delval cpu_num
slave:
None
2.方法二 删除minion的grains配置文件,重启服务
[root@slave 192.168.11.71 ~]$rm -rf /etc/salt/grains
[root@slave 192.168.11.71 ~]$!sys
systemctl restart salt-minion
# 检查结果删除成功
7.数据管理中心之Pillar组件
Pillar也是saltstack组件中非常重要的组件之一,称作数据管理中心,经常配合states在大规模的配置管理中使用。
Pillar是动态的,存储在master端,提供和给minion端
Pillar在SaltStack中主要的作用是存储和定义配置管理中需要的一些数据,比如软件版本号,用户账号密码等,保证敏感数据不被其他minion看到
存储格式与Grains类似,都是YAML格式1
在master配置文件中有一段Pillar settings选项专门定义Pillar的参数。
cat /etc/salt/master
#此配置代表pillar的工作根目录,在/srv/pillar下,然后可以新建sls文件
#pillar_roots:
# base:
# - /srv/pillar
默认pillar的工作目录在/srv/pillar目录下,执行如下代码
mkdir -p /srv/pillar
# 指定环境,标记,引用packages.sls和services.sls
vim /srv/pillar/top.sls
base:
'*':
- packages
- services
vim /srv/pillar/packages.sls
nginx:
packages-name: nginx
version: 1.12.2
vim /srv/pillar/packages.sls
nginx:
port: 80
user: root
检查我们设置的pillar值
[root@master 192.168.199.155 /srv/pillar]$salt '*' pillar.item nginx
slave:
----------
nginx:
----------
packages-name:
nginx
port:
80
user:
root
version:
1.12.2
pillar和grains对比:
Grains | 静态 | minion启动时收集 数据查询 | 目标选择 配置管理 minion |
Pillar | 动态 | master进行自定义 目标选择 | 配置管理 敏感数据 master |
Python API调用saltstack
SaltStack本身提供salt(usr/bin/salt)来交互管理,但是去服务器上敲命令肯定不是一个长远之计,这时候python就体现了nb的功能。
Python API就是给Python提供的API使用,需要在SaltStack master上运行
实例代码
[root@master ~]$python
Python 2.7.5 (default, Jul 13 2018, 13:06:57)
[GCC 4.8.5 20150623 (Red Hat 4.8.5-28)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import salt.client
>>> local = salt.client.LocalClient() #<salt.client.LocalClient object at 0x7f886dbdd850>
>>> local.cmd('*','cmd.run',['hostname'])#向所有minion发送命令
{'slave': 'slave'}
因此python API就是提供了向saltstack发送命令的入口。
通过API获取saltstack的配置文件
获取master配置文件
>>> import salt.config #导入salt配置模块
>>> m_opts=salt.config.client_config('/etc/salt/master') #读取salt配置文件,得到一个字典数据
获取minion配置文件
Python 2.7.5 (default, Jul 13 2018, 13:06:57)
[GCC 4.8.5 20150623 (Red Hat 4.8.5-28)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import salt.client
>>> salt.config.minion_config('/etc/salt/minion') #读取minion配置文件,得到字典数据,通过字典方法可以查看信息
Python API介绍
/usr/bin/salt默认使用的接口是LocalClient,该接口只能在salt master上使用
[root@master ~]$python
Python 2.7.5 (default, Jul 13 2018, 13:06:57)
[GCC 4.8.5 20150623 (Red Hat 4.8.5-28)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import salt.client
>>> local = salt.client.LocalClient() #<salt.client.LocalClient object at 0x7f886dbdd850>
>>> local.cmd('*','cmd.run',['hostname'])#向所有minion发送命令
{'slave': 'slave'}
逐条返回结果,local.cmd_iter()
>>> ret=local.cmd_iter('*','test.ping')
>>> ret
<generator object cmd_iter at 0x7f886d455c80>
>>> for i in ret:
... print i
...
{'slave': {'retcode': 0, 'ret': True}}
斐波那契数列
>>> local.cmd('*','test.fib',[10])
{'slave': [[0, 1, 1, 2, 3, 5, 8], 2.1457672119140625e-06]}
检查minion服务器信息
>>> local.cmd('*','cmd.run',['hostname'])
{'slave': 'slave'}
>>> local.cmd('*','cmd.run',['ifconfig'])
>>> local.cmd('*','cmd.run',['crontab -l'])
>>> local.cmd('*','cmd.run',['df -h'])
启停minion的服务,如nginx
>>> local.cmd('*','service.stop',['nginx'])
{'slave': True}
>>> local.cmd('*','service.status',['nginx'])
{'slave': False}
>>> local.cmd('*','service.start',['nginx'])
{'slave': True}