xyzjr 发表于 2018-7-31 12:10:01

Saltstack 简单入门

  saltstack (http://www.saltstack.com) 是一个服务器基础架构集中化管理平台,开始于2011年的一个项目,具备配置和管理、远程执行、监控等功能,一般可以理解成简化版puppet(http://puppetlabs.com)和加强版的func(https://fedorahosted.org/func)。saltstack基于Python语言实现,结合轻量级消息队列(ZeroMQ)与Python第三方模块(Pyzmq、PyCrypto、Pyjinja2、python-msgpack和PyYAML)等构建。Saltstack具备如下特点。
  1、部署简单、方便
  2、支持大部分UNIX/Linux及Windows
  3、主从集中化管理
  4、配置简单、功能强大、扩张性强
  5、主控端(master)和被控端(minion)基于证书认证,安全可靠。
  6、支持API及自定义模块、可通过Python轻松扩展。
  通过部署Saltstack环境 我们可以在成千上万台服务器上做到批量执行名命令,根据不同的业务特性进行配置集中化管理、分发文件、采集服务器数据、操作系统基础及软件包管理等。因此 Saltstack是运维人员提高工作效率、规范业务配置与操作的利器。目前Saltstack已经趋向成熟。用户群及社区活跃度都不错,同事官方也开放了不少子项目,具体可访问https://github.com/saltstack 获得。
  一 :Saltstack的安装
  Saltstack的不同角色服务安装非常简单,建议采用yum源方式来实现部署。
  1.业务环境说明:

  为了方便理解,通过虚拟化环境部署了两组业务功能服务器进行演示。操作系统版本为CentOS>角色ID IP组名CPU核数Nginx根目录MasterTEST-ID192.168.137.7---minionNODE1192.168.137.8webserver2/wwwminionNODE2192.168.137.9webserver2/dataminionNODE3192.168.137.10web2group2/wwwminionNODE4192.168.137.11web2group2/www  2.    安装EPEL
  由于目前RHEL官网yum源还没有Saltstack的安装包支持,因此现安装EPEL作为部署Saltstack的默认yum源。安装过程不在详述。
  3.开始安装。
  主控端安装。
yum install salt-master -y  
chkconfig salt-master on
  
service salt-master start
  被控端安装
yum install salt-minion -y  
chkconfig salt-minion on
  
service salt-minion start
  4.Saltstack防火墙配置
  在主控端添加TCP 4505 4506的规则,而在被控端无需配置防火墙,原理是被控直接与主控的zeromq建立长连接,接受广播到的任务信息并执行,具体操作是添加两条iptables 规则:
iptables -A INPUT -m state --state new -m tcp -p tcp --dport 4505 -j ACCEPT  
iptables -A INPUT -m state --state new -m tcp -p tcp --dport 4506 -j ACCEPT
  5. 更新Saltstack配置及安装测试
  Saltstack分两种角色,一种是master 主控端 另一种是minion 被控端 安装完毕后需要对两种角色的配置文件进行修改,具体如下:
  主控端配置:
  【/etc/salt/master】
#绑定master通信IP  
interface: 192.168.137.7
  
#自动认证,避免手动运行salt-key来确认证书信息
  
auto_accept: True
  
#指定Saltstack文件根目录位置
  
file_roots:
  
   base:
  
   - /srv/salt
  重启Saltstack salt-master服务器使配置生效。具体如下:
service salt-master restart  被控端配置:
  【/etc/salt/minion】
#指定master主机IP  
master: 192.168.137.7
  
#修改被控端主机识别ID,建议使用操作系统名来配置
  
id: NODE1
  重启Saltstack salt-minion服务器使配置生效。具体如下:
service salt-minion restart  测试安装结果。
  通过test模块的ping方法 可以确认指定被控端设备与主控端是否建立信任关系,连通性是否正常,探测所有被控端采用 '*' 来代替ID 即可 具体如下:
# salt 'NODE1' test.ping  
NODE1:
  
    True
  
# salt '*' test.ping
  
NODE1:
  
    True
  
NODE2:
  
    True
  
#
  当/etc/salt/master没有配置auto_accept: True时,需要通过salt-key命令来进行证书认证,具体操作如下:
  salt-key -L显示已经或者未认证的被控端ID,Accepted Keys为已认证 Unaccepted Keys 为未认证。
  salt-key -D 删除所有认证主机id证书

  salt-key -d>  salt-key -A 接受所有id证书请求

  salt-key -a>  二:利用Saltstack远程执行命令
  命令格式:salt '<操作目标>' <方法> [参数]
  示例:查看被控主机的内容使用情况
  salt '*' cmd.run 'free -m'
# salt '*' cmd.run 'free -m'  
NODE1:
  
               total       used       free   shared    buffers   cached
  
    Mem:          1989      678       1311          0         74      276
  
    -/+ buffers/cache:      327       1662
  
    Swap:         2015          0       2015
  
NODE2:
  
               total       used       free   shared    buffers   cached
  
    Mem:          1989      674       1315          0         74      276
  
    -/+ buffers/cache:      323       1666
  
    Swap:         2015          0       2015
  
#
  其中针对<操作目标>,Saltstack提供了多种方法对被控端主机(id)进行过滤。下面列举常用的具体参数。
  -E,--pcre,通过正则表达式进行匹配。示例:测试web字符开头的主机ID名是否连通 命令:
salt -E '^WEB.*' test.ping 运行结果如下:  
# salt -E '^web.*' test.ping
  
web2:
  
    True
  
web1:
  
    True
  
#
  -L,--list以主机id名列表的形式进行过滤,格式与Python列表相似。即不同主机id名称使用逗号分隔。示例: 获取主机id名为web1、web2;获取完整的操作系统发行版名称 命令如下:
# salt -L 'web1,web2' grains.item osfullname  
web1:
  
    ----------
  
    osfullname:
  
      CentOS
  
web2:
  
    ----------
  
    osfullname:
  
      CentOS
  
#
  -G,--grain根据被控主机的grains(后面详述)信息匹配过滤格式为:
  '<grainvalue>:<glob expression>'   例如:过滤内核为Linux的主机可以写成'kernel:Linux',如果同时需要正则表达式的支持可切换成--grain-pcre参数来执行。示例:获取主机发行版本号为6.8的Python版本号,命令:
# salt -G 'osrelease:6.8' cmd.run 'python -V'  
web1:
  
    Python 2.6.6
  
web2:
  
    Python 2.6.6
  
#
  -I,--pillar,根据被控主机的pillar(后面详述)信息进行匹配过滤,格式为"对象名称:对象值" 例如 过滤所有具备'apache:httpd' pillar值的主机。示例:探测具有"nginx:root: /data"信息的主机连通性 如下:
  salt -I 'nginx:root:/data' test.ping
..........  
...........
  
............
  其中pillar属性配置文件如下:
nginx:  
   root: /data
  -N,--nodegroup 根据主控端master配置文件中的分组名称进行过滤(主机信息支持正则表达式、grain、条件运算符等)通常根据业务类型划分,不通业务具备相同的特点,包括部署环境,应用平台、配置文件等。举例分组配置信息如下:
  【/etc/salt/master】
nodegroups:  
   web1group: 'L@web1,web2'
  
   webserver: 'L@web1,web2'
  其中 ,L@表示后面的主机id格式为列表,即主机id以逗号分隔;G@表示以grain格式描述, S@表示以IP子网或者地址格式描述。
  示例:探测webserver被控主机的连通性,如下:
# salt -N webserver test.ping  
web2:
  
    True
  
web1:
  
    True
  
#
  -C,--compound,根据条件运算符not、and、or去匹配不通规则的主机信息,示例 探测以we开头并且操作系统版本为CentOS的主机连通性。如下:
# salt -C 'E@^we.* and G@os:CentOS' test.ping  
web2:
  
    True
  
web1:
  
    True
  
#
  其中,not语句不能作为一个条件执行,不过可以通过以下方法来规避,示例:探测非SN开头的主机连通性,命令如下:
# salt -C '* and not E@^SN.*' test.ping  
web2:
  
    True
  
web1:
  
    True
  
#
  -S,--ipcidr,根据被控主机的IP地址或IP子网进行匹配。示例:
# salt -S 192.168.0.0/16 test.ping  
web1:
  
    True
  
web2:
  
    True
  
# salt -S 192.168.137.9 test.ping
  
web2:
  
    True
  
#
  三:Saltstack常用模块及API
  Saltstack提供了非常丰富的功能模块,涉及操作系统的基础功能,常用工具支持等,更多模块信息见官网模块介绍http://docs.saltstack.com/ref/modules/all/index.html。当然 也可以通过sys模块列出当前版本支持的模块 如下:
# salt 'web1' sys.list_modules  
web1:
  
    - acl
  
    - aliases
  
    - alternatives
  
    - apache
  
    - archive
  
    - artifactory
  
    - at
  
    - blockdev
  
    - bridge
  
    - btrfs
  
    - buildout
  
    - cloud
  
    - cmd
  
    - composer
  
    - config
  
    - container_resource
  
    - cp
  
    - cron
  
    - data
  
    - defaults
  
    - devmap
  
    - dig
  
    - disk
  
    - django
  
    - dnsmasq
  
    - dnsutil
  
    - drbd
  
    - elasticsearch
  
    - environ
  
    - etcd
  
    - event
  
    - extfs
  
    - file
  
    - gem
  
    - genesis
  
    - git
  
    - grains
  
    - group
  
    - grub
  
    - hashutil
  
    - hg
  
    - hipchat
  
    - hosts
  
    - http
  
    - img
  
    - incron
  
    - ini
  
    - introspect
  
    - ip
  
    - iptables
  
    - jboss7
  
    - jboss7_cli
  
    - key
  
    - kmod
  
    - locale
  
    - locate
  
    - logrotate
  
    - lowpkg
  
    - lvm
  
    - match
  
    - mine
  
    - modjk
  
    - mount
  
    - network
  
    - nginx
  
    - openstack_config
  
    - pagerduty
  
    - partition
  
    - pillar
  
    - pip
  
    - pkg
  
    - pkg_resource
  
    - postfix
  
    - ps
  
    - publish
  
    - pyenv
  
    - quota
  
    - raid
  
    - random
  
    - random_org
  
    - rbenv
  
    - ret
  
    - rsync
  
    - runit
  
    - rvm
  
    - s3
  
    - saltutil
  
    - schedule
  
    - scsi
  
    - sdb
  
    - seed
  
    - serverdensity_device
  
    - service
  
    - shadow
  
    - slack
  
    - smtp
  
    - sqlite3
  
    - ssh
  
    - state
  
    - status
  
    - supervisord
  
    - svn
  
    - sys
  
    - sysctl
  
    - syslog_ng
  
    - system
  
    - test
  
    - timezone
  
    - user
  
    - vbox_guest
  
    - virtualenv
  
    - webutil
  
    - xfs
  
#
  接下来抽取常见的模块进行介绍,同时也会列举模块的API使用方法。API的原理是通过调用master client模块,实例化一个LocalClient对象,再调用cmd()方法来实现的,一下是API实现的test.ping的示例:
import salt.client  
client = salt.client.LocalClient()
  
ret = client.cmd('web1','test.ping')
  
print ret
  结果以一个标准的Python字典形式的字符串返回,可以通过eval()函数转换成Python的字典类型,方便后续的业务逻辑处理,程序运行结果如下
{'WEB1': True}  【1 Archive模块】
  功能:实现系统层面的压缩包调用,支持gunzip gzip rar tar unrar unzip 等
  示例:
  采用gunzip解压/tmp/sourcefile.txt.gz包
salt '*' archive.gunzip /tmp/sourcefile.txt.gz  采用gzip压缩/tmp/sourcefile.txt文件
salt '*' archive.gzip /tmp/sourcefile.txt  
#运行结果如下:
  
# salt 'web1' archive.gzip /etc/nginx/nginx.conf
  
web1:
  
#
  

  
#web1节点的/etc/nginx/目录如下:
  
# ls
  
conf.d          koi-utfmime.typesnginx.conf.gz       scgi_params   win-utf
  
fastcgi_paramskoi-winmodules   nginx.conf.rpmsaveuwsgi_params
  
#
  API调用:
client.cmd('*','archive.gunzip',['/tmp/sourcefile.txt.gz'])  【2 cmd模块】
  功能:实现远程的命令调用执行 默认具备root操作权限,使用时需要评估风险
  示例:
  获取所有被控主机的内存使用情况
salt '*' cmd.run "free -m"  
#执行结果如下:
  
# salt '*' cmd.run "df -H"
  
web2:
  
    Filesystem            SizeUsed Avail Use% Mounted on
  
    /dev/mapper/vg_serv-lv_root
  
                           19G   12G6.0G66% /
  
    tmpfs               1.1G   13k1.1G   1% /dev/shm
  
    /dev/sda1             500M   84M386M18% /boot
  
web1:
  
    Filesystem            SizeUsed Avail Use% Mounted on
  
    /dev/mapper/vg_serv-lv_root
  
                           19G   12G6.0G66% /
  
    tmpfs               1.1G   13k1.1G   1% /dev/shm
  
    /dev/sda1             500M   84M386M18% /boot
  
#
  在web1主机运行test.sh脚本,其中script/test.sh存放在file_roots指定的目录,该命令会做两个动作,首先同步test.sh到minion的cache目录(如同步到/var/cache/salt/minion/files/base/script/test.sh);运行脚本:
salt 'web1' cmd.script salt://script/test.sh  
#创建 /srv/salt 目录,把调试好的 shell 脚本 test.sh 放到 /srv/salt 目录下
  
#执行结果如下:
  
# salt '*' cmd.script salt://test.sh
  
web1:
  
    ----------
  
    pid:
  
      21592
  
    retcode:
  
      0
  
    stderr:
  
    stdout:
  
      OK...........................
  
web2:
  
    ----------
  
    pid:
  
      2663
  
    retcode:
  
      0
  
    stderr:
  
    stdout:
  
      OK...........................
  
#
  API调用
client.cmd('web1','cmd.run',['free -m'])  【3 cp模块】
  功能:实现远程文件、目录的复制、以及下载URL文件等操作
  示例:
  将指定被控主机的/etc/hosts文件复制到被控主机本地的salt cache目录(/var/cache/salt/minion/localfiles)
salt '*' cp.cache_local_file /etc/hosts  将主服务器file_roots指定位置下的目录复制到被控机
salt '*' cp.get_dir salt://path/to/dir /minion/dest  
#本例复制一个名为nali的目录,先将目录复制到/srv/salt目录下:
  
#执行结果如下:
  
# salt '*' cp.get_dir salt://nali /etc
  
web2:
  
    - /etc/nali/INSTALL
  
    - /etc/nali/LICENSE
  
    - /etc/nali/Makefile
  
    - /etc/nali/README
  
    - /etc/nali/bin/nali
  
    - /etc/nali/bin/nali-dig
  
    - /etc/nali/bin/nali-nslookup
  
    - /etc/nali/bin/nali-ping
  
    - /etc/nali/bin/nali-tracepath
  
    - /etc/nali/bin/nali-traceroute
  
    - /etc/nali/bin/nali-update
  
    - /etc/nali/bin/qqwrynali
  
    - /etc/nali/config.h
  
    - /etc/nali/config.mak
  
    - /etc/nali/configure
  
    - /etc/nali/libqqwry/qqwry.c
  
    - /etc/nali/libqqwry/qqwry.h
  
    - /etc/nali/nali.c
  
    - /etc/nali/share/QQWry.Dat
  
    - /etc/nali/share/nali.pl
  
    - /etc/nali/share/nali.sh
  
web1:
  
    - /etc/nali/INSTALL
  
    - /etc/nali/LICENSE
  
    - /etc/nali/Makefile
  
    - /etc/nali/README
  
    - /etc/nali/bin/nali
  
    - /etc/nali/bin/nali-dig
  
    - /etc/nali/bin/nali-nslookup
  
    - /etc/nali/bin/nali-ping
  
    - /etc/nali/bin/nali-tracepath
  
    - /etc/nali/bin/nali-traceroute
  
    - /etc/nali/bin/nali-update
  
    - /etc/nali/bin/qqwrynali
  
    - /etc/nali/config.h
  
    - /etc/nali/config.mak
  
    - /etc/nali/configure
  
    - /etc/nali/libqqwry/qqwry.c
  
    - /etc/nali/libqqwry/qqwry.h
  
    - /etc/nali/nali.c
  
    - /etc/nali/share/QQWry.Dat
  
    - /etc/nali/share/nali.pl
  
    - /etc/nali/share/nali.sh
  
#
  将主服务器file_roots指定位置下的文件复制到被控机
salt '*' cp.get_file salt://path/to/file /mini/dest  
#文件和目录同理。
  下载URL内容到被控机指定位置
salt '*' cp.get_url http://www.salshdot.org /tmp/index.html  
#执行结果如下:
  
# salt '*' cp.get_url http://www.baidu.com /tmp/index.html
  
web2:
  
    /tmp/index.html
  
web1:
  
    /tmp/index.html
  
#
  API调用
client.cmd('*','cp.get_file',[' salt://path/to/file ',' /minion/dest'])  【4 cron模块】
  功能:实现被控主机的crontab清单.
  示例:
  查看指定被控主机 root用户的crontab清单
salt 'web1' cron.raw_cron root  
#执行结果如下:
  
# salt 'web1' cron.raw_cron root
  
web1:
  
    #Ansible: test_check
  
    * 5,2 * * * ls -l > /root/ll.txt
  
    #Ansible: test_checks
  
    * 5 * * * ls -l > /root/ll.txt
  
#
  为指定被控主机 root用户添加/usr/local/weekly任务作业
salt 'web1' cron.set_job root '*' '*' '*' '*' 1 /usr/local/weekly  
#运行结果如下:
  
# salt 'web1' cron.set_job root '*/5' '*' '*' '*' '*' "/bin/bash /etc/viewcpu.sh" viewcpu
  
web1:
  
    new
  
#
  

  
# web1任务如下:
  
# crontab -l
  
# Lines below here are managed by Salt, do not edit
  
# viewcpu
  
*/5 * * * * /bin/bash /etc/viewcpu.sh
  
#
  删除指定的被控主机 root用户crontab的/usr/local/weekly任务作业
salt 'web1' cron.rm_job root /usr/local/weekly  
#执行结果如下:
  
# salt 'web1' cron.rm_job root "/bin/bash /etc/viewcpu.sh"
  
web1:
  
    removed
  
#
  API调用
client.cmd('web1','cron.set_job',['root','*','*','*','*' 1,'/usr/local/weekly'])  【5 dnsutil模块】
  功能:实现被控主机通用DNS相关操作
  示例
  添加指定被控主机hosts的主机配置项
salt '*' dnsutil.hosts_append /etc/hosts 127.0.0.1 ad1.yuk.com,ad2.yuk.com  
#运行结果如下:
  
# salt '*' dnsutil.hosts_append /etc/hosts 127.0.0.1 www.a.com
  
web1:
  
    The following line was added to /etc/hosts:
  
    127.0.0.1 www.a.com
  
web2:
  
    The following line was added to /etc/hosts:
  
    127.0.0.1 www.a.com
  
#
  删除指定被控主机hosts的主机配置项
salt '*' dnsutil.hosts_remove /etc/hosts ad1.yuk.com  
#运行结果如下:
  
# salt '*' dnsutil.hosts_remove /etc/hosts www.a.com
  
web2:
  
    None
  
web1:
  
    None
  
#
  API调用
client.cmd('*','dnsutil.hosts_append',['/etc/hosts','127.0.0.1','ad1.yuk.com'])  【6 file模块】
  功能:被控主机文件常见操作,包括文件读写、权限、查找、效验等。
  示例:
  效验所有被控主机/etc/fstab文件的MD5是否为XXXXXXXXXXXXXXXXXX,一致则返回True
salt '*' file.check_hash /etc/fstab md5=XXXXXXXXXXXXXXXXXXXXXX  效验所有被控主机文件的加密信息支持MD5sha1 sha224 sha256 sha384 sha512如下:
salt '*' file.get_sum /etc/passwd md5  修改所后被控主机/etc/passwd文件的属组、用户权限、等价于 chown root:root /etc/passwd
salt '*' file.chown /etc/passwd root root  复制所有被控主机本地/path/to/src 文件到本地的
salt'*' file.copy/path/to/src /path/to/dest  
#运行结果如下:
  
# salt '*' file.copy /etc/fstab /tmp/fstab
  
web1:
  
    True
  
web2:
  
    True
  
#
  检查所有被控主机/etc目录是否存在,存在则返回True,检查文件是否存在使用file.file_exists方法
salt '*' file.directory_exists /etc  
#执行结果如下:
  
# salt '*' file.directory_exists /etc
  
web1:
  
    True
  
web2:
  
    True
  
#
  获取所有被控主机/etc/passwd的stats信息
salt '*' file.stats /etc/passwd  
#运行结果如下:
  
# salt 'web1' file.stats /etc/passwd
  
web1:
  
    ----------
  
    atime:
  
      1469920681.98
  
    ctime:
  
      1469920663.82
  
    gid:
  
      0
  
    group:
  
      root
  
    inode:
  
      677190
  
    mode:
  
      0644
  
    mtime:
  
      1469461866.61
  
    size:
  
      1253
  
    target:
  
      /etc/passwd
  
    type:
  
      file
  
    uid:
  
      0
  
    user:
  
      root
  
#
  获取所有被控主机 /etc/passwd的权限mode,如 755 644
salt '*' file.get_mode /etc/passwd  
#运行结果如下:
  
# salt '*' file.get_mode /etc/passwd
  
web1:
  
    0644
  
web2:
  
    0644
  
#
  修改所有被控主机/etc/passwd的权限为0644
salt '*' file.set_mode /etc/passwd 0644  在所有被控主机创建/opt/test目录
salt '*' file.mkdir /opt/test  
#执行结果如下:
  
# salt '*' file.mkdir /opt/testfile
  
web2:
  
    None
  
web1:
  
    None
  
#
  将所有被控主机/etc/httpd/httpd.conf文件的LogLevel参数的warn值修改为info
salt '*' file.sed /etc/httpd/httpd.conf 'LogLevel warn' 'LogLevel info'  给所有被控主机的/tmp/test/test.conf文件追加内容"Maxclient 100"
salt '*' file.append /tmp/test/test.conf "maxclient 100"  删除所有被控主机的/tmp/foo文件
salt '*' file.remove /tmp/foo  
#执行结果如下:
  
# salt '*' file.remove /opt/test
  
web1:
  
    True
  
web2:
  
    True
  
#
  API调用
client.cmd('*', 'file.remove ',['/tmp/foo'])  【7 iptables模块】
  功能:被控主机iptables支持
  示例:
  在所有被控制端主机追加(append)、插入(insert)iptables模块,其中INPUT为输入链,
salt '*' iptables.append filter INPUT rule='-m state --state RELATED,ESTABLISHE -j ACCEPT'  
salt '*' iptables.insert filter INPUT position=3 rule='-m state --state RELATED,ESTABLISHED -j ACCEPT'
  
运行结果如下:
  
# salt '*' iptables.append filter INPUT rule='-m state --state RELATED,ESTABLISHE -j ACCEPT'
  
web2:
  
    True
  
web1:
  
    True
  
#
  在所有被控端主机删除指定链编号为3(position=3)或指定存在的规则
salt '*' iptables.delete filter INPUT position=3  
salt '*' iptables.delete filter INPUT rule='-m state --state RELATED,ESTABLISHED -j ACCETP'
  保存所有被控端主机规则到本硬盘(/etc/sysconfig/iptables)
salt '*' iptables.save /etc/sysconfig/iptables  
#运行结果如下:
  
# salt '*' iptables.save /etc/sysconfig/iptables
  
web2:
  
    Wrote 1 lines to "/etc/sysconfig/iptables"
  
web1:
  
    Wrote 1 lines to "/etc/sysconfig/iptables"
  
#
  API调用:
client.cmd('web1','iptables.append',['filter','INPUT','rule=\'-p tcp --sport 80 -j ACCEPT\''])  【8 network模块】
  功能:返回被控主机网络信息
  示例:
  在指定被控主机'web'获取dig、ping 、traceroute 目录域名信息
salt 'web1' network.dig www.qq.com  
salt 'web1' network.ping www.qq.com
  
salt 'web1' network.traceroute
  
#运行结果如下:
  
# salt 'web1' network.dig www.qq.com
  
web1:
  

  
    ; <<>> DiG 9.8.2rc1-RedHat-9.8.2-0.47.rc1.el6 <<>> www.qq.com
  
    ;; global options: +cmd
  
    ;; Got answer:
  
    ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 4973
  
    ;; flags: qr rd ra; QUERY: 1, ANSWER: 3, AUTHORITY: 0, ADDITIONAL: 0
  

  
    ;; QUESTION SECTION:
  
    ;www.qq.com.                        IN      A
  

  
    ;; ANSWER SECTION:
  
    www.qq.com.         164   IN      A       59.37.96.63
  
    www.qq.com.         164   IN      A       14.17.32.211
  
    www.qq.com.         164   IN      A       14.17.42.40
  

  
    ;; Query time: 27 msec
  
    ;; SERVER: 114.114.114.114#53(114.114.114.114)
  
    ;; WHEN: Sun Jul 31 07:30:06 2016
  
    ;; MSG SIZErcvd: 76
  
# salt 'web1' network.ping www.qq.com
  
web1:
  
    PING www.qq.com (14.17.42.40) 56(84) bytes of data.
  
    64 bytes from 14.17.42.40: icmp_seq=1 ttl=53 time=3.94 ms
  
    64 bytes from 14.17.42.40: icmp_seq=2 ttl=53 time=4.06 ms
  
    64 bytes from 14.17.42.40: icmp_seq=3 ttl=53 time=7.13 ms
  
    64 bytes from 14.17.42.40: icmp_seq=4 ttl=53 time=4.76 ms
  

  
    --- www.qq.com ping statistics ---
  
    4 packets transmitted, 4 received, 0% packet loss, time 3011ms
  
    rtt min/avg/max/mdev = 3.941/4.976/7.132/1.284 ms
  获取指定被控主机'web1'的MAC地址
salt 'web1' network.hwaddr eth1  
#运行结果如下:
  
# salt 'web1' network.hwaddr eth1
  
web1:
  
    00:0c:29:7a:59:6d
  检查指定被控主机'web1'是否属于10.0.0.0/16子网范围 属于则返回True
salt 'web1' network.in_subnet 10.0.0.0/16  
#执行结果如下:
  
# salt 'web1' network.in_subnet 10.0.0.0/16
  
web1:
  
    False
  
# salt 'web1' network.in_subnet 192.168.0.0/16
  
web1:
  
    True
  获取指定被控主机'web1'的网卡配置信息
salt 'web1' network.interfaces  
#执行结果如下:
  
# salt 'web1' network.interfaces
  
web1:
  
    ----------
  
    eth1:
  
      ----------
  
      hwaddr:
  
            00:0c:29:7a:59:6d
  
      inet:
  
            |_
  
            ----------
  
            address:
  
                  192.168.137.8
  
            broadcast:
  
                  192.168.137.255
  
            label:
  
                  eth1
  
            netmask:
  
                  255.255.255.0
  
      inet6:
  
            |_
  
            ----------
  
            address:
  
                  fe80::20c:29ff:fe7a:596d
  
            prefixlen:
  
                  64
  
            scope:
  
                  link
  
      up:
  
            True
  
    lo:
  
      ----------
  
      hwaddr:
  
            00:00:00:00:00:00
  
      inet:
  
            |_
  
            ----------
  
            address:
  
                  127.0.0.1
  
            broadcast:
  
                  None
  
            label:
  
                  lo
  
            netmask:
  
                  255.0.0.0
  
      inet6:
  
            |_
  
            ----------
  
            address:
  
                  ::1
  
            prefixlen:
  
                  128
  
            scope:
  
                  host
  
      up:
  
            True
  
#
  获取指定被控主机'web1' 的IP地址配置信息
salt 'web1' network.ip_addrs  
#运行结果如下:
  
# salt 'web1' network.ip_addrs
  
web1:
  
    - 192.168.137.8
  
#
  获取指定别空主机'web1'的子网信息
salt 'web1' network.subnets  
#运行结果如下:
  
# salt 'web1' network.subnets
  
web1:
  
    - 192.168.137.0/24
  API调用
client.cmd('web1','network.ip_addrs')  【9 pkg包管理模块】
  功能:被控主机程序包管理如 yum.apt-get等。
  示例:
  为所有被控主机安装PHP环境,根据不同系统发行版调用不同安装工具进行部署,如REDHAT平台的yum,等价于yum -y install php
salt '*' pkg.install php  
#运行结果如下:
  
# salt '*' pkg.install gd-devel
  
web1:
  
    ----------
  
    fontconfig-devel:
  
      ----------
  
      new:
  
            2.8.0-5.el6
  
      old:
  
    freetype-devel:
  
      ----------
  
      new:
  
            2.3.11-17.el6
  
      old:
  
    gd-devel:
  
      ----------
  
      new:
  
            2.0.35-11.el6
  
      old:
  
    libX11-devel:
  
      ----------
  
      new:
  
            1.6.3-2.el6
  
      old:
  
    libXau-devel:
  
      ----------
  
      new:
  
            1.0.6-4.el6
  
      old:
  
    libXpm-devel:
  
      ----------
  
      new:
  
            3.5.10-2.el6
  
      old:
  
    libjpeg-turbo-devel:
  
      ----------
  
      new:
  
            1.2.1-3.el6_5
  
      old:
  
    libpng-devel:
  
      ----------
  
      new:
  
            2:1.2.49-2.el6_7
  
      old:
  
    libxcb-devel:
  
      ----------
  
      new:
  
            1.11-2.el6
  
      old:
  
    xorg-x11-proto-devel:
  
      ----------
  
      new:
  
            7.7-13.el6
  
      old:
  
...........................
  卸载所有被控主机的PHP环境
salt '*' pkg.remove php  
#运行结果如下:
  
# salt '*' pkg.remove php
  
web2:
  
    ----------
  
web1:
  
    ----------
  升级所有被控主机的软件包
salt '*' pkg.upgrade  API调用
client.cmd('*','pkg.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.status nginx
  

  
#运行结果如下:
  
# salt '*' service.enable httpd
  
web1:
  
    True
  
web2:
  
    True
  
# salt '*' service.disable httpd
  
web1:
  
    True
  
web2:
  
    True
  
# salt '*' service.start httpd
  
web1:
  
    True
  
web2:
  
    True
  
# salt '*' service.stop httpd
  
web1:
  
    True
  
web2:
  
    True
  
# salt '*' service.status httpd
  
web2:
  
    False
  
web1:
  
    False
  
#
  API调用
client.cmd('*','service.stop',['nginx'])  【11其他模块】
  通过上面的10个模块,基本上已经覆盖日常运维操作.Saltstack还提供了user(系统用户模块)、group(系统组模块)、partition(系统分区模块)、puppet(puppet管理模块)、system(系统重启关机模块)、timezone(时区管理模块)、nginx(Nginx管理模块)、mount(文件系统挂在模块)、等等,更多内容见官网介绍:http://docs.saltstack.com/ref/modules/all/index.html#all-salt-modules。当然,我们也可以通过Python扩展功能来满足要求。
  【grains】组件
  grains是Saltstack最重要的组件之一,grains的作用是收集被控主机的基本信息,这些信息通常都是一些静态的数据,包括CPU、内核、操作系统、虚拟化等,在服务器端可以根据这些信息进行灵活定制,管理管可以利用这些信息对不通业务进行个性化配置。官网提供的用来区分不同操作系统的示例如下:(采用jinja模板)
{% if grains['os'] == 'Ubuntu' %}  
host: {{ grains['host'] }}
  
{% elif grains['os'] == 'CentOS' %}
  
host: {{ grains['fqdn'] }}
  
{% endif %}
  示例中CentOS发行版主机将被" host:{{ grains['fqdn'] }}" 匹配,以主机web1(CentOS 6.4)为例,最终得到 " host:web1".同时,命令行的匹配操作系统发行版本为CentOS的被控端可以通过-G 参数来过滤,如
  salt -G 'os:CentOS' test.ping。
  【grains常用操作命令】
  匹配内核版本为4.6.3的主机:
  salt -G 'kernelrelease:4.6.3' cmd.run 'uname -a'
  运行结果如下:
# salt -G 'kernelrelease:4.6.3' cmd.run 'uname -a'  
web2:
  
    Linux web2 4.6.3 #1 SMP Wed Jun 29 06:29:23 CST 2016 x86_64 x86_64 x86_64 GNU/Linux
  
web1:
  
    Linux web1 4.6.3 #1 SMP Wed Jun 29 06:29:23 CST 2016 x86_64 x86_64 x86_64 GNU/Linux
  

  
# 过滤OS版本为x86_64位的系统
  
# salt -G 'osarch:x86_64' cmd.run 'uname -a'
  
web2:
  
    Linux web2 4.6.3 #1 SMP Wed Jun 29 06:29:23 CST 2016 x86_64 x86_64 x86_64 GNU/Linux
  
web1:
  
    Linux web1 4.6.3 #1 SMP Wed Jun 29 06:29:23 CST 2016 x86_64 x86_64 x86_64 GNU/Linux
  
#
  获取指定主机或者所有主机的grains信息
#运行结果如下:  
# salt 'web1' grains.ls
  
web1:
  
    - 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_codename
  
    - lsb_distrib_id
  
    - lsb_distrib_release
  
    - 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
  
    - virtual
  
    - zmqversion
  
#
  当然也可以获取主机单项grains数据 如获取操作系统发行版本,执行如下:
# salt '*' grains.item os  
web2:
  
    ----------
  
    os:
  
      CentOS
  
web1:
  
    ----------
  
    os:
  
      CentOS
  
#
  获取ID为 "web1"的所有grains键和值 如下:
# salt 'web1' grains.items  
web1:
  
    ----------
  
    SSDs:
  
    biosreleasedate:
  
      05/20/2014
  
    biosversion:
  
      6.00
  
    cpu_flags:
  
      - fpu
  
      - vme
  
      - de
  
      - pse
  
      - tsc
  
      - msr
  
      - pae
  
      - mce
  
      - cx8
  
      - apic
  
      - sep
  
      - mtrr
  
      - pge
  
      - mca
  
      - cmov
  
      - pat
  
      - pse36
  
      - clflush
  
      - dts
  
      - mmx
  
      - fxsr
  
      - sse
  
      - sse2
  
      - ss
  
      - syscall
  
      - nx
  
      - rdtscp
  
      - lm
  
      - constant_tsc
  
      - arch_perfmon
  
      - pebs
  
      - bts
  
      - nopl
  
      - xtopology
  
      - nonstop_tsc
  
      - aperfmperf
  
      - eagerfpu
  
      - pni
  
      - pclmulqdq
  
      - ssse3
  
      - cx16
  
      - pcid
  
      - sse4_1
  
      - sse4_2
  
      - x2apic
  
      - popcnt
  
      - tsc_deadline_timer
  
      - aes
  
      - xsave
  
      - avx
  
      - f16c
  
      - rdrand
  
      - hypervisor
  
      - lahf_lm
  
      - epb
  
      - fsgsbase
  
      - tsc_adjust
  
      - smep
  
      - dtherm
  
      - ida
  
      - arat
  
      - pln
  
      - pts
  
    cpu_model:
  
      Intel(R) Core(TM) i7-3520M CPU @ 2.90GHz
  
    cpuarch:
  
      x86_64
  
    domain:
  
      gov.cn
  
    fqdn:
  
      web1.gov.cn
  
    fqdn_ip4:
  
      - 192.168.137.8
  
    fqdn_ip6:
  
    gpus:
  
      |_
  
          ----------
  
          model:
  
            SVGA II Adapter
  
          vendor:
  
            unknown
  
    host:
  
      web1
  
    hwaddr_interfaces:
  
      ----------
  
      eth1:
  
            00:0c:29:7a:59:6d
  
      lo:
  
            00:00:00:00:00:00
  
    id:
  
      web1
  
    init:
  
      upstart
  
    ip4_interfaces:
  
      ----------
  
      eth1:
  
            - 192.168.137.8
  
      lo:
  
            - 127.0.0.1
  
    ip6_interfaces:
  
      ----------
  
      eth1:
  
            - fe80::20c:29ff:fe7a:596d
  
      lo:
  
            - ::1
  
    ip_interfaces:
  
      ----------
  
      eth1:
  
            - 192.168.137.8
  
            - fe80::20c:29ff:fe7a:596d
  
      lo:
  
            - 127.0.0.1
  
            - ::1
  
    ipv4:
  
      - 127.0.0.1
  
      - 192.168.137.8
  
    ipv6:
  
      - ::1
  
      - fe80::20c:29ff:fe7a:596d
  
    kernel:
  
      Linux
  
    kernelrelease:
  
      4.6.3
  
    locale_info:
  
      ----------
  
      defaultencoding:
  
            UTF8
  
      defaultlanguage:
  
            en_US
  
      detectedencoding:
  
            UTF-8
  
    localhost:
  
      web1
  
    lsb_distrib_codename:
  
      Final
  
    lsb_distrib_id:
  
      CentOS
  
    lsb_distrib_release:
  
      6.8
  
    machine_id:
  
      64583632c20bdf7e7fce37f80000001f
  
    manufacturer:
  
      VMware, Inc.
  
    master:
  
      192.168.137.7
  
    mdadm:
  
    mem_total:
  
      1989
  
    nodename:
  
      web1
  
    num_cpus:
  
      1
  
    num_gpus:
  
      1
  
    os:
  
      CentOS
  
    os_family:
  
      RedHat
  
    osarch:
  
      x86_64
  
    oscodename:
  
      Final
  
    osfinger:
  
      CentOS-6
  
    osfullname:
  
      CentOS
  
    osmajorrelease:
  
      6
  
    osrelease:
  
      6.8
  
    osrelease_info:
  
      - 6
  
      - 8
  
    path:
  
      /sbin:/usr/sbin:/bin:/usr/bin
  
    productname:
  
      VMware Virtual Platform
  
    ps:
  
      ps -efH
  
    pythonexecutable:
  
      /usr/bin/python2.6
  
    pythonpath:
  
      - /usr/bin
  
      - /usr/lib64/python26.zip
  
      - /usr/lib64/python2.6
  
      - /usr/lib64/python2.6/plat-linux2
  
      - /usr/lib64/python2.6/lib-tk
  
      - /usr/lib64/python2.6/lib-old
  
      - /usr/lib64/python2.6/lib-dynload
  
      - /usr/lib64/python2.6/site-packages
  
      - /usr/lib64/python2.6/site-packages/gtk-2.0
  
      - /usr/lib/python2.6/site-packages
  
      - /usr/lib/python2.6/site-packages/setuptools-0.6c11-py2.6.egg-info
  
    pythonversion:
  
      - 2
  
      - 6
  
      - 6
  
      - final
  
      - 0
  
    saltpath:
  
      /usr/lib/python2.6/site-packages/salt
  
    saltversion:
  
      2015.5.10
  
    saltversioninfo:
  
      - 2015
  
      - 5
  
      - 10
  
      - 0
  
    selinux:
  
      ----------
  
      enabled:
  
            False
  
      enforced:
  
            Disabled
  
    serialnumber:
  
      VMware-56 4d f6 e1 93 65 b0 56-00 55 6f 82 99 7a 59 6d
  
    server_id:grains:
  
      967878355
  
    shell:
  
      /bin/sh
  
    virtual:
  
      VMware
  
    zmqversion:
  
      3.2.5
  
#
  【定义grains数据】
  定义grains数据的方法有两种,其中一种为在被控主机定制配置文件,另一种是通过主控端扩展模块API实现,区别是模块更领廓,可以通过Python编程动态定义,而且配置文件只合适相对固定的键值 下面说明
  1 被控端主机定制grains数据
  SSH登录一台被控主机,如 "web1",配置文件定制的路径为/etc/salt/minion,参数为default_include:minion.d/*.conf
  
grains:  
roles:
  
    - webserver
  
    - memcache
  
deployment: datacenter4
  
cabinet: 13
  重启被控主机salt-minion服务,使其生效:service salt-minion restart。验证结果在主控端主机运行
  salt 'web1' grains.item roles deployment cabinet
# salt 'web1' grains.item roles deployment cabine  
web1:
  
    ----------
  
    cabine:
  
    deployment:
  
      datacenter4
  
    roles:
  
      - webserver
  
      - memcache
  
#
  【2 主控端扩展模块定制grains数据】
  首先在主控端编写Python代码 然后将改Python文件同步到被控主机,最后刷新生效 在主控端base目录(/srv/salt)下生成_grains目录,执行 install -d /srv/salt/_grains开始编写代码,实现获取被控主机系统允许最大打开文件数(ulimit -n)的grains数据
  【/srv/salt/_grains/grains_openfile.py】
import os,sys,commands  
def Grains_openfile():
  
   """
  
       return os max open file of grains value
  
   """
  
   grains = {}
  

  
   #init default value
  
   _open_file=65536
  

  
   try:
  
       getulimit=commands.getstatusoutput('source /etc/profile;ulimit -n')
  
   except Exception,e:
  
       pass
  
   if getulimit==0:
  
       _open_file=int(getulimit)
  
   grains['max_open_file'] = _open_file
  
   return grains
  代码说明如下:
  grains_openfile() 定义一个获取最大打开文件数的函数,名称没有要求 符合Python的函数规则即可
  grains = {} 初始化一个grains字典、变量名一定要用grains 一般Saltstack识别;
  grains['max_open_file'] = _open_file 将获取的Linux ulimit -n的结果值赋予grains['max_open_file'],其中 "max_open_file"就是grains的项,_open_file就是grains的值。
  最后同步模块到指定被控端主机并刷新生效,因为grains比较合适采集静态的数据,比如硬件、内核信息等。当有动态类的功能需求时,需要提行刷新,具体如下:
  同步模块salt 'web1' saltutil.sync_all,看看web1主机上发生了什么?文件已经同步到minion cache目录中,如下:
/var/cache/salt/minion/extmods/grains/grains_openfile.py  
/var/cache/salt/minion/files/base/_grains/grains_openfile.py
  /var/cache/salt/minion/extmods/grains 为扩展模块文件最终存放位置,刷新魔窟后将在同路径下生成字节码pyc /var/cache/salt/minion/files/base/_grains 为临时存放目录。
  刷新模块 salt 'web1' sys.reload_modules, 再看看主机发生了什么变化?在/var/cache/salt/minion/extmods/grains位置多了一个编译后的字节码文件 grains_openfile.pyc文件,为Python可执行的格式
/var/cache/salt/minion/extmods/grains/grains_openfile.py  
/var/cache/salt/minion/extmods/grains/grains_openfile.pyc
  
/var/cache/salt/minion/files/base/_grains/grains_openfile.py
  效验结果为可以在主控端查看grains信息,执行 salt 'web1' grains.item max_open_file,结果显示 "max_open_file:65535"这个就是前面定制的主机grains信息。
web1:  
max_open_file: 65535
  【pillar组件】
  pillar也是Saltstack最重要的组件之一,其租用是定义与被控端主机相关的任何数据,定义好的数据可以被其他组件使用,如模板、API等。在pillar中定义的数据与不同业务特性的被控主机相关联,这样不同的被控主机只能看到自己匹配的数据,因此pillar安全性很高,使用一些比较敏感的数据,这也是区别于grains最关键的一点,如果定义不同业务组主机的用户id、组id、读写权限、程序包等信息,定义的规范是采用Python字典形式,即 键/值,最上层的键一般为主机的id或组名称。下面详细描述如何进行pillar的定义和使用。
  【pillar的定义】

[*]  主配置文件定义
  Saltstack默认将主控端配置文件中的所有数据都定义到pillar中,而且对所有被控主机开发,可以通过修改/etc/salt/master配置中的pillar_opts:True 或者 false 来定义是否开启或禁用这项功能,修改后执行
  salt '*' pillar.data 来观察效果。如下代码 为pillar_opts:True 的返回结果,以主机web1 为例。执行如下:
# salt 'web1' pillar.data  
web1:
  
    ----------
  
    master:
  
      ----------
  
      __role:
  
            master
  
      auth_mode:
  
            1
  
      auto_accept:
  
            True
  
      cache_sreqs:
  
            True
  
      cachedir:
  
            /var/cache/salt/master
  
      cli_summary:
  
            False
  
      client_acl:
  
            ----------
  
      client_acl_blacklist:
  
            ----------
  
      cluster_masters:
  
      cluster_mode:
  
            paranoid
  
      con_cache:
  
            False
  
      conf_file:
  
            /etc/salt/master
  
      config_dir:
  
            /etc/salt
  
      cython_enable:
  
            False
  
      daemon:
  
            True
  
      default_include:
  
            master.d/*.conf
  
      enable_gpu_grains:
  
            False
  
      enforce_mine_cache:
  
            False
  
      enumerate_proxy_minions:
  
            False
  
      environment:
  
            None
  
      event_return:
  
      event_return_blacklist:
  
      event_return_queue:
  
            0
  
      event_return_whitelist:
  
      ext_job_cache:
  
      ext_pillar:
  
      extension_modules:
  
            /var/cache/salt/extmods
  
      external_auth:
  
            ----------
  
.................省略......................
  【SLS文件定义】
  pillar支持在sls文件中定义数据,格式须符合YAML规范,与Saltstack的state组件十分相似,容易混淆,两者文件的配置格式、入口文件top.sls都是一致的。下面详细介绍pillar使用sls定义的配置过程。

[*]  定义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
  通过查看"web1"主机的pillar数据,可以看到了多出data.sls数据项,原因是我们定义top.sls时适用"*"覆盖了所有主机,这样当查看web1的pillar数据时可以看到我们定义的数据。如果结果不符合预期,可尝试刷新被控主机的pillar数据,运行 salt '*' saltutil.refresh_pillar
# salt 'web1' pillar.data appname flow  
web1:
  
    ----------
  
    appname:
  
      website
  
    flow:
  
      ----------
  
      maxconn:
  
            30000
  
      maxmem:
  
            6G
  
#
  【pillar的使用】
  完成pillar配置后,接下来介绍使用方法。我们可以在state、模块文件中引用,模板格式为:
  "{{ pillar 变量}}",例如:
{{ pillar['appname'] }}#一级字典  
{{ pillar['flow']['maxconn'] }} #二级字典
  
{{ salt['pillar.get']('flow:maxconn',{}) }}
  Python API格式如下:
pillar['flow']['maxconn']  
pillar.get('flow:appname', {})

[*]  操作目标主机,通过-I 选项是使用pillar来匹配被控主机:
#salt -I 'appname:website' test.ping  
web1:
  
   True
  
web2:
  
   True
  2 .结合grains处理数据的差异性
  首先通过结合grains的id信息来区分不同的id的maxcpu的值,其次进行引用观察的信息,延伸pillar的例子,将data.sls修改成如下形状,其中 " if....else....endfi"为jinja2的模块语法,更多信息请访问jinja2的官方语法介绍。http://jinja.pocoo.org/docs/template/。
appname: website  
flow:
  
   maxconn: 30000
  
   maxmem: 6G
  
   {% if grains['id'] == 'web1' %}
  
   maxcpu: 8
  
   {% else %}
  
   maxcpu: 4
  
   {% endif %}
  通过查看被控主机的pillar数据,可以看到maxcpu的差异。 如下代码
# salt '*' pillar.data appname flow  
web2:
  
    ----------
  
    appname:
  
      website
  
    flow:
  
      ----------
  
      maxconn:
  
            30000
  
      maxcpu:
  
            8
  
      maxmem:
  
            6G
  
web1:
  
    ----------
  
    appname:
  
      website
  
    flow:
  
      ----------
  
      maxconn:
  
            30000
  
      maxcpu:
  
            16
  
      maxmem:
  
            6G
  
#
  State介绍
  state是Saltstack最核心的功能,通过预先定制好的sls(salt state file)文件对对被控主机进行状态管理,支持包括程序包(pkg)、文件(file)、网络配置(network)、系统服务(service)、系统用户(user)等,更多状态对象见http://docs.saltstack.com/ref/states/all/index.html。
  【1 state的定义】
  state的定义时通过sls文件进行描述的,支持YAML语法,定义的规则如下:
  $ID:
  $State:
  - $state: states
  其中:
  $ID : 定义state的名称,通常采用与描述的对象保持一致的方法,如Apache,nginx等
  $State:须管理对象的类型,详见http://docs.saltstack.com/ref/states/all/index.html;
  $state:states 定制对象的状态。
  官网提供的示例如下:
1 apache:  
2    pkg:
  
3       - installed
  
4    service:
  
5       - running
  
6       - require:
  
7       - pkg: apache
  上述代码检查Apache软件包是否已经安装状态,如果未安装,将通过yum或apt进行安装;检查服务Apache的进程是否处于运行状态。下面进行进行说明:
  第1行用户定义state的名称,此示例为Apache,当然也可以取其他相关的名称。
  第2和4行表示state声明的开始,使用pkg和service这两个状态对象。pkg使用系统本地的软件包管理器(yum或apt)管理将要安装的软件,service管理系统守护进程。
  第3和5行是要执行的方法,这些方法定义了Apache软件包和服务目标状态,此示例要求软件包应当处于已安装状态,服务器必须运行,如未安装将会被安装并启动。
  第6行是关键字require,它确保了Apache服务只有在成功安装软件包后才会启动。
  注意: require:在运行此state前,先运行依赖的state关系检查,可以配置多个state依赖对象;watch: 在检查某个state发生变化时运行此模块。
  【2state的使用】
  state的入口文件与pillar一样,文件名都是top.sls,但state要求sls文件必须放在Saltstack base定义的目录下,默认为/src/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也采用如此方式。
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 %}
  测试pillar数据,执行salt '*' pillar.data pkgs 结果返回一下信息,说明配置已生效。
web1:  
   ----------
  
   pkgs:
  
       ----------
  
       apache:
  
         httpd
  定义state
  【/srv/salt/top.sls】
base:  
   '*':
  
   - apache
  【/srv/salt/apcahe/init.sls】
apache:  
    pkg:
  
      - installed
  
      - name: {{ pillar['pkgs']['apache'] }}
  
    service.running:
  
      - name: {{ pillar['pkgs']['apache'] }}
  
      - require:
  
      - pkg: {{ pillar['pkgs']['apache'] }}
  在配置中,{{ pillar['pkgs']['apahce'] }}将引用匹配到操作系统发行本版对应的pillar数据,本例的环境为CentOS,故将匹配为httpd,检查目标主机是否已经安装,没有则进行安装 (yum -y install httpd) 同时检查Apache服务是否已经启动,没有则启动(/etc/init.d/httpd start)
  3 执行state及返回结果信息 如下代码 用vsftpd做了示例
# salt '*' state.highstate  
web1:
  
----------
  
          ID: vsftpd
  
    Function: pkg.installed
  
      Name: vsftpd
  
      Result: True
  
   Comment: The following packages were installed/updated: vsftpd
  
   Started: 22:47:51.599478
  
    Duration: 16282.604 ms
  
   Changes:
  
            ----------
  
            vsftpd:
  
                  ----------
  
                  new:
  
                      2.2.2-21.el6
  
                  old:
  
----------
  
          ID: vsftpd
  
    Function: service.running
  
      Name: vsftpd
  
      Result: True
  
   Comment: Started Service vsftpd
  
   Started: 22:48:07.892523
  
    Duration: 275.246 ms
  
   Changes:
  
            ----------
  
            vsftpd:
  
                  True
  

  
Summary
  
------------
  
Succeeded: 2 (changed=2)
  
Failed:    0
  
------------
  
Total states run:   2
  
web2:
  
----------
  
          ID: vsftpd
  
    Function: pkg.installed
  
      Name: vsftpd
  
      Result: True
  
   Comment: The following packages were installed/updated: vsftpd
  
   Started: 22:47:50.835836
  
    Duration: 19862.871 ms
  
   Changes:
  
            ----------
  
            vsftpd:
  
                  ----------
  
                  new:
  
                      2.2.2-21.el6
  
                  old:
  
----------
  
          ID: vsftpd
  
    Function: service.running
  
      Name: vsftpd
  
      Result: True
  
   Comment: Started Service vsftpd
  
   Started: 22:48:10.701113
  
    Duration: 126.012 ms
  
   Changes:
  
            ----------
  
            vsftpd:
  
                  True
  

  
Summary
  
------------
  
Succeeded: 2 (changed=2)
  
Failed:    0
  
------------
  
Total states run:   2
  
#
页: [1]
查看完整版本: Saltstack 简单入门