SaltStack

SaltStack

Ansible和SaltStack的区别

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简单很多。

一、安装SaltStack

1、实验环境:

角色 id(minion id) IP
Master SN-2020-03-01 192.1687.79.143
minion SN-2020-03-11 192.1687.79.146

2、安装EPEL

yum install epel

3、安装SaltStack

(1)主服务器安装(主控端)
yum install salt-master
chkconfig salt-master on
service salt-master start
(2)从服务器安装(被控端)
yum install salt-minion
chkconfig salt-minion on
service salt-minion start

4、SaltStack防火墙配置

在主控端添加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

5、更新Saltstack配置及安装校验

Saltstack分两种角色,一种为master(主控端),另一种为minion(被控端),安装完毕后需要对两种角色的配置文件进行修改。下面具体说明:

(1)master主控端配置
1)更新主控端关键项配置

/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证书请求
2)重启saltstack salt-master服务,使新配置生效
service salt-master restart
(2)minion被控制端配置
1)更新被控端关键项配置

/etc/salt/minion

# 指定master主机IP地址
master: 192.168.79.143
# 修改被控制端主机识别ID,建议使用操作系统主机名来配置
id: SN2020-03-11
2)重启saltstack salt-minion服务,使新配置生效
service salt-minion restart
(3)校验安装结果

通过test模块的ping方法,可以确认指定被控端设备与主控端是否建立信任关系,及连通性是否正常,探测所有被控端采用“*”来代替“SN-2020-03-20”即可。如下所示:

[root@192 ~]# salt 'SN-2020-03-11' test.ping
SN-2020-03-11:
    True
[root@192 ~]# 

二、使用saltstack远程执行命令

saltstack的一个比较突出的优势是,具备执行远程命令的功能,可以帮助运维人员完成集中化的操作平台。

1、salt命令格式

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

2、常用的具体参数

针对<操作目标>,saltstack提供了多种方法对被控端主机(id)进行过滤。

(1)-E,–pcre

通过正则表达式进行匹配。示例:监控SN-2020字符开头的主机id名是否连通,如下所示:

[root@192 ~]# salt -E '^SN-2020*' test.ping
SN-2020-03-20:
    True
(2)-L,–list

以主机名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
(3)-N,–nodegroup

根据主控端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 ~]# 
(4)-C,–compound

根据条件运算符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
(5)-S,–ipcidr

根据被控主机的IP地址或IP子网进行匹配,示例如下:

[root@192 ~]# salt -S 192.168.0.0/16 test.ping
[root@192 ~]# salt -S 192.168.79.164 test.ping

三、saltstack常用模块及API

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}

1、Archive模块

功能:实现系统层面的压缩包调用,支持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'])

2、cmd模块

实现远程的命令行调用执行(默认具备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'])

3、cp模块

实现远程文件、目录的复制,以及下载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’])

4、cron模块

实现被控主机的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'])

5、dnsutil模块

实现被控主机通用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'])

6、file模块

被控主机文件常见的操作,包括文件读写、权限、查找、校验等。

示例:

# 校验所有被控主机/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'])

7、iptables模块

被控主机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\''])

8、network模块

返回被控主机网络信息。

示例:

# 在指定被控主机“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')

9、pkg包管理模块

被控主机程序包管理,如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'])

10、Service服务模块

被控主机程序包的服务管理。

示例:

# 开启(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'])

11、其他模块

通过上面介绍的10个常用的模块,基本上已经覆盖了日常的运维操作。saltstack还提供了其他模块,如下所示:

user:系统用户模块
group:系统组模块
partition:系统分区模块
puppet:puppet管理模块
system:系统重启、关机模块
timezone:时区管理模块
nginx:NGINX管理模块
mount:文件系统挂载模块
……

更多的模块介绍请查阅官网。

四、grains组件

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。

1、grains常用操作命令

匹配内核版本为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

2、定义grains数据

定义grains数据的方法有两种,其中一种为在被控主机定制配置文件,另一种是通过主
控端扩展模块API实现,区别是模块更灵活。可以通过Python编程动态定义,而配置文件
只适合相对固定的键与值,下面分别举例说明。

(1)被控端主机定制grains数据

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
(2)主控端主机定制grains数据

实现步骤:

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比较适合采集静态类数据,比如:硬件、内核信息等。当有动态类的功能需求是,需要执行刷新,具体操作如下:

