1、Ansible安装部署简单。默认情况下,SaltStack需要安装客户端接收服务器发送过来的命令。Ansible不需要在被控服务器上部署任何的客户端,直接使用ssh通道进行远程命令的执行或者下发配置。
2、SaltStack响应速度快。默认情况下,Ansible使用的是标准的SSH协议,而SaltStack使用ZeroMQ进行通信和传输。因此,仅仅从响应速度来讲,SaltStack比Ansible快很多,甚至快十几倍。在一般运维场景下,Ansible的响应速度完全可以满足需求。
3、Ansible更安全。Ansible使用标准的SSH连接传输数据,不需要在远程主机上启动守护进程。此外,标准的SSH数据传输本身就是加密传输,远程主机不易被攻击。
4、对Windows的支持。SaltStack对Windows的支持比较友好,Ansible从1.7版本开始加入了对Windows的支持。由于Windows默认没有SSH,而Ansible有依赖SSH进行通信,所以在Windows下Ansible需要依赖PowerShell来实现远程管理。Ansible必须使用Linux系统运行控制端。
5、Ansible自身运维比较简单。SaltStack需要在Master和Minion主机启动一个守护进程,自身需要检测守护进程的运行状态,增加了运维成本。Ansible和服务器之间用SSH进行通信,服务器上值需要运行SSH进程就可以进行运维操作。因此,从工具本身的运维角度来说,Ansible要比SaltStack简单很多。
角色 | id(minion id) | IP |
---|---|---|
Master | SN-2020-03-01 | 192.1687.79.143 |
minion | SN-2020-03-11 | 192.1687.79.146 |
yum install epel
yum install salt-master
chkconfig salt-master on
service salt-master start
yum install salt-minion
chkconfig salt-minion on
service salt-minion start
在主控端添加TCP 4505、TCP 4506的规则,而在被控端无须配置防火墙,原理是被控端直接与主控端的zeromq建立长链接,接收广播到的任务信息并执行,具体操作是添加两条iptables规则:
[root@192 ~]# iptables -I INPUT -m state --state new -m tcp -p tcp --dport 4505 -j ACCEPT
[root@192 ~]# iptables -I INPUT -m state --state new -m tcp -p tcp --dport 4506 -j ACCEPT
Saltstack分两种角色,一种为master(主控端),另一种为minion(被控端),安装完毕后需要对两种角色的配置文件进行修改。下面具体说明:
/etc/salt/master
# 绑定Master通信IP
interface: 192.168.79.143
# 自动认证,避免手动运行salt-key来确认证书信任
auto_accept: True
# 指定saltstack文件根目录的位置
file_roots:
base:
- /srv/salt
当/etc/salt/master没有配置auto_accept: True时,需要通过salt-key命令来进行证书认证操作,具体操作如下:
salt-key -L:显示已经或未认证的被控端id,Accepted Keys为已认证清单,Unaccepted Kys为未认证的清单
salt-key -D:删除所有认证主机id证书
salt-key -d id:删除单个id证书
salt-key -A:接受所有id证书请求
salt-key -a id:接受单个id证书请求
service salt-master restart
/etc/salt/minion
# 指定master主机IP地址
master: 192.168.79.143
# 修改被控制端主机识别ID,建议使用操作系统主机名来配置
id: SN2020-03-11
service salt-minion restart
通过test模块的ping方法,可以确认指定被控端设备与主控端是否建立信任关系,及连通性是否正常,探测所有被控端采用“*”来代替“SN-2020-03-20”即可。如下所示:
[root@192 ~]# salt 'SN-2020-03-11' test.ping
SN-2020-03-11:
True
[root@192 ~]#
saltstack的一个比较突出的优势是,具备执行远程命令的功能,可以帮助运维人员完成集中化的操作平台。
salt '<操作目标>' <方法>[参数]
示例:查看被控主机的内存使用情况
[root@192 ~]# salt 'SN-2020-03-11' cmd.run 'free -m'
SN-2020-03-20:
total used free shared buff/cache available
Mem: 972 577 82 16 311 170
Swap: 2047 134 1913
针对<操作目标>,saltstack提供了多种方法对被控端主机(id)进行过滤。
通过正则表达式进行匹配。示例:监控SN-2020字符开头的主机id名是否连通,如下所示:
[root@192 ~]# salt -E '^SN-2020*' test.ping
SN-2020-03-20:
True
以主机名id列表的形式进行过滤,格式与Python的列表相似,即不同的主机id名称使用逗号进行分隔。示例:获取主机id名为SN-2020-03-11、SN-2020-03-12;获取完整操作系统发行版本名称。如下所示:
[root@192 ~]# salt -L 'SN-2020-03-11,SN-2020-03-12' grains.item osfullname
SN-2020-03-11:
----------
osfullname:
CentOS Linux
SN-2020-03-12:
----------
osfullname:
CentOS Linux
根据主控端master配置文件中的分组名称进行过滤。如下所示:
/etc/salt/master
[root@192 ~]# vim /etc/salt/master
nodegroups:
group1: 'L@SN-2020-03-20,SN-2020-03-21,SN-2020-03-22'
group2: 'L@SN-2020-03-11,SN-2020-03-12'
[root@192 ~]# service salt-master restart
Redirecting to /bin/systemctl restart salt-master.service
[root@192 ~]# salt -N group1 test.ping
SN-2020-03-20:
True
SN-2020-03-21:
True
SN-2020-03-22:
True
[root@192 ~]#
根据条件运算符not、and、or去匹配不同规则的主机信息。示例:探测SN-2020开头,并且操作系统版本为CentOS的主机连通性。
[root@192 ~]# salt -C 'E@SN-2020.* and G@os:CentOS' test.ping
SN-2020-03-20:
True
其中,not语句不能作为第一个条件执行,不过可以通过以下方式来规避。示例:探测非SN-2023开头的主机连通性。
[root@192 ~]# salt -C '* and not E@^SN-2023*' test.ping
SN-2020-03-20:
True
根据被控主机的IP地址或IP子网进行匹配,示例如下:
[root@192 ~]# salt -S 192.168.0.0/16 test.ping
[root@192 ~]# salt -S 192.168.79.164 test.ping
saltstack提供了非常丰富的功能模块,设计操作系统的基础功能、常用工具支持等。使用sys模块可以列出当前版本支持的模块。
[root@192 ~]# salt '*' sys.list_modules
SN-2020-03-20:
- acl
- aliases
- alternatives
- archive
- artifactory
<!--省略部分输出-->
APId的原理是通过调用master client模块,实例化一个LocalClient对象,再调用cmd()方法实现的。以下是API实现test.ping的示例:
import salt.client
clinet = salt.client.LocalClient()
result = client.cmd('*', 'test.ping')
print(result)
结果以一个标准的Python字典形式的字符串返回,可以通过eval()函数转换成Python的字典类型,方便后续的业务u逻辑处理。程序运行结果如下:
{'SN-2020-03-20':True}
功能:实现系统层面的压缩包调用,支持gunzip、gzip、rar、tar、unrar、unzip等。
示例:
# 采用gzip解压 /tmp/data.txt文件
[root@192 ~]# salt 'SN-2020-03-20' archive.gzip /tmp/data.txt
SN-2020-03-20:
# 采用tar压缩 /tmp/data.txt文件
[root@192 ~]# salt 'SN-2020-03-20' archive.tar cvf /tmp/data.txt.tar /tmp/data.txt
SN-2020-03-20:
- tar: Removing leading `/' from member names
- /tmp/data.txt
调用API:
client.cmd('SN-2020-03-20','archive.gzip',['/tmp/data.txt'])
实现远程的命令行调用执行(默认具备root操作权限,慎用!)
示例:
# 获取所有被控主机的内存情况
salt '*' cmd.run "free -m"
# 在SN-2020-03-20主机运行test.sh脚本,
salt 'SN-2020-03-20' cmd.script salt://script/test.sh
# 其中script/test.sh脚本存放在file_roots指定的目录:/srv/salt
mkdir -p /srv/salt/script
vim /srv/salt/script/test.sh
# 该命令会做2个动作:
# 1.首先同步test.sh到minion的cache目录(如:同步到
# /var/cache/salt/minion/files/base/script/test.sh);
# 2.其次运行该脚本。
调用API:
client.cmd('SN-2020-03-20','cmd.run',['free -m'])
实现远程文件、目录的复制,以及下载URL文件等操作。
示例:
# 将指定被控主机的/etc/hosts文件复制到被控主机本地的salt的cache目录(/var/cache/salt/minion/localfiles/)
[root@192 ~]# salt '*' cp.cache_local_file /etc/hosts
SN-2020-03-20:
/var/cache/salt/minion/localfiles/etc/hosts
# 将主服务器file_roots指定位置下的目录复制到被控主机,空目录不复制
[root@192 ~]# salt "SN-2020-03-20" cp.get_dir salt://ccc /tmp
SN-2020-03-20:
- /tmp/ccc/ccc.txt
# 将主服务器file_roots指定位置下的文件复制到被控主机
[root@192 ~]# salt "SN-2020-03-20" cp.get_file salt://test.sh /tmp/test.sh
SN-2020-03-20:
/tmp/test.sh
# 下载URL内容到被控主机指定位置
[root@192 ~]# salt "SN-2020-03-20" cp.get_url https://slashdot.org/ /tmp/index.html
SN-2020-03-20:
/tmp/index.html
调用API:
client.cmd(‘SN-2020-03-20’, ‘cp.get_file, [‘salt://path/to/file’ ,’/minion/dest’])
实现被控主机的crontab操作。
示例:
# 查看指定被控主机、root用户的crontab清单
[root@192 ~]# salt "SN-2020-03-20" cron.raw_cron root
SN-2020-03-20:
# Lines below here are managed by Salt, do not edit
* * * * * /usr/bin/date
# 为指定的被控主机、root用户添加/usr/bin/date任务作业
[root@192 ~]# salt "SN-2020-03-20" cron.set_job root '*' '*' '*' '*' '*' /usr/bin/date
SN-2020-03-20:
new
# 删除指定的被控主机、root用户crontab的/usr/bin/date任务作业
[root@192 ~]# salt "SN-2020-03-20" cron.rm_job root /usr/bin/date
SN-2020-03-20:
removed
调用API:
client.cmd('SN-03-2020-20', 'cron.set_job', ['root','*','*','*','*','*','/usr/bin/date'])
实现被控主机通用DNS相关操作。
示例:
# 添加指定被控主机hosts的主机配置项
salt '*' dnsutil.hosts_append /etc/hosts 127.0.0.1 ad1.yk.com,ad2,yk.com
# 删除指定被控主机hosts的主机配置项
salt '*' dnsutil.hosts_remove /etc/hosts ad1.yk.com
调用API:
client.cmd('*', 'dnsutil.hosts_append', ['/etc/hosts','127.0.0.1','ad1.yk.com'])
被控主机文件常见的操作,包括文件读写、权限、查找、校验等。
示例:
# 校验所有被控主机/etc/fstab文件的MD5,一致则返回True
# 修改所有别空主机文件的属组、用户权限,等价于chown test:root /tmp/test.sh
[root@192 ~]# salt "SN-2020-03-20" file.chown /tmp/test.sh test root
SN-2020-03-20:
None
# 复制被控主机本地文件到本地的文件
[root@192 ~]# salt "SN-2020-03-20" file.copy /tmp/ccc/ccc.txt /tmp/c.txt
SN-2020-03-20:
True
# 检查所有被控主机/etc目录是否存在,存在则返回True,检查文件是否存在使用file.file_exists方法
[root@192 ~]# salt "SN-2020-03-20" file.directory_exists /etc
SN-2020-03-20:
True
[root@192 ~]# salt "SN-2020-03-20" file.file_exists /etc/passwd
SN-2020-03-20:
True
[root@192 ~]#
# 获取所有被控主机/etc/passwd的stats信息
[root@192 ~]# salt "SN-2020-03-20" file.stats /etc/passwd
SN-2020-03-20:
----------
atime:
1585115927.94
ctime:
1572940727.67
gid:
0
group:
root
inode:
19172097
mode:
0644
mtime:
1572940727.67
size:
2349
target:
/etc/passwd
type:
file
uid:
0
user:
root
# 获取所有被控主机/etc/passwd的权限mode,如:755,644
[root@192 ~]# salt "SN-2020-03-20" file.get_mode /etc/passwd
SN-2020-03-20:
0644
# 修改所有被控主机/etc/passwd的权限mode为644
[root@192 ~]# salt "SN-2020-03-20" file.set_mode /etc/passwd 644
SN-2020-03-20:
0644
# 在所有被控主机创建目录
[root@192 ~]# salt "SN-2020-03-20" file.mkdir /opt/test
SN-2020-03-20:
None
# 将所有被控主机/etc/httpd/httpd.conf文件的LogLevel参数warn值修改为info
[root@192 ~]# salt "SN-2020-03-20" file.sed /tmp/date.log "内容" "content"
SN-2020-03-20:
----------
pid:
15581
retcode:
0
stderr:
stdout:
# 给所有被控主机的/tmp/test/test.conf文件追加内容“maxclient 100”
[root@192 ~]# salt "SN-2020-03-20" file.append /tmp/date.log "追加内容"
SN-2020-03-20:
Wrote 1 lines to "/tmp/date.log"
# 删除所有被控主机的/tmp/foo文件
[root@192 ~]# salt "SN-2020-03-20" file.remove /tmp/c.txt
SN-2020-03-20:
True
调用API:
client.cmd('*', 'file.remove', ['/tmp/foo'])
被控主机ilptables支持。
示例:
# 在所有被控主机追加、插入iptables规则,其中INPUT为输入链
salt '*' iptables.append filter INPUT rule='-m state --state RELATED,ESTABLISHED -j ACCEPT'
salt '*' iptables.insert filter INPUT position=3 rule='-m state --state RELATED,ESTABLISHED -j ACCEPT'
# 在所有被控主机删除指定链编号为3(position=3)或者指定存在的规则
salt '*' iptables.delete filter INPUT position=3
salt '*' iptables.delete filter INPUT rule='-m state --state RELATED,ESTABLISHED -j ACCEPT'
# 保存所有被控主机规则到本地硬盘(/etc/sysconfig/iptables)
salt '*' iptables.save /etc/sysconfig/iptables
调用API:
client.cmd('SN-2020-03-20', 'iptables.append', ['filter', 'INPUT', 'rule=\'-p tcp--sport 80 -j ACCEPT\''])
返回被控主机网络信息。
示例:
# 在指定被控主机“SN-2020-03-20”获取dig、ping、traceroute目录域名信息
salt 'SN-2020-03-20' network.dig www.qq.com
salt 'SN-2020-03-20' network.ping www.qq.com
salt 'SN-2020-03-20' network.traceroute www.qq.com
# 获取指定被控主机“SN-2020-03-20”的MAC地址
salt 'SN-2020-03-20' network.hwaddr ens33
# 检测指定被控主机“SN-2020-03-20”是否属于10.0.0.0/16子网范围,属于则返回True
salt 'SN-2020-03-20' network.in_subnet 10.0.0.0/16
# 获取指定被控主机“SN-2020-03-20”的网卡配置信息
salt 'SN-2020-03-20' network.interfaces
# 获取指定被控主机“SN-2020-03-20”的IP地址配置信息
salt 'SN-2020-03-20' network.ip_addrs
# 获取指定被控主机“SN-2020-03-20”的子网信息
salt 'SN-2020-03-20' network.subnets
调用API:
client.cmd('SN-2020-03-20','network.subnets')
被控主机程序包管理,如yum、apt-get等。
示例:
# 为所有被控主机安装PHP环境,根据不同系统发行版调用不同的安装工具进行部署,如Redhat平台的yum,等价于yum -y install php
salt '*' pkg.install php
# 卸载所有被控主机的PHP环境
salt '*' pkg.remove php
# 升级所有被控主机的软件包
salt '*' pkg.upgrade
调用API:
client.cm('SN-2020-03-20','pgk.remove', ['php'])
被控主机程序包的服务管理。
示例:
# 开启(enable)、禁用(disable)nginx开机自启动服务
salt '*' service.enable nginx
salt '*' service.disable nginx
# 针对nginx服务的reload、restart、start、stop、status操作
salt '*' service.reload nginx
salt '*' service.restart nginx
salt '*' service.start nginx
salt '*' service.stop nginx
salt '*' service.staus nginx
API调用:
client.cmd('SN-2020-03-20', 'service.stop', ['nginx'])
通过上面介绍的10个常用的模块,基本上已经覆盖了日常的运维操作。saltstack还提供了其他模块,如下所示:
user:系统用户模块
group:系统组模块
partition:系统分区模块
puppet:puppet管理模块
system:系统重启、关机模块
timezone:时区管理模块
nginx:NGINX管理模块
mount:文件系统挂载模块
……
更多的模块介绍请查阅官网。
grains是saltstack最重要的组件之一,grains的作用是手机被控主机的基本信息,这些信息通常都是一些静态类的数据,包括CPU、内核、操作系统、虚拟化等,在服务器端可以根据这些信息进行灵活定制,管理员可以利用这些信息对不同业务进行个性化配置。官网提供的用来区分不同操作系统的示例如下(采用jinja模板):
{% if grains['os'] == 'Ubuntu' %}
host: {{ grains['host'] }}
{% elif grains['os'] == 'CentOSu' %}
host: {{ grains['fqdn'] }}
{% endif %}
示例中CentOS发行版主机将被“host: {{ grains[‘fqdn’] }}”匹配,同时,命令行的匹配操作系统发行版本为CentOS的被控端可以通过-G参数来过滤,如salt -G ‘os:CentOS’ test.ping。
匹配内核版本为3.10.0-957.el7.x86_64的主机:
[root@192 ~]# salt -G 'kernelrelease:3.10.0-957.el7.x86_64' cmd.run 'uname -a'
SN-2020-03-20:
Linux 192.168.79.146 3.10.0-957.el7.x86_64 #1 SMP Thu Nov 8 23:39:32 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux
获取所有主机的grains项信息:
[root@192 ~]# salt 'SN-2020-03-20' grains.ls
SN-2020-03-20:
- SSDs
- biosreleasedate
- biosversion
- cpu_flags
- cpu_model
- cpuarch
- domain
- fqdn
- fqdn_ip4
- fqdn_ip6
- gpus
- host
- hwaddr_interfaces
- id
- init
- ip4_interfaces
- ip6_interfaces
- ip_interfaces
- ipv4
- ipv6
- kernel
- kernelrelease
- locale_info
- localhost
- lsb_distrib_id
- machine_id
- manufacturer
- master
- mdadm
- mem_total
- nodename
- num_cpus
- num_gpus
- os
- os_family
- osarch
- oscodename
- osfinger
- osfullname
- osmajorrelease
- osrelease
- osrelease_info
- path
- productname
- ps
- pythonexecutable
- pythonpath
- pythonversion
- saltpath
- saltversion
- saltversioninfo
- selinux
- serialnumber
- server_id
- shell
- systemd
- virtual
- zmqversion
当然,也可以获取主机单项grains数据,如获取操作系统发行版本,执行命令:salt ‘SN-2020-03-20’ grains.item os,结果如下所示:
[root@192 ~]# salt 'SN-2020-03-20' grains.item os
SN-2020-03-20:
----------
os:
CentOS
如果要获取主机id为“SN-2020-03-20”的所有grains键及值信息,执行以下命令:
salt 'SN-2020-03-20' grains.items
定义grains数据的方法有两种,其中一种为在被控主机定制配置文件,另一种是通过主
控端扩展模块API实现,区别是模块更灵活。可以通过Python编程动态定义,而配置文件
只适合相对固定的键与值,下面分别举例说明。
SSH登录一台被控机,如:SN-2020-03-20,配置文件定制的路径为/etc/salt/minion.d/hostinfo.conf,具体操作如下:
[root@192 ~]# vim /etc/salt/minion.d/hostinfo.conf
grains:
roles:
- webserver
- redis
deployment: datacenter4
cabinet: 13
[root@192 ~]# service salt-minion restart
重启被控主机salt-minion服务,使配置生效。验证结果在主控机运行:salt ‘SN-2020-03-20’ grains.item roles deployment cabinet,观察配置的键和值,如下所示:
[root@192 ~]# salt 'SN-2020-03-20' grains.item roles deployment cabinet
SN-2020-03-20:
----------
cabinet:
13
deployment:
datacenter4
roles:
- webserver
- redis
实现步骤:
1. 首先在主控端编写Python代码,
2. 然后将Python文件同步到被控主机,
3. 最后刷新生效。
在主控端base目录(默认的base配置在/srv/salt)下生成_grains目录,编写Python代码,事项获取主控机系统允许最大打开文件数的grains数据。
/srv/salt/_grains/sysprocess.py
import os,sys,commands
def grains_openfile():
grains = {}
_open_file = 65536
getulimit = 0
try:
getulimit = commands.getstatusoutout('source /etc/profile;ulimit -n')
if getulimit[0] == 0:
_open_file = int(getulimit[1])
except Exception as e:
pass
grains['max_open_file'] = _open_file
return grains
上面代码说明:
1. grains_open_file():定义一个获取最大打开文件数的函数,函数名称没有要求,符合Python的函数命名规则即可;
2. grains{}:初始化一个grains字典,变量名一定要用grains,以便SaltStack识别;
3. grains['max_open_file']=_open_file:将获取的“ulimit -n”的结果赋值给grains['max_open_file'],其中“max_open_file”就是grains的项,“_open_file”就是grains的值。
最后同步模块到指定被控端主机,并刷新生效。因为grains比较适合采集静态类数据,比如:硬件、内核信息等。当有动态类的功能需求是,需要执行刷新,具体操作如下:
[root@192 ~]# salt 'SN-2020-03-20' saltutil.sync_all
SN-2020-03-20:
----------
beacons:
grains:
- grains.sysprocess
modules:
output:
renderers:
returners:
sdb:
states:
utils:
文件被同步到控端主机的minion cache目录下,如下所示:
/var/cache/salt/minion/extmods/grains/为扩展模块文件最终存放位置,刷新模块后将在同路径下生成字节码pyc;
/var/cache/salt/minion/files/base/_grains/为临时存放位置。
[root@192 ~]# ll /var/cache/salt/minion/extmods/grains/
总用量 8
-rw-------. 1 root root 362 3月 27 14:22 sysprocess.py
[root@192 ~]# ll /var/cache/salt/minion/files/base/_grains/
总用量 4
-rw-------. 1 root root 362 3月 27 14:22 sysprocess.py
[root@192 ~]# salt 'SN-2020-03-20' sys.reload_modules
SN-2020-03-20:
True
在被控端主机的/var/cache/salt/minion/extmods/grains/位置多了一个编译后的字节码文件sysprocess.pyc。
[root@192 ~]# ll /var/cache/salt/minion/extmods/grains/
总用量 8
-rw-------. 1 root root 362 3月 27 14:22 sysprocess.py
-rw-------. 1 root root 646 3月 27 14:22 sysprocess.pyc
[root@192 ~]# ll /var/cache/salt/minion/files/base/_grains/
总用量 4
-rw-------. 1 root root 362 3月 27 14:22 sysprocess.py
[root@192 ~]# salt 'SN-2020-03-20' grains.item max_open_file
SN-2020-03-20:
----------
max_open_file:
65536
pillar也是Saltstack最重要的组件之一其作用是定义与被控主机相关的任何数据,定义好的数据可以被其他组件使用,如模板、state,、API等。在pillar中定义的数据与不同业务特性的被控主机相关联,这样不同被控主机只能看到自己匹配的数据,因此pillar安全性很高,适用于一些比较敏感的数据,这也是区别于grains最关键的一点。如定义不同业务组主机的用户id、组id、读写权限、程序包等信息。定义的规范是采用Python字典形式,即键/值。最上层的键一般为主机的id或组名称。下面详细描述如何进行pillar的定义和使用。
Saltstack默认将主控端配置文件中的所有数据都定义到pillar中,而且对所有被控主机开放,可通过修改**/etc/salt/master配置中的pillar opts: Ture或False来定义是否开启或禁用这项功能,修改后执行salt ‘*’ pillar.data**来观察效果。以主机“SN2013-08-022”为例,执行salt ‘SN2013-08-022’ pillar.data。
[root@192 ~]# salt 'SN-2020-03-20' pillar.data
SN-2020-03-20:
----------
appname:
website
flow:
----------
maxconn:
30000
maxmem:
6G
pillar支持在sls文件中定义数据,格式须符合YAM L规范,与Saltstack的state组件十分相似,新人容易将两者混淆,两者文件的配置格式、入口文件top.sls都是一致的。下面详细介绍pillar使用sls定义的配置过程。
修改主配置文件**/etc/salt/master**的pillar_roots参数,定义pillar的主目录,格式如下:
pillar_roots:
base:
- /srv/pillar
同时创建pillar目录,执行命令:install -d /srv/pillar。
入口文件的作用一般是定义pillar的数据覆盖被控主机的有效范围,“*”代表任意主机,其中包括了一个data.sls文件,具体内容如下:
/srv/pillar/top.sls
base:
'*':
- data
/srv/pillar/data.sls
appname: website
flow:
maxconn: 30000
maxmem: 6G
通过查看" SN2020-03-20”主机的pillar数据,可以看到多出了data.sls数据项,原因是我们定义top.sls时使用‘*’覆盖了所有主机,这样当查看’‘ SN2020-03-20”的pillar数据时可以看到我们定义的数据。
如果结果不符合预期,可以尝试刷新被控主机pillar数据,运行salt ’*’ saltutil.refresh_pillar即可。
[root@192 ~]# salt '*' saltutil.refresh_pillar
SN-2020-03-20:
True
[root@192 ~]# salt 'SN-2020-03-20' pillar.data appname flow
SN-2020-03-20:
----------
appname:
website
flow:
----------
maxconn:
30000
maxmem:
6G
完成pillar配置后,接下来介绍使用方法。
我们可以在state、模块文件中引用,模块格式为“{{ pillar变量 }}”,例如:
{{ pillar['appname'] }} #一级字典
{{ pillar['flow']['maxconn'] }} #二级字典
PythonAPI格式如下:
pillar['flow']['maxconn']
pillar.get('flow:appname', {})
[root@192 ~]# salt -I 'appname:website' test.ping
SN-2020-03-20:
True
首先通过结合grains的id信息来区分不同id的maxcpu的值,其次进行引用观察匹配的信息,将data.sls修改成如下形式.其中,“if … else…endfi”为jinja2的模板语法,更多信息请访问Jinja2官网语法介绍,网址为http://jinja.pocoo.
org/docs/templates/。
appname: website
flow:
maxconn: 30000
maxmem: 6G
{% if grains['id'] == 'SN-2020-03-20' %}
maxcpu: 8
{% else %}
maxcpu: 4
{% endif %}
通过查看被控主机的pillar数据,可以看到maxcpu的差异,如下所示:
[root@192 ~]# salt 'SN-2020-03-20' pillar.data flow
SN-2020-03-20:
----------
flow:
----------
maxconn:
30000
maxcpu:
8
maxmem:
6G
[root@192 ~]# salt 'SN-2020-03-21' pillar.data flow
SN-2020-03-20:
----------
flow:
----------
maxconn:
30000
maxcpu:
4
maxmem:
6G
state是Saltstack最核心的功能。通过预先定制好的sls (salt state file)文件对被控主机进行状态管理,支持包括程序包(pkg)、文件(file)、网络配置(network)、系统服务(service),系统用户(user)等,更多状态对象见http://docs.sai tstack.com/ref/states/all/index.html。
state的定义是通过sls文件进行描述的,支持YAML语法,定义的规则如下:
$ID:
$State:
- $state: states
其中:
$ID:定义state的名称,通常采用与描述的对象保持一致的方法,如apache, nginx等;
$State:须管理对象的类型
$state:states:定制对象的状态。
官网提供的示例如下:
apache:
pkg:
- installed
service:
- running
- require
- pkg: apache
上述代码检查apache软件包是否已安装状态,如果未安装,将通过yum或apt进行安装;检查服务apache进程是否处于运行状态。下面详细进行说明:
第1行用于定义state的名称,此示例为apache,当然也可以取其他相关的名称。
第2行和第4行表示state声明开始,使用了pkg和service这两个状态对象。pkg使用系统本地的软件包管理器(yum或apt)管理将要安装的软件,service管理系统守护进程。
第3行和第5行是要执行的方法。这些方法定义了pache软件包和服务目标状态,此示例要求软件包应当处于已安装状态,服务必须运行,如未安装将会被安装并启动。
第6行是关键字require,它确保了apache服务只有在成功安装软件包后才会启动。
state的入口文件与pillar一样,文件名称都是top.sls,但state要求sls文件必须存放在saltstack base定义的目录下,默认为/srv/salt。state描述配置.sls支持jinjia模板、grains、pillar引用等。在state的逻辑层次定义完成后,再通过salt ‘*’ state.highstate执行生效。
下面结合grains与pillar,实现一个根据不同操作系统类型部署apache环境的任务。
/srv/pillar/top.sls
base:
'*':
- apache
在top.sls中引用二级配置有两种方式:一种是直接引用,如直接引用apache.sls;另一种是创建apache目录,再引用目录中的init.sls文件,两者的效果是一样的。为了规范起见,我们采用二级配置形式。同理,state的top.sls也采用如此方式。
mkdir /srv/pillar/apache
内容如下:
pkgs:
{% if grains['os_family'] == 'Debian' %}
apache: apache2
{% elif grains['os_family'] == 'RedHat' %}
apache: httpd
{% elif grains['os'] == 'Arch' %}
apache: apache
{% endif %}
[root@192 ~]# salt 'SN-2020-03-20' pillar.data pkgs
SN-2020-03-20:
----------
pkgs:
----------
apache:
httpd
/srv/salt/top.sls
base:
'*':
- apache
/srv/salt/apache/init.sls
apache:
pkg:
- installed
- name: {{ pillar['pkgs']['apache'] }}
service:
- running
- name: {{ pillar['pkgs']['apache'] }}
- require:
- pgk: {{ pillar['pkgs']['apache'] }}
在配置中,{{ pillar[‘pkgs’][‘apache’] }}将引用匹配到操作系统发行版对应的pillar数据,我的环境为CentOS,故将匹配为httpd,检查目标主机是否已经安装,没有则进行安装( yum -y install httpd)。同时检查apache服务是否已经启动,没有则启动(/etc/init.d/httpd start)。
执行state及返回信息如下所示:
[root@192 ~]# salt 'SN-2020-03-20' state.highstate
SN-2020-03-20:
----------
ID: apache
Function: pkg.installed
Name: httpd
Result: True
Comment: The following packages were installed/updated: httpd
Started: 17:24:45.296375
Duration: 38108.261 ms
Changes:
----------
httpd:
----------
new:
2.4.6-90.el7.centos
old:
----------
ID: apache
Function: service.running
Name: httpd
Result: False
Comment: The following requisites were not found:
require:
pgk: httpd
Started:
Duration:
Changes:
Summary
------------
Succeeded: 1 (changed=1)
Failed: 1
------------
Total states run: 2
可以看出,结果返回两种对象类型结果,分别为pkg与service,执行的结果是自动部署apache 2.4.6-90环境,但是启动apache服务失败,因为“/etc/init.d/httpd start”无法执行,只能手动启动了。