saltstack系统中管理对象叫作Target,在master上能够采用不一样的Tatget去管理不一样的minion。这些Target都是经过去管理和匹配Minion的ID来作一些集合。php
# salt -E '[a-z].*' test.ping #直接就是匹配字母开头的minionnode
# salt -E 'a.*' test.ping #匹配a开头的minionmysql
# salt -E '(a|z).*' test.ping #匹配a或者z开头的minion,切记是开头而不是包含。web
#salt -L 'dasha_ceshi_172.16.5.239,dasha_ceshi_172.16.5.240' test.ping ##同时让多个minion去执行,多minion之间用逗号隔开(这里只是ID,组的不行)。正则表达式
minions的Grains信息时在Minions服务启动的时候汇总给Master的,Grains是saltstack组建中很是重要的,由于在配置部署的过程当中会常用它,Grains是saltstack记录minion的一些静态信息的组件,grains里面记录着每台minion的一些经常使用属性如CPU、内存、操做系统类型和版本等,能够经过grains.item查看某台minion的全部grains信息。sql
# salt -G 'os:CentOS' test.ping #让minion端操做系统是CentOS去执行,固然也支持正则表达式的方式shell
# salt -G 'os:C*' test.ping #如匹配操做系统是C开头的apache
# salt -G 'osmajorrelease:[1-9]' test.ping #匹配系统版本是数字的。centos
cat /etc/salt/master | grep nodegroups
这里还可使用正则及其余匹配方式,我这里写的是最简单,也是最繁琐的一种。安全
nodegroups: ceshi1: dasha_ceshi_172.16.5.239 ceshi2: dasha_ceshi_172.16.5.240
#salt -N ceshi1 test.ping #测试test这组。
解释:复合匹配的意思是,使用不一样的判断条件精准的在指定的minion中执行。
#salt -C 'G@os:CentOS and G@osmajorrelease:7' test.ping #让os是CentOS而且系统版本是7的去执行 #salt -C 'G@os:CentOS and G@osmajorrelease:7 and E@dasha_ceshi*' test.ping # 在操做系统是CentOS版本是7,而且id开头是dasha_ceshi的机器是执行test.ping操做。
[root@bogon ~]# salt -S '172.16.5.0/24' test.ping #匹配IP是172.16.5.0网段的的全部IP地址,执行test.ping操做 dasha_ceshi_172.16.5.240: True dasha_ceshi_172.16.5.239: True [root@bogon ~]# salt -S '172.16.5.239' test.ping #在IP是172.16.5.239服务器上执行test.ping操做。 dasha_ceshi_172.16.5.239: True
Grains上面已经介绍过了,相似于facter。简单的说就是把minion端在启动的时候把自身的的各类属性信息采集汇报给master端,可使用 salt ‘id’ grains.items查看。
# salt '*' grains.ls #能够查看有哪些属性能够查看,显示的是属性的名字,相似于os之类的。
#salt 'dasha_ceshi_172.16.5.239' grains.item os osrelease oscodename ##知道了属性的名称,咱们就能够查看属性的值,这里就是查看os,osrelease,oscodename这三个属性的值,多属性用空格隔开。
# salt '*' grains.items #这种就是将全部minion端属性以及属性的值全打印出来,建议打印是指定某个minion id,不然打印的东西太多。
上面咱们说了,在master上执行grains.items能查看到不少minion的参数,可是好比设备的具体位置,业务名称等信息就显的力不从心了,可是有了minion自定义grains后,就没有那么难了。
minion端的操做:
grains: #以grains开头 roles: #设置一个属性叫roles,下面若是多条就像下面同样- value值,这里的意思是标注服务器属于什么业务 - webserver - memcache deployment: bj-zb-5F #这里是标注所在机房的位置 cabinet: B11 #标注所在机柜的位置 cab_u: 19-21 #标注所在机柜的U位
# systemctl restart salt-minion #上面已经说了,grains信息是在minion端启动的时候才会发送,因此要重启minion端。
master端的查看:
# salt 'dasha_ceshi_172.16.5.240' grains.ls #用这个查看会发现咱们自定义的哪几个grains的属性已经出现了。
#salt '*' grains.item roles deployment cabinet cab_u #查看咱们在minion自定义的grains信息。
#salt 'dasha_ceshi_172.16.5.239' grains.append purpose 'ceshi' #经过grains.append方法为dasha_ceshi_172.16.5.239机器添加了一个属性,purpose 用途,后面跟的值是ceshi,注意空格和引号。
这种自定义的方法配置文件位置再minion的/etc/salt/grains配置文件中,永久生效,删除的话,能够直接去minion操做。还可使用其余的方法,如grains.setvals来定义多个属性,或者还能够删除自定义的grains。这都是立马生效并永久生效的。
Pillar是saltstack组件中很是重要的一个,是数据管理中心,常常配合states在大规模的配置管理工做中使用它,它的主要做用是存储和定义配置管理中须要的一些数据。它的定义存储格式跟grains相似,都是YAML格式。
下面的操做都是在master端的操做:
# mkdir /srv/pillar #这是master配置文件里面#pillar_roots:默认指定的路径。默认不存在须要手工建立。 # cat /srv/pillar/top.sls #top.sls是配置管理的入口文件,一切都是从这里开始,这里是默认位置,在这里定义谁来执行那个方法或者说模块。 base: #top.sls 默认从 base 标签开始解析执行,下一级是操做的目标,能够经过正则,grain模块,或分组名,来进行匹配,再下一级是要执行的state文件,不包换扩展名。 '*': - pkgs # cat /srv/pillar/pkgs.sls #一个简单的根据minion端的grains信息,动态的设置apache软件包对应的name名称。前面咱们学习saltstack的minion,咱们知道给客户端定义新的属性时候,是须要在客户端文件加内容的,可是pillar则是在服务器给客户端定义新属性,并且不用重启服务, pkgs: {% if grains['os_family'] == 'RedHat' %} apache: httpd {% elif grains['os_family'] == 'Debian' %} apache: apache2 {% elif grains['os'] == 'Arch' %} apache: apache {% endif %} # salt '*' pillar.item pkgs
有结果来看,pillar数据是在Salt master上生成的并被安全地分布到minions上。Salt当定义pillar的时候,没必要限制在sls文件,也能够从外部资源得到数据,咱们能够把Pillar数据。pillar中最强大的抽象之一就是将states参数化的能力。
States是SaltStack中的配置语言,在平常进行配置管理时须要编写大量的States文件。如安装软件啊,更改配置啊等,就须要编写states sls文件(描述状态配置的文件)去描述和实现这些功能。编写states sls文件通常是是YAML语法格式,也支持使用Python语言来编写。
#salt 'dasha_ceshi_172.16.5.239' sys.list_state_modules ##查看minion支持的全部states列表。
1 - acl 2 - alias 3 - alternatives 4 - archive 5 - artifactory 6 - beacon 7 - bigip 8 - blockdev 9 - buildout 10 - ceph 11 - chronos_job 12 - cloud 13 - cmd 14 - composer 15 - cron 16 - cryptdev 17 - csf 18 - disk 19 - elasticsearch 20 - elasticsearch_index 21 - elasticsearch_index_template 22 - environ 23 - esxdatacenter 24 - etcd 25 - ethtool 26 - event 27 - file 28 - firewall 29 - firewalld 30 - gem 31 - glassfish 32 - gnomedesktop 33 - gpg 34 - grafana4_dashboard 35 - grafana4_datasource 36 - grafana4_org 37 - grafana4_user 38 - grains 39 - group 40 - highstate_doc 41 - hipchat 42 - host 43 - http 44 - incron 45 - infoblox_a 46 - infoblox_cname 47 - infoblox_host_record 48 - infoblox_range 49 - ini 50 - ipset 51 - iptables 52 - jboss7 53 - jenkins 54 - junos 55 - k8s 56 - kernelpkg 57 - keyboard 58 - kmod 59 - ldap 60 - libcloud_dns 61 - libcloud_loadbalancer 62 - libcloud_storage 63 - locale 64 - logrotate 65 - loop 66 - lxc 67 - marathon_app 68 - modjk 69 - modjk_worker 70 - module 71 - mount 72 - msteams 73 - network 74 - nexus 75 - openstack_config 76 - opsgenie 77 - pagerduty 78 - pagerduty_escalation_policy 79 - pagerduty_schedule 80 - pagerduty_service 81 - pagerduty_user 82 - pkg 83 - pkgbuild 84 - pkgng 85 - pkgrepo 86 - powerpath 87 - process 88 - pushover 89 - pyenv 90 - rbenv 91 - rvm 92 - salt 93 - salt_proxy 94 - schedule 95 - serverdensity_device 96 - service 97 - slack 98 - smtp 99 - solrcloud 100 - sqlite3 101 - ssh_auth 102 - ssh_known_hosts 103 - stateconf 104 - status 105 - statuspage 106 - supervisord 107 - sysctl 108 - syslog_ng 109 - telemetry_alert 110 - test 111 - timezone 112 - tuned 113 - uptime 114 - user 115 - vault 116 - vbox_guest 117 - virtualenv 118 - winrepo 119 - zenoss
#salt 'dasha_ceshi_172.16.5.239' sys.list_state_functions file host ##查看file和host的全部function,多模块用空格隔开
1 dasha_ceshi_172.16.5.239: 2 - file.absent 3 - file.accumulated 4 - file.append 5 - file.blockreplace 6 - file.cached 7 - file.comment 8 - file.copy 9 - file.decode 10 - file.directory 11 - file.exists 12 - file.line 13 - file.managed 14 - file.missing 15 - file.mknod 16 - file.mod_run_check_cmd 17 - file.not_cached 18 - file.patch 19 - file.prepend 20 - file.recurse 21 - file.rename 22 - file.replace 23 - file.retention_schedule 24 - file.sdecode 25 - file.serialize 26 - file.shortcut 27 - file.symlink 28 - file.touch 29 - file.uncomment 30 - host.absent 31 - host.only 32 - host.present
# salt 'agent1.salt' sys.list_state_modules #查看minion支持的全部states列表。
# salt 'agent1.salt' sys.list_state_functions file host #查看file和host的全部function,多模块用空格隔开
# salt 'agent1.salt' sys.state_doc file #查看指定模块的function的用法与例子,平常编写states按照例子编写即可。
# salt 'agent1.salt' sys.state_doc file.managed #查看file.managed的详细用法与例子,这也是咱们常常用到的function。
如今咱们有个需求,往minion的特定目录下传一个配置文件,前面咱们说过使用cp.get_file方法就能够传文件,可是咱们常常要给某些minion传特定的配置文件的话,使用state的文件传送就很方便。
首先咱们先来看一下master里面state路径定义的方法,咱们一共定义了三个路径,base是必需要有的,剩下的随意,注意空格。注意:salt://这几个字符分别表明了里面的三个路径,好比salt://file/test,绝对路径就是/srv/salt/base/file/test,/srv/salt/prod/file/test,/srv/salt/test/file/test。
分别建立配置文件里面的三个路径,最后完成后必定要重启master服务。
如今咱们来看看写法,首先你要定义个须要传送到客户端的文件,能够新建,随便写点内容便可,首先咱们分析一下基本环境,只须要看你标红位置便可。
我在base里面又新建了一个目录files,我把my.cnf配置文件放在了这里面,而后我在base下面新建了衣蛾cp_file.sls文件,在这个文件中写了点传送文件的内容。
基本写法介绍:
cp-file-my.cnf: #惟一表示ID file.managed: #方法,我用哪一个方法,这里用file.managed方法传送文件 - name: /root/my.cnf #目标机器上的哪一个文件,必定要加文件名。 - source: salt://files/my.cnf #master端的路径,上线咱们说过,这里的绝对路径是/srv/salt/base/files/my.cnf - user: root #文件属主 - group: root #文件属组 - mode: 644 #文件权限 注意:salt全部配置文件里面禁止用tab键,层级关系用两个空格隔开,-符号后面还有个空格,例如- name: 冒号后面也得有空格。
写好具体要作什么之后,这里要发送了
#state.sls是用state.sls这个方法,cp_file是只cp_file.sls这个文件,这里去掉文件.后面的内容便可,test=True指先测试一下,若是肯定要发送的话,去掉test=True便可。 salt '*' state.sls cp_file test=True
这里可能有同窗要说了,好麻烦啊,我直接scp过去就ok了,你这里还得写这么东东西,别着急,若是有1000台机器,你也一个一个scp么,而这里我只须要匹配哪些服务器须要便可。
#若是你源文件没有发生改变,再次执行的话,Comment会提示你这个文件是正确的。Changes:下面没内容。Succeeded: 1,这就是区别,也就是不更新
SLS(表明SaLt State文件)是Salt State系统的核心。SLS描述了系统的目标状态,由格式简单的数据构成。这常常被称做配置管理,简单的讲就说你写了那么多的路径和sls文件,到底要让谁来执行top里面能够写谁来执行哪些sls文件。
由于咱们用YAML格式来编写sls文件,因此掌握编写技巧利于后面少出错。
5.1.1 什么是YAML?
YAML 语言(发音 /ˈjæməl/ )的设计目标,就是方便人类读写。它实质上是一种通用的数据串行化格式。语法很简单,结构经过空格来展现,项目使用“-”来表明,键值对使用“:”分隔。
它的基本语法规则以下:
大小写敏感,以“:”来分隔key和value。对象:键值对的集合,又称为映射(mapping)/ 哈希(hashes) / 字典(dictionary)。
使用固定的缩进风格表示层级关系。缩进时不容许使用Tab键,只容许使用空格,通常每一个缩进级别由两个空格组成。
# 表示注释,从这个字符一直到行尾,都会被解析器忽略。
想要表示列表项,使用一个短横杠加一个空格。多个项目使用一样的缩进级别做为同一列表的一部分。列表能够做为一个键值对的value。
top.sls是配置管理的入口文件,这个很重要在生产中很重要,默认存放在/srv/salt/目录.默认从base标签开始解析执行,下一级是操做的目标也就是要对哪些主机进行操做,能够经过正则、grain模块或分组名等来进行匹配,而后再下一级是要执行的state文件(不包含.sls扩展名)。
基本写法1:
首先top文件必须写在base环境下,必需要叫top.sls,而后咱们看一下基本写法:
base: #下面的sls在哪一个路径这里就写什么 'dasha_ceshi_172.16.5.239' #哪一个minion去执行 - cp_file #执行哪一个方法
基本写法2:
base: 'dasha_ceshi_172.16.5.239' - cp_file 'dasha_ceshi_172.16.5.240' - cp_file
正则写法1:
base: #下面的sls在哪一个路径这里就写什么 'dasha_ceshi*' #哪一个minion去执行,不会正则的同窗能够去看看 - cp_file #执行哪一个方法
# cat /srv/salt/base/top.sls
base:
centosgroups: #这里就是咱们上面在master配置文件里面定义的那个组名
- match: nodegroup #这句话是必需要有的,指定以组匹配
- cp_file
# cat /srv/salt/base/top.sls #同上-match: grain也是必需要带的,指定让其按照grain进行匹配,指定让os是Centos的操做系统来执行。
base:
'os:CentOS':
- match: grain
- cp_file
# cat /srv/salt/base/top.sls #上面的grain模块匹配可能知足不了咱们的匹配条件,我想要更加精确的让全部Centos6.4的操做系统去执行,就是我下面的设置。
base:
'G@os:CentOS and G@osrelease:6.4':
- match: compound
- cp_file
# cat /srv/salt/base/top.sls
base:
'192.168.1.0/24':
- match: ipcidr
- cp_file
# salt '*' state.highstate #master将会指导全部的目标minions运行 state.highstate。当minion执行highstate,它将会下载top文件中匹配的内容,minion将表达式中匹配的内容下载、编译、执行。一旦完成,minion将返回全部的动做执行结果和全部更改。基本意思就是谁来执行什么操做,去看top文件里面是怎么写的,就怎么执行。
# salt '*' state.highstate test=True #只是测试执行,相似于模拟,不会在minion真正执行,便于咱们编写测试时使用,建议每次执行都测试一下。
5.5 state的层级关系
include:将别的SLS添加到当前文件中,因此能够require或watch被引用的SLS中定义的内容,还能够extend覆盖其内容。include语句使得state能够跨文件引用。使用include至关于把被引用的内容文件添加到自身。
extend:扩展被引用的SLS数据。不须要重头写新的SLS,能够先直接include sls文件,而后在其基础上增长或者覆盖内容。
首先说应用场景,如今我在prod下面新建了三个目录web,php,mysql,里面分别写了init.sls(初始化环境配置),按照上面的写法,我须要一键执行的话,首先须要在top里面把它们加进去,以下图
top.sls
这样的话,若是我要安装的环境特别的多,这里都直接下载top里面就比较乱了,因此为了醒目,我在prod下直接新建一个lamp.sls文件,而后把这些操做文件都写进去,而后就方便了,而后只须要在top文件里面写上lamp就oK了,是否是很方便。
这里只会一种用法,生产中还有不少种用法。
环境需求,若是已经写好了lamp的安装配置环境了,而后忽然发现还有安装一个软件,这个时候直接去改文件就显的有点粗暴了,这里能够直接在include的里面写,例如,这里我须要给lamp环境下安装一个tree的包。
其它的什么都不须要动,只须要在lamp下添加extend便可。
这里注意,既然是扩展,那就得知道给谁扩展,include的中咱们已经标注了要执行的操做是web,php,mysql下的init操做。可是扩展的还怎么写呢?extend:是标准写法,层级关系是两个空格,那这个id怎么写呢?有人说随便写,你写个试试,确定不行。既然是扩展你得指定给谁扩展。我在php里面的init文件中写过php-install这个id,这里我指定是给它扩展,因此必须得把它的id写在这里,而后再写是什么方法,要干什么。这里须要注意的就是这个id写法,其实也不难理解,既然是扩展,确定是要写给谁扩展的,不然不是乱套了。
match : 配模某个模块,好比 match: grain match: nodegroup
require: 依赖某个state,在运行此state前,先运行依赖的state,依赖能够有多个,被谁依赖是require_in
watch : 在某个state变化时运行此模块,watch除具有require功能外,还增了关注状态的功能,被谁依赖是watch_in。
order : 优先级比require和watch低,有order指定的state比没有order指定的优先级高,假如一个state模块内安装多个服务,或者其余依赖关系,可使用
require和require_in示例:
应用场景,首先咱们是肯定哪些操做都作了之后才能执行此操做,好比全部的安装操做都完成,最后要重启一些服务,就可使用此参数
以下,若是file这个模块下的id是apache-config这个操做成功的话,就执行id是apache-service操做,若是有enable就是重启,若是有reload的参数就是重载配置。
require:
require_in:
写法以下,能够理解为被谁依赖,以下,若是我这个文件操做成功的话就执行service这个模块的id是apache-service的操做。
watch和watch_in示例:
这个就NB了,它具有require的特性。应用场景,若是咱们服务都安装完了,这个时候我须要给全部的minion修改一下配置文件,修改完成后从新加载配置文件,用watch就能够解决,用法和require如出一辙。
若是file这个模块下的id是apache-config这个操做成功(首先是从source这个路径传送到minino端的name路径下后,从新加载httpd这个服务)。watch_in用法恰好相反,相似于require_in0。
6.一、介绍
Jinja2 是一个现代的,设计者友好的,仿照 Django 模板的 Python 模板语言。 它速度快,被普遍使用,而且提供了可选的沙箱模板执行环境保证安全:
参考地址:http://docs.jinkan.org/docs/jinja2/
Jinja的使用分为三个步骤:
File状态使用template参数 - template: jinja。
模板文件里面变量使用{{名称}},好比{{PORT}}.
File状态模块里面指定变量列表。
6.二、jinji的基本使用
环境介绍,为了区分,我在master配置文件中新加一个/srv/salt/jiaja2的模块。
基本写法
{% set iplist= grains['ipv4'] %} #申明变量名称 /files/minion.conf: #定义传输文件id file.managed: #执行方法 - name: /root/minion.conf #目的路径 - source: salt://files/minion.conf.jinja #文件存放位置 - template: jinja #申请只用jinja模板 - defaults: #定义默认将值传递给模板 IP_ADDR: {{iplist[1]}} #获取iplist这个变量的值,由于返回的是一个列表,因此咱们须要取第2个值。
cat files/minion.conf.jinja 这里为了明显,我只写了一个值,
ipaddr:{{IP_ADDR}}
minion效果
总结,这就很厉害了,好比我定义安装minion客户端的某个服务要根据写入本身的ip地址或者固定端口,就能够在这里定义多个变量defaults下面新加就行。它不但能够写变量还支持条件判断和循环。
6.三、逻辑判断
Jinja还主要用来给状态增长逻辑关系,如for循环,或者if判断,也是常用到的。
salt,grains,pillar是salt中jinja里面的三个特殊字典,salt是包含全部salt函数对象的字典,grains是包含minion上grains的字典,pillar是包含minion上pillar的字典。上面已经介绍了如何使用了。
if...elif...endif的示例:
# cat /srv/pillar/pkgs.sls
apache: pkg.installed: #这是根据系统的不一样,判断安装的软件名称。若是有变量就放到{{}}中 {% if grains['os_family'] == 'RedHat' %} #jinja中判断,循环等标签是放在{% %}中 - name: httpd {% elif grains['os_family'] == 'Debian' %} - name: apache2 {% elif grains['os'] == 'Arch' %} - name: apache {% endif %} #也会有结束标签{% end** %}
#固然还支持:{% if %}...{% elif %}...{% else %}...{% endif %}之类的写法。
for循环的示例:
{% set userlist = ['yunwei','cacti','www'] %} {% for user in userlist %} {{ user }}: user.present: - shell: /bin/bash - home: /home/{{ user }} {% endfor %}
参考地址:http://www.51niux.com/?id=117