1) 同步模块
[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 327 14:22 sysprocess.py
    
[root@192 ~]# ll /var/cache/salt/minion/files/base/_grains/
总用量 4
-rw-------. 1 root root 362 327 14:22 sysprocess.py
2)刷新模块
[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 327 14:22 sysprocess.py
-rw-------. 1 root root 646 327 14:22 sysprocess.pyc
    
[root@192 ~]# ll /var/cache/salt/minion/files/base/_grains/
总用量 4
-rw-------. 1 root root 362 327 14:22 sysprocess.py    
3)校验数据
[root@192 ~]# salt 'SN-2020-03-20' grains.item max_open_file
SN-2020-03-20:
    ----------
    max_open_file:
        65536

五、pillar组件

pillar也是Saltstack最重要的组件之一其作用是定义与被控主机相关的任何数据,定义好的数据可以被其他组件使用,如模板、state,、API等。在pillar中定义的数据与不同业务特性的被控主机相关联,这样不同被控主机只能看到自己匹配的数据,因此pillar安全性很高,适用于一些比较敏感的数据,这也是区别于grains最关键的一点。如定义不同业务组主机的用户id、组id、读写权限、程序包等信息。定义的规范是采用Python字典形式,即键/值。最上层的键一般为主机的id或组名称。下面详细描述如何进行pillar的定义和使用。

1、pillar的定义

1)主配置文件定义

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

2)SLS文件定义

pillar支持在sls文件中定义数据,格式须符合YAM L规范,与Saltstack的state组件十分相似,新人容易将两者混淆,两者文件的配置格式、入口文件top.sls都是一致的。下面详细介绍pillar使用sls定义的配置过程。

1. 定义pillar的主目录

修改主配置文件**/etc/salt/master**的pillar_roots参数,定义pillar的主目录,格式如下:

pillar_roots:
  base:
    - /srv/pillar

同时创建pillar目录,执行命令:install -d /srv/pillar

2. 定义入口文件top.sls

入口文件的作用一般是定义pillar的数据覆盖被控主机的有效范围,“*”代表任意主机,其中包括了一个data.sls文件,具体内容如下:

/srv/pillar/top.sls

base:
  '*':
    - data

/srv/pillar/data.sls

appname: website
flow:
  maxconn: 30000
  maxmem: 6G
3. 校验pillar

通过查看" 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

2、pillar的使用

完成pillar配置后,接下来介绍使用方法。

我们可以在state、模块文件中引用,模块格式为“{{ pillar变量 }}”,例如:

{{ pillar['appname'] }} #一级字典
{{ pillar['flow']['maxconn'] }} #二级字典

PythonAPI格式如下:

pillar['flow']['maxconn']
pillar.get('flow:appname', {})

1、操作主机
[root@192 ~]# salt -I 'appname:website' test.ping
SN-2020-03-20:
    True

2、结合grains处理数据的差异性

首先通过结合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介绍

state是Saltstack最核心的功能。通过预先定制好的sls (salt state file)文件对被控主机进行状态管理,支持包括程序包(pkg)、文件(file)、网络配置(network)、系统服务(service),系统用户(user)等,更多状态对象见http://docs.sai tstack.com/ref/states/all/index.html。

1、state的定义

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服务只有在成功安装软件包后才会启动。

2、state的使用

state的入口文件与pillar一样,文件名称都是top.sls,但state要求sls文件必须存放在saltstack base定义的目录下,默认为/srv/salt。state描述配置.sls支持jinjia模板、grains、pillar引用等。在state的逻辑层次定义完成后,再通过salt ‘*’ state.highstate执行生效。

下面结合grains与pillar,实现一个根据不同操作系统类型部署apache环境的任务。

(1)定义pillar

/srv/pillar/top.sls

base:
  '*':
    - apache

在top.sls中引用二级配置有两种方式:一种是直接引用,如直接引用apache.sls;另一种是创建apache目录,再引用目录中的init.sls文件,两者的效果是一样的。为了规范起见,我们采用二级配置形式。同理,state的top.sls也采用如此方式。

1)创建apache目录:
mkdir /srv/pillar/apache

2)在apache目录创建init.sls

内容如下:

pkgs:
  {% if grains['os_family'] == 'Debian' %}
	apache: apache2
  {% elif grains['os_family'] == 'RedHat' %}
	apache: httpd
  {% elif grains['os'] == 'Arch' %}
	apache: apache
  {% endif %}

3)测试pillar数据
[root@192 ~]# salt 'SN-2020-03-20' pillar.data pkgs
SN-2020-03-20:
    ----------
    pkgs:
        ----------
        apache:
            httpd

(2)定义state

/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)。

(3)执行state

执行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”无法执行,只能手动启动了。

你可能感兴趣的:(SaltStack)