salt命令组成结构
在命令行输入的命令都是执行模块,等到命令写入到文件中就叫做状态模块
#即可查看salt帮助
[root@master ~]# salt --help
Usage: salt [options] '<target>' <function> [arguments]
salt命令 参数 目标 salt模块的函数 远程执行的参数
#--summary参数显示salt命令的概要
[root@master ~]# salt --summary '*' cmd.run 'hostname'
slave:
slave
-------------------------------------------
Summary
-------------------------------------------
# of Minions Targeted: 1
# of Minions Returned: 1
# of Minions Did Not Return: 0
-------------------------------------------
列出所有salt的sys模块
#与系统交互的sys模块
[root@master ~]# salt 'slave' sys.list_modules
slave:
- acl
- aliases
- alternatives
- archive
- artifactory
- blockdev
- btrfs
- buildout
- cloud
- cmd
- composer
- config
- container_resource
- cp
- cron
- data
- defaults
- devmap
- disk
- django
- dnsmasq
- dnsutil
- drbd
- elasticsearch
- environ
- etcd
远程执行命令模块
cmd是超级模块,所有shell命令都能执行
[root@master ~]# salt 'slave' cmd.run 'ps -ef|grep python'
slave:
root 873 1 0 22:23 ? 00:00:01 /usr/bin/python -Es /usr/sbin/tuned -l -P
root 1229 1 0 22:31 ? 00:00:00 /usr/bin/python /usr/bin/salt-minion
root 1232 1229 0 22:31 ? 00:00:02 /usr/bin/python /usr/bin/salt-minion
root 1345 1 0 23:17 ? 00:00:00 /usr/bin/python /usr/bin/salt-minion
root 1346 1345 0 23:17 ? 00:00:00 /bin/sh -c ps -ef|grep python
root 1348 1346 0 23:17 ? 00:00:00 grep python
远程安装nginx
#在minion上安装nginx
[root@master ~]# salt 'slave' pkg.install "nginx"
#检查pkg包的版本
[root@master ~]# salt 'slave' pkg.version "nginx"
#卸载minion上的nginx
[root@master ~]# salt 'slave' pkg.remove "nginx"
远程管理服务模块
管理服务是系统管理员的重要任务,通过salt管理minion服务会很简单,使用service模块
[root@master ~]# salt 'slave' service.start "nginx"
slave:
True
[root@master ~]# salt 'slave' service.status "nginx"
slave:
True
[root@master ~]# salt 'slave' service.stop "nginx"
slave:
True
与标准的Linux命令一样,salt的命令一样用法
--out控制salt命令结果输出的格式
JSON
[root@master ~]# salt --out=json '*' cmd.run_all 'hostname'
{
"slave": {
"pid": 11780,
"retcode": 0,
"stderr": "",
"stdout": "slave"
}
}
YAML
[root@master ~]# salt --out=yaml '*' cmd.run_all 'hostname'
slave:
pid: 11774
retcode: 0
stderr: ''
stdout: slave
YAML讲解
在学习saltstack过程中,第一要点就是States编写技巧,简称SLS文件。这个文件遵循YAML语法。
json xml yaml 数据序列化格式
yaml容易被解析,应用于配置文件
Salt的配置文件是yaml配置文件,不能用tab
Saltstack、Kubernetes、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',
}
}
YAML是YAML Ain't Markup Language的首字母缩写,YAML的语法简单,
结构体通过空格展示
项目使用 '-' 代表
键值对通过 ':' 分割
YAML语法遵循固定的缩进风格,表示数据层级结构关系,saltstack需要每个缩进级别由2个空格组成,禁止用tabs!!!
Python中的字典是简单的键值对,go语言中称作哈希表map
字典的key通过冒号分割
key在YAML中表现形式是一个冒号结果的字符串
my_key: my_value
转化到python语法中,上述命令为
{'my_key':'my_value'}
value还可以通过缩进和key关联,四个空格!!
my_key:
my_value
转化为python语法同样的
{'my_key':'my_value'}
YAML语法中字典是可以嵌套的
one_dict_key:
two_dict_key:value_dict
转化为python语法
{
'one_dict_key':{
'two_dict_key':'value_dict'
}
}
短横杠
YAML语法表示列表,使用一个横杠加一个空格
多个项使用同样的缩进级别作为同一个列表的部分
- list_value_one
- list_value_two
- list_value_three
列表可以作为一个键值对的value,例如一次性要安装多个软件
my_dict:
- l1
- l2
- l3
转化为python代码理解就是
{
'my_dict':['l1','l2',;l3]
}
目标定位字符串
之前的salt命令我们都是使用 salt '*'控制所有minion,并且我们只有一个“slave”,但是生产环境的服务器很可能是成千上百的minion,因此需要灵活地定位所需的服务器并且执行远程命令。
1、全局匹配
[root@master ~]# salt '*' test.ping
slave:
True
Linux通配符
* 代表任意字符,或空字符串
? 代表一个字符,不可以为空
[a-z] [0-9] 代表任何一个小写字母
[root@master ~]# salt 'slav?' test.ping
slave:
True
[root@master ~]# salt '[a-z]lave' test.ping
slave:
True
salt还支持python的re正则表达式
state模块定义主机状态
之前执行的远程命令,都是一个过程式的,类似一段shell或者python脚本执行,执行一次触发一次相同的功能。
那么大量的minion上运行远程命令就必须使用salt提供的“状态管理”了,状态是对minion的一种描述和定义,运维不需要关心部署是如何完成的,只需要描述minion需要达到什么状态。
接下来通过state模块部署nginx
master端
[root@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都需要执行,都需要创建文件夹
[root@master ~]# mkdir -p /srv/salt/{base,dev,test,prod}
[root@slave ~]# mkdir -p /srv/salt/{base,dev,test,prod}
#在master创建nginx.sls状态文件
[root@master ~]# cd /srv/salt/base
[root@master base]# vim 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 base]# salt 'slave' state.sls nginx
slave:
----------
ID: nginx-install
Function: pkg.installed
Name: nginx
Result: True
Comment: The following packages were installed/updated: nginx
Started: 23:44:06.160157
Duration: 13504.719 ms
Changes:
通过master检查slave的nginx状态
[root@master base]# salt 'slave' cmd.run 'ps -ef |grep nginx'
slave:
root 11190 1 0 23:44 ? 00:00:00 nginx: master process /usr/sbin/nginx
nginx 11191 11190 0 23:44 ? 00:00:00 nginx: worker process
root 11232 11231 0 23:50 ? 00:00:00 /bin/sh -c ps -ef |grep nginx
root 11234 11232 0 23:50 ? 00:00:00 grep nginx
Salt采集静态信息之Grains
如果你入职了,你的老板让你收集公司300台服务器的相关硬件信息,你是一台台登录呢?还是选择用salt收集呢?又或者用python的salt-api写脚本呢
Grains 是saltstack组件中非常重要之一,在配置部署时候回经常使用,Grains记录minion的静态信息,比如常用属性,CPU、内存、磁盘、网络信息等。
Minions的Grains信息是Minion启动时采集汇报给Master的
Grains是以 key value形式存储的数据库,可以看做Host的元数据(metadata)
Grains保存着收集到的客户端的详细信息
如果slave机器数据变化,grains就过期了
在生产环境中需要自定义Grains,可以通过
Minion配置文件
Grains相关模块定义
Python脚本定义
#查看grains的命令用法
[root@master ~]# salt 'slave' sys.doc grains
Grains人为是描述minion本身固有的静态属性数据,列出主机所有Grains数据
[root@master ~]# salt 'slave' grains.items
slave:
----------
SSDs:
biosreleasedate:
05/19/2017
biosversion:
6.00
cpu_flags:
.........
#信息过长,已经省略
#列出所有grains方法
[root@master ~]# salt 'slave' grains.ls
检索某些数据
[root@master ~]# salt 'slave' grains.item os id host
slave:
----------
host:
slave
id:
slave
os:
CentOS
利用Grains静态信息定位主机
两种写法:
salt '*' grains.item key1 key2 key3
salt '*' -G
#定位CentOS的机器
[root@master ~]# salt -G 'os:CentOS' test.ping
slave:
True
#定位操作系统系统是7系列的机器
[root@master ~]# salt -G 'osrelease:7*' test.ping
slave:
True
#找出IP地址
[root@master ~]# salt '*' grains.item fqdn_ip4
slave:
----------
fqdn_ip4:
- 192.168.1.78
因此用grains.items列出所有的数据匹配主机,以及根据单一信息定位数据,Grains还可以自定义来满足不同的需求。
自定义设置Grains数据
#设置数据
[root@master ~]# salt 'slave' grains.setval cpu_num 8
slave:
----------
cpu_num:
8
#查询数据
[root@master ~]# salt 'slave' grains.item cpu_num
slave:
----------
cpu_num:
8
在master端设置Grains静态数据,原理会将此数据添加到minion服务器的配置文件的/etc/salt/grains
[root@slave ~]# cat /etc/salt/grains
cpu_num: 8
对于复杂的数据结构,可以添加灵活的JSON语法
[root@master ~]# salt 'slave' grains.setval cpu_info '["Intel","Xeon","10"]'
slave:
----------
cpu_info:
- Intel
- Xeon
- 10
[root@master ~]# salt 'slave' grains.item cpu_info
slave:
----------
cpu_info:
- Intel
- Xeon
- 10
此时可以检查minion服务器上的grains文件
[root@slave ~]# cat /etc/salt/grains
cpu_info:
- Intel
- Xeon
- '10'
cpu_num: 8
因此Grains数据写入配置文件后,重启salt-minion服务,数据也不会丢失
想要删除可以通过grains.delval命令删除,或者去minion的配置文件删除配置一样完成操作(或者删除文件)
1、方法一(清空值)
[root@master ~]# salt 'slave' grains.delval cpu_info
slave:
None
[root@master ~]# salt 'slave' grains.delval cpu_num
slave:
None
2、方法二(删除minion的grains配置文件,重启服务)
[root@slave ~]# rm -rf /etc/salt/grains
[root@slave ~]# systemctl restart salt-minion
#检查结果删除成功
数据管理中心之Pillar组件
Pillar也是saltstack组件中非常重要的组件之一,称作数据管理中心,经常配合states在大规模的配置管理中使用。
Pillar是动态的,存储在master端,提供和给minion端
Pillar在SaltStack中主要的作用是存储和定义配置管理中需要的一些数据,比如软件版本号,用户账号密码等,保证敏感数据不被其他minion看到
存储格式与Grains类似,都是YAML格式
在master配置文件中有一段Pillar settings选项专门定义Pillar的参数
[root@master ~]# vim /etc/salt/master
#此配置代表pillar的工作根目录,在/srv/pillar下,然后可以新建sls文件
#pillar_roots:
# base:
# - /srv/pillar
默认pillar的工作目录在/srv/pillar目录下,执行如下代码
[root@master ~]# mkdir -p /srv/pillar
#指定环境,标记,引用packages.sls和services.sls
[root@master ~]# vim /srv/pillar/top.sls
base:
'*':
- packages
- services
[root@master ~]# vim /srv/pillar/packages.sls
nginx:
packages-name: nginx
version: 1.12.2
[root@master ~]# vim /srv/pillar/services.sls
nginx:
port: 80
user: root
检查我们设置的pillar值
[root@master ~]# salt '*' pillar.item nginx
slave:
----------
nginx:
----------
packages-name:
nginx
port:
80
user:
root
version:
1.12.2
Pillar与Grains对比
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, Aug 4 2017, 00:39:18)
[GCC 4.8.5 20150623 (Red Hat 4.8.5-16)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import salt.client
>>> local = salt.client.LocalClient()
>>> local.cmd('*','cmd.run',['hostname']) #向所有minion发送命令
{'slave': 'slave'}
因此python API就是提供了向saltstack发送命令的入口。
通过API获取saltstack的配置文件
获取master配置文件
>>> import salt.config #导入salt配置模块
>>> salt.config.client_config('/etc/salt/master') #读取salt配置文件,得到一个字典数据
获取minion配置文件
>>> 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, Aug 4 2017, 00:39:18)
[GCC 4.8.5 20150623 (Red Hat 4.8.5-16)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import salt.client
>>> local = salt.client.LocalClient()
>>> local.cmd('*','cmd.run',['hostname']) #向所有minion发送命令
{'slave': 'slave'}
逐条返回结果,local.cmd_iter()
>>> ret=local.cmd_iter('*','test.ping')
>>> ret
<generator object cmd_iter at 0x2b084b0>
>>> 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}