学习saltstack (四)

1、salt经常使用命令html

salt 该命令执行salt的执行模块,一般在master端运行,也是咱们最经常使用到的命令node

salt [options] '<target>' <function> [arguments]python

如: salt '*' test.pingmysql

salt-run 该命令执行runner(salt带的或者自定义的,runner之后会讲),一般在master端执行,好比常常用到的managereact

salt-run [options] [runner.func]
salt-run manage.status    #查看全部minion状态
salt-run manage.down      #查看全部没在线minion
salt-run manged.up        #查看全部在线minion

salt
-key #密钥管理,一般在master端执行 salt-key [options] salt-key -L #查看全部minion-key salt-key -a <key-name> #接受某个minion-key salt-key -d <key-name> #删除某个minion-key salt-key -A #接受全部的minion-key salt-key -D #删除全部的minion-key
salt
-call #该命令一般在minion上执行,minion本身执行可执行模块,不是经过master下发job salt-call [options] <function> [arguments] salt-call test.ping #本身执行test.ping命令 salt-call cmd.run 'ifconfig' #本身执行cmd.run函数
salt
-cp #分发文件到minion上,不支持目录分发,一般在master运行 salt-cp [options] '<target>' SOURCE DEST salt-cp '*' testfile.html /tmp salt-cp 'test*' index.html /tmp/a.html
salt
-ssh 0.17.1版本加入的salt-ssh
salt
-master master运行命令 salt-master [options] salt-master #前台运行master salt-master -d #后台运行master salt-master -l debug #前台debug输出
salt
-minion minion运行命令 salt-minion [options] salt-minion #前台运行 salt-minion -d #后台运行 salt-minion -l debug #前台debug输出
salt
-syndic #syndic是salt的代理,之后会说到

 

2、普通用户执行saltnginx

普通用户执行salt两种方案:1,salt ACL 2.salt external_authgit

1.ACLgithub

1) 设置master配置文件web

  client_acl:
   monitor:
    - test*:
   - test.*
  dev:
    - service.*
   sa:
    - .*

2) 重启Master正则表达式

service salt-master restart

3) 目录和文件权限

chmod +r /etc/salt/master
chmod +x /var/run/salt
chmod +x /var/cache/salt

4) 测试

# su - monitor
# salt 'test*' test.ping
# exit; su - sa
# salt '*' test.ping
# salt '*' cmd.run 'uptime'
# exit;

2.external_auth

1) 修改master配置文件

external_auth:
pam: monitor: – ‘test‘: – test. sa: – .* – 2) 3)与ACL相同

4) 测试

# salt -a pam 'test*' test.ping    ##会提示输入帐号密码,因此external_auth与当前用户无关
  username: monitor
      password:
# su - monitor
# salt -a pam '*' cmd.run 'uptime'
username: sa
password:

5) 使用Token没必要每次都输入帐号密码,使用external_auth每次都是须要密码的,这样多麻烦,这里引入了Token,它会保存一串字符到在当前用户家目录下.salt_token中,在有效时间内使用external_auth是不须要输入密码的,默认时间12hour,能够经过master配置文件修改

# salt -T -a pam '*' test.ping
username: sa
password:
#salt -a pam '*' test.ping #不会提示输入密码了

3、target

指定你的命令或者模块应用哪写Minion上

1.globbing 默认
salt 'test*' test.ping

2.RE 正则
salt -E 'web1-(pro|devel)' test.ping

3.List 列表
salt -L '127.0.0.1, test*' test.ping

4.grains
salt -G 'os:CentOS' test.ping         #查看全部grains键/值
salt 'test*' grains.items             #查看全部grains项
salt 'test*' grains.ls                #查看某个grains的值
salt 'test*' grains.item num_cpus

在top file中匹配grains
'node_type:web':
 - match: grain         #没有s
 - webserver

top file中使用jinja模板
{% set self = grains['node_type'] %}
   - match: grain
- {{ self }}

5.nodegroups 其实就是对Minion分组
首先在master的配置文件中对其分组,推荐写到/etc/salt/master.d/中一个独立的配置文件中,好比nodegroup.conf
vim /etc/salt/master.d/nodegroup.conf
#写到master中也是这个格式,master.d中*.conf是默认动态加载的
nodegroups:
test1: 'L@test1,test2 or test3*'
test2: ‘G@os:CenOS or test2'

salt -N test1 test.ping #-N指定groupname 在top file中使用nodegroups 'test1': - match: nodegroup ##意没s - webserver 6.混合指定,就是将以上的混合起来用 G Grains glob G@os:Ubuntu E PCRE Minion ID E@web\d+\.(dev|qa|prod)\.loc P Grains PCRE P@os:(RedHat|Fedora|CentOS) L List of minions L@minion1.example.com,minion3.domain.com or bl*.domain.com I Pillar glob I@pdata:foobar S Subnet/IP address S@192.168.1.0/24 or S@192.168.1.100 R Range cluster R@%foo.bar salt -C 'G@os:CentOS and L@127.0.0.1,192.168.1.12' test.ping top file 指定: 'webserver* and G:CentOS or L@127.0.0.1,test1': - match: compound - webserver 7.一次在n个minion上执行 -b n --batch-size n 示例: salt '*' -b 5 test.ping 5个5个的ping

 

4、远程批量执行

格式:
salt '<target>' <function> [argument]
注: function是salt带的或本身写的可执行模块里面的function,自带的全部列表http://docs.saltstack.com/ref/modules/all/index.html?highlight=full%20list%20builtin 实例:
salt '*' at.at 10.10am 'uptime'
salt '*' test.ping

 

5、多Master

1.在另外一台机器上安装salt-master
yum -y install salt-master

2.将原来master上的master密钥拷贝到新的master是一份
scp /etc/salt/pki/master/master* newmaster:/etc/salt/pki/master/

3.启动新的Master
service salt-master start

4.修改minion配置文件/etc/salt/minion设置两个master
master:
  - master1
- master2

5.重启minion
service salt-minion restart

6.在新的master上接受全部key
salt-key -L
salt-key -A

注意:

1.2个master并不会共享Minion keys,一个master删除了一个key不会影响另外一个

2.不会自动同步File_roots,因此须要手动去维护,若是用git就没问题了

3.不会自动同步Pillar_Roots,因此须要手工去维护,也能够用git

4.Master的配置文件也是独立的

6、pillar

Pillar在salt中是很是重要的组成部分,利用它能够完成很强大的功能,它能够指定一些信息到指定的minion上,不像grains同样是分发到全部Minion上的,它保存的数据能够是动态的,Pillar以sls来写的,格式是键值对

适用情景:

1.比较敏感的数据,好比密码,key等

2.特殊数据到特定Minion上

3.动态的内容

4.其余数据类型

查看Minion的Pillar信息
salt '*' pillar.items

查看某个Pillar值
salt '*' pillar.item <key>      #只能看到顶级的
salt '*' pillar.get <key>:<key> #能够取到更小粒度的

编写pillar数据

1.指定pillar_roots,默认是/srv/pillar(可经过修改master配置文件修改),创建目录

mkdir /srv/pillar
cd /srv/pillar

2.编辑一个pillar数据文件

vim test1.sls
name: 'salt'
users:
  hadoop: 1000
redhat: 2000
ubuntu: 2001

3.创建top file指定minion到pillar数据文件

vim top.sls
base:
  '*':
    - test1

4.刷新Pillar数据

salt '*' saltutil.refresh_pillar

5.测试

salt '*' pillar.get name
salt '*' pillar.item name
在state中经过jinja使用pillar数据
vim /srv/salt/user.sls
{% for user, uid in pillar.get(’users’, {}).items() %}  ##pillar.get('users',{})可用pillar['users']代替,前者在没有获得值的状况下,赋默认值
{{user}}:
  user.present:
    - uid: {{uid}}
{% endfor %}
固然也能够不使用jinja模板

vim /srv/salt/user2.sls
{{ pillar.get('name','') }}:
user.present:
  - uid: 2002
经过jinja模板配合grains指定pillar数据
/srv/pillar/pkg.sls
pkgs:
{% if grains[’os_family’] == ’RedHat’ %}
apache: httpd
vim: vim-enhanced
{% elif grains[’os_family’] == ’Debian’ %}
apache: apache2
vim: vim
{% elif grains[’os’] == ’Arch’ %}
apache: apache
vim: vim
{% endif %}

7、grains

服务器的一些静态信息,这里强调的是静态,就是不会变的东西,好比说os是centos,若是不会变化,除非从新安装系统

定义minion的grains能够写在/etc/salt/minion中格式以下

grains:
roles:
  - webserver
  - memcache
deployment: datacenter4
cabinet: 13
cab_u: 14-15

或者写在/etc/salt/grains中,格式以下
roles:
- webserver
- memcache
deployment: datacenter4
cabinet: 13
cab_u: 14-15

也能够在master中编写grains的模块,同步到minion中,用Python来写很简单的

1.在/srv/salt中创建_grains目录

mkdir /srv/salt/_grains

2.编写grains文件,须要返回一个字典

vim test1.py
def hello():                      ##函数名字无所谓,应该是全部函数都会运行
  agrain = {}
  agrain['hello'] = 'saltstack'
return agrain                   ##返回这个字典

3.同步到各个minion中去

salt '*' saltutil.sync_grains
salt '*' saltutil.sync_all
salt '*' state.highstate

4.验证

salt '*' grains.item hello

8、使用 salt state

它的核心是写sls(SaLt State file)文件,sls文件默认格式是YAML格式(之后会支持XML),并默认使用jinja模板,YAML与XML相似,是一种简单的适合用来传输数据的格式,而jinja是根据django的模板语言发展而来的语言,简单并强大,支持for if 等循环判断。salt state主要用来描述系统,软性,服务,配置文件应该出于的状态,经常被称为配置管理!

一般state,pillar,top file会用sls文件来编写。state文件默认是放在/srv/salt中,它与你的master配置文件中的file_roots设置有关

示例: apache.sls文件内容 ##/srv/salt/apahce.sls,之后没有用绝对路径意思就是在/srv/salt下
apache:            ##state ID,全文件惟一,若是模块没跟-name默认用的ID做为-name
pkg:             ##模块
  - installed    ##函数
 #- name: apache ##函数参数,能够省略
service:         ##模块
  - running      ##函数
 #- name: apache ##函数参数,这个是省略的,也能够写上
  - require:     ##依赖系统
    - pkg: apache  ##表示依赖id为apache的pkg状态

下面来解释上面示例的意思:

声明一个叫apache的状态id,该id能够随意,最好能表示必定意思

pkg表明的是pkg模块

installed是pkg模块下的一个函数,描述的是状态,该函数表示apache是否部署,返回值为True或者False,为真时,表示状态OK,不然会去知足该状态(下载安装apache),若是知足不了会提示error,在该模块上面省略了参数-name: apache,由于ID为apache,这些参数是模块函数须要的(能够去查看源码)

service是指的service模块,这个模块下主要是描述service状态的函数,running状态函数表示apache在运行,省略-name不在表述,-require表示依赖系统,依赖系统是state system的重要组成部分,在该处描述了apache服务的运行须要依赖apache软件的部署,这里就要牵涉到sls文件的执行,sls文件在salt中执行时无序(若是没有指定顺序,后面会讲到order),假如先执行了service这个状态,它发现依赖pkg包的安装,会去先验证pkg的状态有没有知足,若是没有依赖关系的话,咱们能够想象,若是没有安装apache,apache 的service确定运行会失败的,咱们来看看怎么执行这个sls文件:

salt '*' state.sls apache  

在命令行里这样执行就ok了,.sls不要写,若是在目录下,将目录与文件用’.’隔开,如: httpd/apache.sls –> httpd.apache

或者

salt '*' state.highstate

这须要咱们配置top file执定哪一个minion应用哪一个状态文件

top.sls内容
base:
'*':
  - apache

下面咱们继续看一些比较复杂的:

ssh/init.sls文件内容
openssh-client:
pkg.installed

/etc/ssh/ssh_config: file.managed: - user: root - group: root - mode 644 - source: salt://ssh/ssh_config - require: - pkg: openssh-client
ssh
/server.sls文件内容 include: - ssh openssh-server: pkg.installed sshd: service.running: - require: - pkg: openssh-client - pkg: openssh-server - file: /etc/ssh/banner - file: /etc/ssh/sshd_config /etc/ssh/sshd_config: file.managed: - user: root - group: root - mode: 644 - source: salt://ssh/sshd_config - require: - pkg: openssh-server /etc/ssh/banner: file: - managed - user: root - group: root - mode: 644 - source: salt://ssh/banner - require: - pkg: openssh-server

ssh/init.sls,学过Python的都知道目录下面的init文件是特殊文件,它怎么特殊呢,它特殊在当咱们应用目录时会应用该文件的内容,如咱们执行 salt ‘*’ state.sls ssh时应用的就是init.sls文件,明白了吗?再看里面的内容,前两行咱们已经看过了,是描述某个rpm包有没有安装的,第三行是ID,也能够用来表示-name,以省略-name,file.managed是file模块与函数managed的快捷写法,看server.sls下最后就知道了,managed它描述了某个文件的状态,后面跟的是managed的参数,user,group,mode大家一看就知道什么意思了,关于这个source是指从哪下载源文件,salt://ssh/sshd_config是指的从salt的文件服务器里面下载,salt文件服务器其实就是file_roots默认/srv/salt/明白了吗,因此salt://ssh/sshd_config指的就是 /srv/salt/ssh/sshd_config,出来用salt的文件服务器,也能够用http,ftp服务器。- require是依赖系统不表,之后会详细说它的。再往下是server.sls文件,include表示包含意思,就是把ssh/init.sls直接包含进来

这时你会看到/srv/salt的目录树是:

ssh/init.sls
ssh/server.sls
ssh/banner
ssh/ssh_config
ssh/sshd_config

下面再来看一个官方样例:

ssh/custom-server.sls 文件内容
include:
- ssh.server
extend:
/etc/ssh/banner:
  file:
- source: salt://ssh/custom-banner
python/mod_python.sls文件内容
include:
- apache
extend:
apache:
  service:
- watch:
  - pkg: mod_python

 首先咱们include的别的文件,可是里面的内容并非所有符合咱们的要求,这时咱们就须要用extend来重写部份内容,特殊的是依赖关系都是追加。custom-server.sls文件意思是包含ssh/server.sls,扩展/etc/ssh/banner,从新其source而其它的如user,group等不变,与include一致。 mode_python.sls文件意思是把apache.sls包含进来,想apache-service是追加了依赖关系(watch也是依赖系统的函数).

经常使用状态配置 salt-states-master.zip

9、关于渲染器render system

咱们上面也提过salt默认的渲染器是yaml_jinja,salt处理咱们的sls文件时,会先把文件用jinja2处理,而后传给ymal处理器在处理,而后生成的是salt须要的python数据类型。除了yaml_jinja还有yaml_mako,yaml_wempy,py,pydsl,我比较感兴趣的就是yaml_jinja,还有py,yaml_jinja是默认的,而py是用纯python来写的。下面来看个样例吧,

apache/init.sls文件内容
apache:
pkg:installed:
  {% if grains['os'] == 'RedHat' %}
- name: httpd
{% endif %}
service.running:
  {% if grains['os'] == 'Redhat' %}
- name: httpd
{% endif %}
- watch:
- pkg: apache

 这个样例很简单,就是加了个判断,若是Minion的grains的os是RedHat那么apache的包名是httpd,默认是apache,咱们知道在别的Linux发行版上,如ubuntu,suse他们的apache的包名就是叫apache,而在redhat系上则叫httpd,因此才有了这个判断写法,下面的service也是如此。咱们着重说语法,jinja中判断,循环等标签是放在{% %}中的,一般也会有结束标签{% end** %},而变量是放在 {{ }}中的,salt,grains,pillar是salt中jinja里面的三个特殊字典,salt是包含全部salt函数对象的字典,grains是包含minion上grains的字典,pillar是包含minion上pillar的字典。

示例:for user/init.sls文件内容

{% set users = ['jerry','tom','gaga'] %}
{% for user in users %}
{{ user }}:
user.present:
  - shell: /bin/bash
  - home: /home/{{ user }}
{% endfor %}

 示例;salt字典 user/init.sls文件内容

{% if salt['cmd.run']('uname -i') == 'x86_64' %}
hadoop:
user.present:
  - shell: /bin/bash
  - home: /home/hadoop
{% elif salt['cmd.run']('uname -i') == 'i386' %}
openstack:
user.present:
  - shell: /bin/bash
- home: /home/openstack
{% else %}
django:
user.present:
  - shell: /sbin/nologin
{% endif %}

 py渲染器 说明:py渲染器是用纯python写的sls文件,它返回的数据与yaml_jinja通过jinja处理通过yaml处理后的数据相似 ,用其余渲染器须要在sls文件头行声明用的渲染器类型,#!py就是声明用的py渲染器,py中可用的变量有salt,grains,pillar,opts,env,sls,前三个分别对应jinja里的salt,grains,pillar,opts是minion的配置文件的字典,env对应的是环境如base,sls对应的是sls的文件名

示例: user/init.sls

#!py
import os
def run():
  '''add user hadoop'''
platform = os.popen('uname -a').read().strip()
if platform == 'x86_64':
  return {'hadoop': {'user': ['present',{'shell': '/bin/bash'}, {'home': '/home/hadoop'}]}}
elif platform == 'i386':
      return {'openstack': {'user': ['present', {'shell': '/bin/bash'}, {'home': '/home/openstack'}]}}
else:
  return {'django': {'user': ['present', {'shell': '/sbin/nologin'}]}}

 说明: 首行声明了使用py做为渲染器,导入了os模块,声明run函数,py渲染sls文件是从run函数开始的,其它的就是python的语法了,注意的是return的数据结构{ID: {module: [func, arg1,arg2,...,]}} 或 {ID: {module.func: [arg1,arg2,..,]}} 。表示的内容与“示例;salt字典”表达的相同

10、state的执行顺序

之前咱们说过,state的执行时无序,那个无序是指执行咱们写的那个sls是无序的,正是由于那个无序,salt保证每次执行的顺序是同样的,就加入了state order,在说它以前看看High Data(高级数据?)和Low Data(低级数据?),高级数据我理解的就是咱们编写sls文件的数据,低级数据就是通过render和parser编译过的数据。

查看highdata

salt '*' state.show_highstate

 查看lowdata

salt '*' state.show_lowstate

 经过查看lowdata咱们发现里面有一个字段order,由于salt默认会自动设置order,从10000开始。能够经过设置master配置文件参数state_auto_order: False来关闭

Order的设定:

1.include 被include的文件Order靠前,先执行

2.手动定义order字段,如

apache:
   pkg:
 - installed
 - order: 1

 order的数字越小越先执行从1开始,-1是最后执行

3.依赖关系系统

11、依赖关系系统requisite system

前面咱们已经用过了依赖关系系统,就是定义状态与状态之间的依赖关系的,常常遇到的依赖系统的函数有’require’和’watch’和它们的变种’require_in’,’watch_in’,require和watch有什么区别吗?

1.不是全部的state都支持watch,比较经常使用的是service

2.watch定义的依赖条件发生变化时会执行一些动做,如当配置文件改变时,service会重启

示例: apache/init.sls文件内容

/etc/httpd/httpd.conf:
file:
  - managed
- source: salt://httpd/httpd.conf
httpd:
pkg:
  - installed
service:
  - running
  - require:
    - pkg: httpd
  - watch:
    - file: /etc/httpd/httpd.conf            ##当httpd.conf改变时,重启httpd服务
require与require_in, watch与watch_in
require,watch是指依赖,require_in,watch_in是指被依赖
a reuire b 那么就是b require_in a
a watch b 那么就是b watch_in a

 示例: apache/init.sls文件内容

/etc/httpd/httpd.conf:
file:
  - managed
- source: salt://httpd/httpd.conf
- watch_in:
- service: httpd
httpd:
pkg:
  - installed
- require_in:
- service: httpd
service:
  - running

 12、salt state环境

针对不用环境,应用不一样的state的file,salt支持多环境,好比开发,测试,生产等环境,咱们经过修改Master配置文件对不一样的环境应用不一样的目录!

file_roots:
base:
  - /srv/salt/prod   ##生产环境
qa:
  - /srv/salt/qa     ##测试环境,若是没发现去prod里面找
- /srv/salt/prod
dev:
  - /srv/salt/dev    ##开发环境,若是找不到,先去qa里找,若是找不到再去prod里面找
- /srv/salt/qa
- /srv/salt/prod
/srv/salt/prod/top.sls文件内容
base:
'web*prod*':
  - webserver.foobarcom
qa:
'web*qa*':
  - webserver.foobarcom
dev:
'web*dev':
  - webserver.foobarcom
  
pillar的目录与file_roots无关,因此Pillar的目录默认仍是/srv/salt,pillar只是Minion的一些信息,不会对系统有什么改变,因此不须要区分环境,一般base便可。
/srv/pillar/top.sls文件内容
base:
'web*prod*':
  - webserver.prod
'web*qa*':
  - webserver.qa
'web*dev*':
  - webserver.dev

/srv/pillar/webserver/prod.sls文件内容 webserver_role: prod /srv/pillar/webserver/qa.sls文件内容 webserver_role: qa /srv/pillar/webserver/dev文件内容 webserver_root: dev
最后sls文件
/srv/salt/prod/webserver/foobarcom.sls(该文件会被全部环境访问到)的内容: {% if pillar.get('webserver_role', '') %} /var/www/foobarcom: file.recurse: - source: salt://webserver/src/foobarcom - env: {{ pillar['webserver_role'] }} - user: www - group: www - dir_mode: 755 - file_mode: 644 {% endif %}

 开发完成后,应用sls文件

1.如今开发环境

salt -I ‘webserver_role:dev’ state.sls webserver.foobarcom

 十3、salt schedule

schedule是salt中的crontab,就是周期性执行一些函数,须要注意的是在minion上执行的函数是salt的可执行模块里的函数,在master上执行的是runner模块的函数,下面看看如何设置: master是修改master配置文件/etc/salt/master:

schedule:
overstate:                    ##这个是ID,能够随意起,全文件惟一
  function: state.over        ##对于master,function就是runner
  seconds: 35                 ##间隔秒数
  minutes: 30                 ##间隔分数
  hours: 3                    ##间隔小时数

 这时每隔3小时30分35秒,master就会运行一个state.over这个runner

minion的schedule定义有两种方式

1.经过修改minion的配置文件,这种方式须要修改全部Minion的配置文件略麻烦
schedule:
highstate:
  function: state.highstate
seconds: 30
minutes: 5
hours: 1
2.为Minion指定pillar
/srv/pillar/schedule.sls文件内容
schedule:
highstate:
  function: state.highstate
seconds: 30
minutes: 5
hours: 1
经过top file指定到Minion
/srv/pillar/top.sls文件内容
base:
*:
  - schedule

 十4、YAML语法风格

1.空格和Tabs

在YAML中不要使用Tab

2.缩进

YAML推荐缩进为2个空格,’:’,’-’后面缩进1个空格再写

3.数字会解析成数字

如mode: 0644会解析成mode: 644,可用’括住防止mode: ’0644′此状况

4.YAML不容许双简写

vim:
pkg.installed   ##第一个简写,单一个简写没问题
user.present    ##第二个简写,加上它是不支持的

 不要偷懒写成下面这样吧。

vim: pkg:
- installed user: – present – 

 5.YAML只支持ASCII

其它字符集最好不要使用,若是非要使用用如下格式:

micro: ‘\u00b5′

 6.下划线_将会被删除

date: 2013_05_13  --> date: 20130513

 经过’括住防止出现该问题

date: '2013_05_13'  

 十5、salt事件系统与反应系统 event and reacter system

咱们知道Master与Minion是基于ZMQ通讯的,他们通讯咱们看来是消息队列,对它们来讲这些消息就是一些事件,什么事件应该作什么,是salt基本已经预设好了。咱们学习它的事件系统来完成一些自定义的行为,后面的反应系统就是基于事件系统的。一条消息其实就是一个事件,事件一般是一个字典数据,这个字典数据一般包含tag,这个tag是用来区分用途过滤消息的,详见绿大-https://groups.google.com/forum/#!topic/saltstack-users-cn/wXVE4ydnnzc ,让咱们来看看这些事件。

捕捉事件(listen event)

1.下载官方给的事件捕捉程序eventlisten

https://github.com/saltstack/salt/blob/develop/tests/eventlisten.py 打开网址,复制下载,不要直接wget

2.运行该程序

Master: python2.6 eventlisten.py                         ##捕捉master端的event直接运行便可

Minion: python2.6 eventlisten.py -n minion <minion-id>   ##捕捉minion端的须要额外参数,minion-id是该Minion的id

发送事件(fire event)
Master发给minion
salt '*' event.fire "{'data': 'some message'}" "tag"     ##前面必须是字符串包住的字典,后面是tag,若是你的minion在监听event,你会看到这条event的
Minion发给minion
salt-call event.fire_master 'some message' 'tag'  ##前面数据类型没有要求,后面是tag,去master那看看收到了没有
Minion发给本身
salt-call event.fire "{'data': 'some message'}" 'tag' ##前面必须是字符串包住的字典,后面是tag
用code来捕捉,并发送event
捕捉事件 Master:
# python2.6
>>> import salt.utils.event
>>> event = salt.utils.event.SaltEvent('master', '/var/run/salt/master')
##master代表是在master端监听,/var/run/salt/master是你master的sock_dir
>>> data = event.get_event()
>>> print(data)       ##查看内容
>>> data = event.get_event(wait=10, tag='auth') ##wait是指timeout时间,默认5s,用tag来过滤事件,可省略
>>> print(data)                
>>> for data in event.iter_events(tag='auth'):  ##用迭代器一直查看事件
>>>     print(data)
Minion:
#python2.6
>>> import salt.utils.event
>>> event = salt.utils.event.SaltEvent('minion', '/var/run/salt/minion',id='minion_id')
##minion表明是在minion端监听,/var/run/salt/minion是minion端的sock_dir,minion_id是该Minion的id
>>> data = event.get_event()
>>> print(data)
>>> for data in event.iter_events(tag='auth'):  ##用迭代器一直查看事件
>>>     print(data)
—————–先这样吧 发送事件:
Master:
>>> import salt.utils.event
>>> event = salt.utils.event.SaltEvent('master', '/var/run/salt/minion')
>>> event.fire_event({'hello': 'world'}, 'hello')

 —————–先这样

反应系统(reacter system)

反应系统是基于事件系统的,它的做用是当master收到来自minion的特殊事件后就触发某些动做,好比minion上线后发送一个init事件,master收到后,对其应用init的状态文件,minion没有反应系统,事情就是这样的。

配置reactor

1.修改master配置文件或者在/etc/salt/master.d/中创建reactor.conf,内容

reactor:
- 'testtag':                    ##接收到的tag
  - /srv/reactor/start.sls
- /srv/reactor/monitor.sls
- 'test1*tag':                  ##接收到的tag,支持通配符
  - /srv/reactor/other.sls

 2.创建reactor响应sls文件

/srv/reacter/start.sls文件内容

{% if data['id'] == 'mysql1' %}
delete_file:
cmd.cmd.run:
  - tgt: 'G@os:CentOS'
- expr_form: compound
- arg:
- rm -rf /tmp/*
{% endif %}
/srv/reactor/other.sls文件内容
{% if data['data']['state'] == 'refresh' %}
overstate_run:
runner.state.over
{% endif %}

 下面来解释一下这两个文件,reacter的sls文件是支持jinja的,因此第一行是经过jinja来判断,reacter的sls支持两个变量data和tag, data是接受事件的那个字典,tag就是事件的tag,因此第一行的判断就很好理解了,第二行是id,能够随意起,第三行是要运行的执行模块或者runner,若是是执行模块,以cmd.开始,若是是runner则以runner.开始,可执行模块执行须要target,因此- tat:后面跟的就是可执行模块的target,- expr_form指的target的匹配方式,- arg是只执行模块函数的参数,runner通常不须要这些。因此第一个示例至关于执行了salt -C 'G@mysql1' cmd.run 'rm -rf /tmp/*' 第二个至关于执行了 salt-run state.over

十6、salt Mine

salt的用的词都过高明,像Grains,Pillar,Mine真心没一个合适的词去翻译,Mine是作什么的呢?Mine的做用是在静态数据和动态数据创建起一座桥梁(官方文档如是说),Mine从minon收集数据而后发送给Master,并缓存在Master端,全部Minion均可以轻易的共享到,Master一般会维护比较新的数据,若是须要维护长期数据,就要考虑retruner或外部的工做缓存了。 mine的出现是用来解决必定问题的. 在Salt的网络体系中,各个minion是毫无关系,相互独立的. 可是在实际应用中,minion之间实际上是有必定关联的,好比一台机器须要获取到另外一台机器的一些信息或者执行一些命令. 后来Salt加入了peer系统(http://docs.saltstack.com/ref/peer.html)使其成为可能. 可是peer系统每次使用的时候都会从新执行一遍, 显然不少不常变化的信息重复执行效率较低,性能开销较大. 因此就有了后来的mine(peer和mine的关系是我杜撰出来的,若有雷同,纯属巧合). mine系统存储在master端, minion想获取的时候, 经过mine.get获取下就能够了,简单方便

修改minion配置文件,配置Mine

mine_functions:
network.interfaces: []
test.ping: []
mine_interval: 1

重启Minion,在master端测试

salt '*' mine_get '*' network.interfaces
salt '*' mine_get '*' test.ping
salt 'test1' mine_get '*' test.ping    ##查看test1上能获得mine数据

 

十7、salt ssh

从0.17.0开始salt加入salt ssh,salt ssh不须要在客户端安装salt-minion包了,是经过ssh协议来完成运城命令执行,状态管理等任务的。它是做为master-minion形式的补充出现的,原理是有一个花名册的文件,里面记录了各个minion的信息,ip,帐号,密码,等,须要远程执行命令时,直接经过ssh来执行,速度与master-minion形式慢不少。

使用: 1.配置/etc/salt/roster格式以下

test1:
host: 192.168.1.133
user: salt
passwd: redhat
sudo: True
port: 22
timeout: 5

test2: host:
192.168.1.134 user: root passwd: redhat
test3: host:
192.168.1.135 user: sa sudo: True

 

说明: test1咱们定义了全部常见的选项,test2咱们用了超级用户,使用帐号密码,test3咱们使用普通用户,没有写密码,就是经过key来认证了,而且以sudo方式执行的,须要注意的是1.key认证用的是/etc/salt/pki/master/ssh/目录下的密钥。2.若是普通用户的话,须要有sudo权限,由于一些功能,包括test.ping都须要sudo权限。

测试:

salt-ssh '*' test.ping
salt-ssh '*' -r 'ls /'   ##执行shell命令
salt-ssh '*' cmd.run 'ls /' ##用模块来执行也是能够的
salt-ssh '*' state.sls   ##执行状态,state.sls在0.71.0中还存在bug,0.72.0中已解决

 

十8、Returners

默认全部minion返回的值都会发送到master端,咱们能够看到,returner就是让Minion把返回的值发给其它地方,如redis,MySQL,或者一个文本 下面咱们来自定义一个returner:

1.创建自定义returner

mkdir -p /srv/salt/_returners;
vim mysql.py  ##就用官方给的例子吧,修改其中mysql的Host,user和pass
内容见https://github.com/saltstack/salt/blob/develop/salt/returners/mysql.py

 

2.创建须要的数据库

见https://github.com/saltstack/salt/blob/develop/salt/returners/mysql.py注释里的见表语句

 

3.受权其余主机用户可写该表

>grant all on salt.* to 'user_in_returner'@'%' identified by 'passwd_in_returner';

 

4.同步

salt '*' saltutil.sync_all      ##同步到minion上去

 

5.测试

salt '*' test.ping --return mysql    ##数据返回到mysql上去,打开mysql查看

 

十9、扩展salt

经过自定义各个模块来扩展salt,常见自定义模块有:

1.可执行模块 Execution Modules

如咱们经常使用的cmd.run , test.ping这样的可执行模块

2.Grains

扩展grains,grains是一些静态信息,可能好多咱们须要的没有,咱们能够经过编写grains模块自定义grains

3.状态模块 State Module

如咱们经常使用的pkg.install,file.managed

4.Returners

咱们能够自定义returner,将返回的数据发送到其余存储,只要符合固定的格式就好了

5.Runner

Runner是在master端快速执行的模块,自定义很方便

二10、自定义可执行模块

全部可执行module见https://github.com/saltstack/salt/tree/develop/salt/modules,或http://docs.saltstack.com/ref/modules/all/index.html?highlight=full%20list%20builtin

1.创建自定义模块目录,一般全部自定义模块放在该目录下

mkdir /srv/salt/_modules

2.编写模块

vim test.py

-*- coding: utf-8 -*-
'''
support for yum of RedHat family!
'''
def __virtual__():
  '''
  Only RedHat family os can use it.
  '''
  if __grains__.get('os_family', 'unkown') == 'RedHat':
      return 'yum'
  else:
      return False
def install(rpm):
  cmd = 'yum -y install {0}'.format(rpm)
  ret = __salt__['cmd.run'](cmd)
  return ret

 说明:__virtual__函数一般用来匹配是否知足该模块的环境,若是知足return出来的字符串做为该模块的名字而不是文件名,若是return的是False表明的此模块无效,不能使用。在自定义模块中能够中__grains__是一个包含了minion 全部grains的字典,__pillar__是包含了全部Pillar的grains字典,__salt__是全部可执行函数对象的字典,一般最常使用的就是这三个变量了。再往下面是定义了函数install,在salt中通常不用’%s’ % var这种格式化形式,而是使用字符串的format方法,具体使用见百度。下面就是经过__salt__执行了cmd.run这个函数来运行yum命令,很简单吧,最后把结果返回回去。

3.测试

salt '*' yum.install ftp  ##查看返回值

 二11、自定义grains

自定义的grains也是由Python写成的,一般放在/srv/salt/_grains下,grains须要返回一个字典,__salt__,__grains__,__pillar__也是能够在grains中使用的。前面已经介绍过写简单自定义grains了,复杂就就参照https://github.com/saltstack/salt/blob/develop/salt/grains/core.py官方这个吧

二12、自定义returner

前面已经看过官方的mysql的returner了,今天来讲说自定义returner须要注意的,来个例子吧。 /srv/salt/_returners/file.py内容

def __virtual__():
  return 'file'
def returner(ret):
  '''
  Return information to /tmp/returns.txt.
  '''
  # open a file
  result_file = '/tmp/returns.txt'
  f = open(result_file, 'a+')
  f.write(str(ret))
  f.close()

 salt '*' saltutil.sync_all         ##同步模块

salt '*' test.ping --return file   ##测试

cat /tmp/returns.txt               ##在minion上查看

{'jid': '20131227153001246117', 'return': True, 'retcode': 0, 'success': True, 'fun': 'test.ping', 'id': 'test1'}

说明: 经过这个简单的例子咱们了解返回的值是个字典,字典包括的项就是上面咱们看到的,之后写其它returner时,也就是把这个字典的值写到不一样的地方而已。这个returner的意思就是把返回的值写到各个minion的/tmp/returns.txt中。

二十3、file state backup

来例子看看吧。 /srv/salt/test.sls文件内容

/tmp/test.txt:

file.managed:
  - source: salt://test.txt
  - backup: minion

 其中多了一个参数backup,后面跟的值minion,意思是说这个文件在minion中备份一份,文件名带着时间戳,备份位置在/var/cache/salt/minion/file_backup

执行并测试:

salt '*' state.sls test    ##注,多修改几回test.txt,多运行几回该state
salt '*' file.list_backups /tmp/test.txt ##这是会返回备份序号,时间,位置,大小
回退 当文件改错后,咱们能够用备份文件回退
salt '*' file.restore_backup /tmp/test.txt 2   ##回退的文件,与想要回退的序列号
删除 删除不须要的备份文件
salt '*' file.delete_backup /tmp/test.txt 3

 二十4、应用实例

saltstack 远程触发文件备份、回滚

一、建立模块方法文件

mkdir /srv/salt/_modules

默认没有此文件,本身生成一个

下面的py文件本身定义,下面是我写的两个方法:

#!/usr/bin/python
# -*- coding: utf-8 -*-
import sys,string,shutil
import os,tarfile
import datetime,time
tn=datetime.datetime.today()
time_now=tn.strftime("%Y-%m-%d")
data_bak='/data/databak'
data_tmp='/data/databak/tmp/%s' % time_now
com_f="%s/%s" % (data_bak,time_now)
if not os.path.exists(com_f):
    os.makedirs(com_f)
def CpFile():
    id = sys.argv[1]
    dir = sys.argv[2]            #传入两个变量,任务自动生成的id与要替换的文件
    filename = '%s/%s.tar' % (com_f, id)
    mode = 'w:tar'
    os.chdir(data_bak)                                                                                                                                                
    w_file=open("/tmp/tmp.list",'w')      
    w_file.write(id+" "+dir)              #记录每次备份的id与相对应的备份目录或文件的路径
    w_file.close()
    file = tarfile.open( filename, mode )
    file.add( '/tmp/tmp.list' )
    file.add( dir )    
    file.close()
    return 'ok'       #测试过程,就先让返回ok吧,以后再作判断
def RollBack():
    id = sys.argv[1]        #想要回滚到的版本id
    if not os.path.exists(data_tmp):
         os.makedirs(data_tmp)
    filename = '%s/%s.tar' % (com_f, id)
    tar = tarfile.open("%s" % filename)
    for b in tar:
         tar.extract(b,path="%s" % data_tmp)
    tar.close()
    for line in open('%s/tmp/tmp.list' % data_tmp):
         id = line.split(" ")[:1][0]
         dir = line.split(" ")[1:][0]       #读取备份时的路径
         backup_dir='%s/%s' % (data_tmp,dir)
         os.system('\cp -rp %s %s' % (backup_dir,dir))
         return 'ok'

 二、测试:

master上同步方法脚本到节点

salt '*' saltutil.sync_all

 而后先测试备份 方法

saltstack

salt ‘*’ cp_bakfile.CpFile 1234  /tmp/test    #id + 路径

 上节点服务器上查看,存在

把/tmp/test下内容删除,测试回滚操做

salt '*' cp_bakfile.RollBack 1234

 使用gitfs作fileserver

用gitfs后,master会从git服务器取回文件缓存,minion不会直接联系git服务器 修改master配置文件/etc/salt/master(注:之后说master配置文件就是指该文件)

fileserver_backend:
- git
gitfs_remotes:
- git://github.com/saltstack/saltstack.git
- git://github.com/example/test1.git      ##能够多个git
- file:///root/td                         ##可使用本地git

 须要:python的模块GitPython >= 0.3.0

saltstack的目录结构

.
|-- bfile
|-- edit
|   `-- vim.sls
`-- top.sls

vim.sls
/tmp/a.txt:
file.managed:
  - source: salt://bfile
ftp:
pkg:
  - installed

 

也可使用git下的子目录做为文件服务器根目录

gitfs_root: somefolder/otherfolder

也能够混合使用git和本地磁盘做为文件服务器

fileserver_backend:
- roots
- git
-

使用ssh协议的GitFS,私钥为~/.ssh/id_rsa

gitfs_remotes:
- git+ssh://git@github.com/example/salt-states.git

 

推荐阅读:

saltstack经常使用管理命令

saltstack使用event机制来监控salt运行

saltstack 中pillar和grains的区别

saltstack master和minion认证机制

saltstack自定义模块示例

使用salt state执行一个复制文件并执行的任务

saltstack pillar设置

saltstack的nodegroups配置

saltstack grains配置

并发之痛 Thread,Goroutine,Actor

requestAnimationFrame最佳实践

############################################################################

master经常使用配置选项

interface:   指定bind的地址(默认0.0.0.0)
publish_port:指定发布端口(默认4505)
ret_port:    指定结果返回端口,与minion配置文件的master——port对应(默认为root)
user:        指定master进程的运行用户,若是调整,则须要调整部分目录的权限(默认root)
timeout:    指定timeout时间,若是minion规模庞大或网络情况很差,建议增大该值(默认5s)
keep_jobs:  默认状况下,minion会执行结果会返回master,master会缓存到本地的cachedir目录,
该参数指定缓存多长时间,以供查看以前的执行结果,会占用磁盘空间(默认24h)
job_cache:  master是否缓存执行结果,若是规模庞大(超过5000台),建议使用其余方式来存储jobs,
关闭本选项(默认为True)
file_recv:  是否容许minion传送文件到master上(默认Flase)
file_roots: 指定file server目录,默认为:
file_roots:
base:
- /srv/salt
pillar_roots:指定pillar目录,默认为:
pillar_roots:
base:
- /srv/pillar
log_level:执行日志级别,支持日志级别有‘garbage’,‘trace’,‘debug’,‘info’,‘warning’,‘error’,‘critical’
(默认为warning)
default_include
  默认值:master.d/*.conf
  master能够从其余文件读取配置,默认状况下master将自动的将master.d/*.conf中的配置读取出来并应用,其中master.d目录是相对存在于主配置文件所在的目的

minion经常使用配置选项:

master:    指定master主机(默认salt)
    master_port: 指定认证和执行结果发送到master的那个端口,与master配置文件的ret_port对应(默认4506)
    id:      指定本minion的标识,salt内部使用id做为标识(默认为主机名)
    user:     执行运行minion的用户,因为安装包,启动服务等操做须要特权用户,推荐使用root(默认为root)
    cache_jobs:  minion是否缓存执行结果(默认False)
    backup_mode:在文件操做(file.managed或file.recurse)时,若是文件发生变动,指定备份目标,当前有效值为minion,
    备份在cachedir/file_backup    目录下,以原始文件名称加时间戳来命名(默认Disabled)
    providers:  指定模块对应的providers,若是RHEL系列中,pkg对应的providers是yumpkg5
    renderer:   指定配置管理系统中的渲染器(默认值:yaml_jinja)
    file_clicent:指定file client默认去哪里(remote或local)寻找文件(默认值为remote)
    loglevel:  指定日志级别
    tcp_keepalive:minion是否与master保持keepalive检查,zeromq3如下版本存在keepalive bug,会致使某些状况下链接异常后minion没法重连master,
    建议有条件的话升级到zeromq3以上版本(默认为True)

salt数据系统(grains谷物和pillar柱子): 

  grains:存储在minion端,用于保存minion端的数据信息,当minion启动时才加载grains信息,因此grains信息是静态的,grains可用于minion信息查询、target配置管理模板等;

grains的用法:

salt '*' grains.items    ##查询全部的grains信息
salt '*' grains.get ip_interfaces:eth0    ##查询eth0所用IP地址

使用grains添加自定义items

 第一种方法:

  在minion端:修改配置文件/etc/salt/minion  中 打开 default_include: minion.d/*.conf 
  在/etc/salt/minion.d/目录中添加须要增长的items,文件类型与配置项*.conf对应
 cat push.conf 
 grains:
 ITEMS: 10
 TEST: yes
   OA:
    - a
    - b

以后重启minion服务 /etc/init.d/salt-minion restart,在master端查看是否添加成功

 salt '10.13.41.21' grains.items
 10.13.41.21:
    ----------
     ITEMS:
          10
      OA:
          - a
          - b
      SSDs:
      TEST:
          True          ##表示成功

 第二种方法:

  在master端添加,在/srv/salt/ 建立_grains目录,编写grains文件,须要返回一个字典
 cat /srv/salt/_grains/nginx.py 
 def nginx():
   nginx={}
   nginx['nginx']='1.5.5'    ##定义nginx的默认版本
   return nginx
 同步到minion端: salt '*' saltutil.sync_all
 或者使用salt '*' state.highstate(这个貌似很差使)命令同步,而后刷新各minion端salt '*' sys.reload_modules,经过grains.items看到相关的信息了

在执行salt '*' grains.item os  --summary    ##加上--summary能够显示执行结果

-------------------------------------------
 Summary
 -------------------------------------------
 # of minions targeted: 254
 # of minions returned: 254
 # of minions that did not return: 0
-------------------------------------------

pillar

 存储在master端,存放须要提供给minion的信息,应用场景:敏感信息(每一个minion只能访问master分配给本身的pillar信息)、变量(差别化的信息)、其它任何数据、可在target、state中使用);
1、修改配置文件
vim /etc/salt/master pillar_roots: base: – /srv/pillar 2、建立top文件
vim /srv/pillar/top.sls base: '*': - packages 3、建立pillar文件
vim /srv/pillar/packages.sls {% if grains['os'] == 'RedHat' %} ##判断系统时候是redhat,是的话Apache名是httpd apache: httpd git: git {% elif grains['os'] == 'Debian' %} apache: apache2 git: git-core {% endif %} 4、测试
salt '*' pillar.get master:interface ## 查看master配置的ip地址
salt '*' saltutil.refresh_pillar      ## 刷新 salt '*' pillar.data             ## 命令查看pillar信息 salt '*' pillar.get schedule         ## pillar取某个值
salt '*' pillar.get master:interface

grains  VS   pillar:

用途不一样:grains用于存储minion的基本数据信息,这些信息是批量的不可变的;pillar用于存储master分配给minion的数据信息;

存储区域不一样:grains的元数据存储在minion端;pillar的元数据存储在master端;

更新方式不一样:grains是在minion启动时进行更新,也可经过saltutil.sync_grains进行刷新;pillar的元数据在master端,要用saltutil.refresh_pillar进行刷新,相较于grains,pillar效率更高、更灵活;

salt远程执行

执行的格式 salt 【target】 【commond】

Targeting:

支持:Globing、正则、List、Grains、Pillar、Node Group、混搭、Batch Size

Globing :      '*',
正则:          指定-E参数,salt -E 'web1-(prod|devel)' test.ping
List:          指定-L参数,salt -L 'node01,node02' test.ping 
Grains:        指定-G参数,salt -G 'os:CentOS' test.ping
pillar:        指定-I参数,salt -I 'apache:httpd' pkg.install httpd
node groups:     指定-N参数,salt -N 'web-cluster' test.ping
混搭(compound)  指定-C参数,salt -C 'G@os:CentOS and *02*' test.ping
batch size       -b参数,指定同时运行的minion数目   salt '*' -b 1 test.ping
salt '*' -b 10 test.ping 分10个minion一批进行执行,直到执行完毕
salt -G 'os:RedHat' --batch-size 25% apache.signal restart 分红25%一批进行执行,直到执行完毕

为了是master文件更加整洁,能够将分组的文件放到/etc/salt/master.d/下面,会自动加载

远程执行实例

 

一、salt '*' test.ping                 #测试minion是否能够连通(非icmp协议)
二、salt '*' pkg.install httpd         #在全部的minion机器上安装httpd服务
三、salt '*' cp.get_file salt://apache/files/httpd.conf  /opt/httpd.conf
   salt-cp '*'       /srv/salt/apache/files/httpd.conf  /opt/httpd2.conf
                                      #拷贝master上的配置文件到minion机器上,用于下发配置文件 通常用第一种
四、salt '*' service.start httpd ###启动minion机器上的httpd服务

 

配置管理

salt 默认使用YAML做为sls文件描述格式

1、使用空白字符为文件缩排表示结构,不能使用TAB
2、注释用#号
3、字符串日常不使用引号,若是有须要,可使用单引号或双引号。使用双引号表示字符串时,特殊字符能够经过倒斜线(\)来进行定义
yaml用法:
1,列表:短杠(-)+ 空白字符 - henry - sina 等价于:['henry','sina'] 2,字典:key和value经过冒号(:)+空白字符隔开 name: henry site: http://www.saltstack.cn/ 等价于:{'name':'henry','site':'http://www.saltstack.cn/'} 3,多层结构:经过缩进来表示层级 - henry: - sites: - blog: http://www.saltstack.cn/ 等价于:[{'henry':[{'sites':[{'blog':'http://www.saltstack.cn/'}]}]}]
官网地址:http://docs.saltstack.cn/topics/yaml/index.html

jinja

  Salt默认使用Jinja2模板系统来生成YAML,是python语言开发的一个模板引擎,相似于Djingo模板系统

jinja模块的用法:

变量:{{ foo }},变量属性可使用{{ foo.bar }}或{{ foo['bar'] }}
注释:{# comment #}
for:                          ##可使用for循环取值
  {% for eachitem in items %}
    {{ eachitem }}
  {% endfor %}
if:                           ##能够作if条件判断
   {% if GFW %}
      welcome to China!
   {% elif not Internet %}
     welcome to North korea!
   {% else %}
     Freedom
   {% endif %}

State Tree

Top file:配置管理入口文件,和pillar相似,指定minions须要完成那些配置管理,默认为top.sls
  注:在定义top.sls时,会先找apache/init.sls,若是没有的话,会找apache.sls
  base:
    '*':
      - apache
  sls模块使用点(.)来分割,如apache.install等于salt://apache/install.sls或salt://apache/install/init.sls
  Include/Extend:sls文件间能够经过include及extend来引用和扩展
  sls中ID必须惟一,且在该ID下的同一类的状态管理模块只能有一个,所谓的slsID 就是定义sls文件时最开始定义在开头的名字。
  0.17.0 salt增长了state_auto_order参数(默认值为True),使state在没有Requisites的状况下按照从上而下的顺序进行执行

http://docs.saltstack.com/en/lastst/ref/states/highstate.html

Requisites(至关于sls流程控制,那个先执行,那个后执行等) 

require:本state执行时须要先执行那些state
require_in:与require位置相反
watch:除了require外,也会监测依赖的state的状态,若是状态发生变化,作出反应(例如监控文件变化,发生变化后当即重启服务)
watch_in: 与watch位置相反
prereq:0.16.0 新增的功能,会经过test=True接口检查所依赖的state的状态,若是状态发生变化,执行
prereq_in:相反

http://docs.saltstack.com/en/lastst/ref/states/requisites.html

下面介绍三个模块的用法,更多模块用法请参考官网

官网地址:https://docs.saltstack.com/en/latest/ref/states/all/

 软件包状态管理模块

模块名:pkg
功能:管理软件包状态,会根据操做系统不一样,选择对应安装方式
基本操做:
pkg.installed:     #确保软件包已安装,若是没有安装进行安装
pkg.latest:        #确保软件包是最新版本,若是不是,进行升级
pkg.remove:        #确保软件包已卸载,若是以前已安装,进行卸载
pkg.purge:         #除remove外,也会删除其配置文件

文件状态管理模块:

模块名:file
功能:管理文件状态
基本用法:
file.managed:      #保证文件存在而且为对应的状态
file.recurse:       #保证目录存在而且为对应的状态
file.absent:        #确保文件不存在,若是存在则进行删除操做

服务状态管理模块:

模块名:service
功能: 管理服务状态
基本用法:
service.running        #确保服务处于运行状态
service.enabled        #确保服务会开机自动启动
service.disabled       #确保服务不会开机自启动
service.dead           #确保服务当前没有运行

实例操做:

一、安装apache

top.sls
    base:
      '*':
        - apache
init.sls
    
apache:                    ##slsID
  pkg.installed:                        ##安装httpd
    - name: httpd
  file.managed:
    - name: /etc/httpd/conf/httpd.conf  ##拷贝/srv/salt/apache/httpd.conf到minion的/etc/httpd/conf/httpd.conf
    - source: salt://apache/httpd.conf
    - require:                      ##检查apache有没有安装成功
      - pkg: apache            
  service.running:
    - enable: True
    - name: httpd
    - watch:                       ##watch检测配置文件,若是发生变化会重启服务
      - pkg: apache
      - file: apache                    

运行配置管理:salt '*' state.sls apache 
salt '*' salt.highstate test=True #test=True用于测试语法

二、apache须要监控8080端口,代码以下:

首先修改apache的主配置文件,修改配置文件为 listen {{ port }},修改完成后能够直接在sls文件里定义
apache:
  pkg.installed:
    - name: httpd
  file.managed:
    - name: /etc/httpd/conf/httpd.conf
    - source: salt://apache/httpd.conf
    - require:
      - pkg: apache
    - template: jinja         ##调用jinja模板渲染
    - context:               ##这里能够是context或default效果同样
      port: 8080
  service.running:
    - enable: True
    - name: httpd
    - watch:
      - pkg: apache
      - file: apache
若是多台主机监听的端口不同,具体修改以下:
    apache:
  pkg.installed:
    - name: httpd
  file.managed:
    - name: /etc/httpd/conf/httpd.conf
    - source: salt://apache/httpd.conf
    - require:                           #先同步配置文件,后重启服务
      - pkg: apache
    - template: jinja
    - defaults:
      {% if grains.id == "10.13.41.80" %}
        port: 8080
      {% elif grais.id == "10.13.41.81" %}
        port: 8081
      {% else %}
        port: 80
      {% endif %}
  service.running:
    - enable: True
    - name: httpd
    - watch:
      - pkg: apache
      - file: apache

为了让sls文件不参杂业务数据,业务数据应该独立存放,到了该pillar登台的时候了。

/srv/pillar/apache/init.sls
apache:    
  {% if grains.id == "test" %}
     port: 8081
  {% elif grains.id == "test1" %}
     port: 8082
  {% else %}
     port: 80
  {% endif %}

 /srv/pillar/top.sls
 base:
   '*':
     - apache

salt '*' saltutil.regresh_pillar  ##刷新pillar
salt '*' pillar.get apache:port   ##取minion的pillar信息

/srv/salt/apache/deploy.sls
- template: jinja
- defaults: 
  port:{{salt['pillar.get']('apaceh:port',80)}}
saltstack官方参考样例:
saltstack官方提供的解决方案:

Job管理

job简介

jid:job id ,格式为%Y%m%d%H%M%S%f
master 在下发指令消息时,会附带上产生的jid。minion在接受到指令开始执行时,会在本地的cachedir(默认是/var/cache/salt/minion/)下的proc目录产生以该jid命名的文件,
用于在执行过程当中master查看当前任务的执行状况,指令执行完毕将结果传送给master后,删除该临时文件 master将minion的执行结果存放在本地
/var/cache/salt/master/jobs目录,默认缓存24小时(能够经过修改master配置文件keep jobs选项调整) salt '*' test.ping -v           ##能够显示任务的Jid,-v 显示命令执行的详细过程
https://github.com/saltstack/salt/pull/12365      ##salt-master -v时显示详细的执行结果
wrapper returns summary to a function           ##点击这个将代码加入到master中

Job基本管理

saltutil模块中的job管理方法

1、saltutil.running                                    ##查看minion当前正在运行的jobs
    salt '* saltutil.running 
2、saltutil.find_job <jid>                            ##查看指定jid的job(minion正在运行的jobs) 
    salt '*' saltutil.find_job 20160422114120923967    ##首先执行saltutil.running 查看jid
3、saltutil.signal_job <jid> <single>                 ##给指定的jid进程发送信号
     salt '*' saltutil.signal_job 20160422114328898570 9 
4、saltutil.term_job <jid>                          ##终止指定的jid进程(信号为15)
    salt '*' saltutil.term_job 20160422114528346315
5、saltutil.kill_job <jid>                          ##终止指定的jid进程(信号为9)同上,不在演示

salt runner中的job管理方法:

1、salt-run jobs.active                           ##查看全部minion当前正在运行的jobs(在全部minion上运行saltutil.running)
    salt-run jobs.active
2、salt-run jobs.lookup_jid <jid>                  ##从master jobs cache 中查询指定jid的运行结果
    salt-run jobs.lookup_jid 20160421215616643464
3、salt-run jobs.list_jobs                       ##列出当前master jobs cache 中的全部job
更多job管理请访问:

Schedule

简介

用于master/minion按期执行schedule中配置的任务; schedule可配置在master配置文件或minion的配置文件或pillar中; master端配置schedule运行runner; minion端配置schedule为远程执行; schedule系统并不会将运行结果发送给master或产生event; schedule支持returner,可将schedule执行结果发送到指定的returner中;

每30分钟minion执行一次highstate(配置在minion配置文件或pillar中)

# cat top.sls 
base:
  '*':
    - schedule
# cat schedule.sls              这个只要是sls结尾就OK
schedule:                       ####这个健必须是schedule,只能有一个,不能在其它的.sls文件中再使用,全部任务计划都放在这
  highstate:                    #每30min执行一次state.highstate
    function: state.highstate
    minutes: 30
--------------------------------------------------------------------
schedule:        
  helloword:
    function: cmd.run
    args: 
      - date >> /tmp/test.log
    minutes: 1

每分钟查询一次loadaverage,并将结果输出到mysql  returner中

schedule
 uptime:   
   function: status.uptime
   seconds: 60
   returner: mysql
#salt '*' saltutil.refresh_pillar 刷新
#salt '*' pillar.get schedule 查看

salt syndic

在syndic server上安装salt-master和salt-syndic,被syndic管理的minion要改/etc/salt/minion中master: syndic_server_IP;

Master 端的配置(/etc/salt/master):
order_masters: True

syndic 端的配置(/etc/salt/master):
syndic_master: Maste _IP
#syndic_master_port: MasterOfMaster_PORT
#syndic_pidfile: /var/run/salt-syndic.pid
#syndic_log_file: /var/log/salt/syndic.log

minion 端的配置(/etc/salt/minion):
master:syndic_master_IP

salt-ssh:

salt ssh基于ssh,无需zeromq和agent,支持sudo;

salt ssh的最终目标是可以和标准的salt完成相同的功能;

当前salt ssh只支持target端的glob和re,当前salt ssh依然为alpha状态,尚不能彻底替代标准的salt应用于生产环境中;

salt roster系统随salt ssh系统加入到salt代码中,主要为saltssh提供须要链接的主机和权限信息,默认/etc/salt/roster;

1、安装并修改配置文件
# yum -y install salt-ssh
# vim /etc/salt/roster
minion1:
 host: 10.96.20.117
 user: root
 passwd: chai

另optional parameters有:
port:        #(the target system's ssh port number)
sudo:        #(boolean to run command via sudo)
priv:        #(file path to ssh private key,defaults to salt-ssh.rsa)
timeout:     #(number of seconds to wait for response)
2、测试
# service salt-master stop
 salt-ssh '*' test.ping   #(有以下报错,解决办法:严格检查禁用或者先用ssh链接minion)
vim .ssh/config
host 10.96.20.117
StrictHostKeyChecking no
salt-ssh '*' -r 'echo hello' 直接执行shell命令

 ############################################################################################

1、.利用SaltStack执行远程命令.

 SaltStack的一个比较突出的优点是具有执行远程命令的功能,操做及方法与func类似,能够帮助运维人员完成集中化的操做平台。

命令格式: salt '<操做目标>' <方法> [参数]

示例:查看被控主机的内存使用状况.以下.

?
1
2
3
4
5
6
7
8
[root@locaohost~]# salt 'SN100-128' cmd.run "free -m"
SN100-128:
                  total       used       free     shared    buffers     cached
     Mem:          8001       6230       1770          0        222       2057
     -/+ buffers/cache:       3950       4051
     Swap:         5119          0       5119
 
#查看SN100-128主机内存使用状况. 

   其中针对<操做目标>,SaltStack提供了多种方法对被控端主机(ID)进行过滤,下面列举经常使用的具体参数。

1.) -E,--pcre,经过正则表达式进行匹配。示例:查询SN100-字符开头的主机id名是否连通,命令: salt -E '^SN100-*' test.ping,运行结果以下.

?
1
2
3
4
5
6
7
8
9
[root@localhost ~]# salt -E '^SN100-*' test.ping
SN100-128:
     True
SN100-129:
     True
SN100-130:
     True
 
#正则匹配主机的连通性.

2.) -L, --list,以主机id名列表的形式进行过滤,格式与python的列表类似,即不一样主机id名称使用逗号分隔。示例:获取主机id名为SN100-128,SN100-129;获取完整操做系统发行版名称,命令:salt -L 'SN100-128,SN100-129' grains.item osfullname,以下:

?
1
2
3
4
5
6
7
8
9
10
11
[root@localhost~]# salt -L 'SN100-128,SN100-129' grains.item osfullname
SN100-128:
     ----------
     osfullname:
         CentOS
SN100-129:
     ----------
     osfullname:
         CentOS
 
#列表形式匹配主机的操做系统类型

3.)-G --grain,根据被控主机的grains信息进行匹配过滤,格式为'<grain value>:<glob expression>',例如,过滤内核为Linux的主机能够写成'kernel:Linux',若是同时须要正则表达式的支持可切换成--grain-pcre参数来执行。示例:获取主机发行版本号为6.4的python版本号,命令:salt -G 'osrelease:6.4' cmd.run 'python -V',运行结果以下。

?
1
2
3
4
5
6
7
8
9
[root@localhost ~]# salt -G 'osrelease:6.4' cmd.run 'python -V'
SN100-128:
     Python 2.6.6
SN100-129:
     Python 2.6.6
SN100-130:
     Python 2.6.6
 
#grain形式匹配主机的python版本

匹配操做系统发行版本为CentOS的被控端能够经过-G参数来过滤。

?
1
2
3
4
5
6
7
8
9
[root@localhost~]# salt -G 'os:CentOS' test.ping
SN100-130:
     True
SN100-128:
     True
SN100-129:
     True
 
#返回True,则表示都是CentOS系统 

4) -I --pillar,根据被控主机的pillar信息进行匹配过滤,格式为"对象名称:对象值",例如,过滤全部具有'apache:httpd' pillar值的主机。示例:探测具备'nginx:root:/data' 信息的主机连通性,命令:salt -I 'nginx:root:/data' test.ping ,运行结果以下。

?
1
2
3
4
5
6
7
8
9
[root@localhost~]# salt -I 'nginx:root:/data' test.ping
SN100-128:
     True
SN100-129:
     True
SN100-130:
     True
 
#pillar形式匹配主机的连通性

其中pillar属性配置文件以下:

?
1
2
nginx:
        root: /data

5.) -N --nodegroup,根据主控端master配置文件中的分组名称进行过滤,(主机信息支持正则表达式、grain、条件运算符等),一般根据业务类型划分,不一样业务具有相同的特色,包括部署环境、应用平台、配置文件等。举例分组配置信息以下:

【/etc/salt/master】

nodegroups:
   group1: 'L@SN100-128,SN100-129,SN100-130'
   group2: 'L@SN200-131'

其中,L@表示后面的主机id格式为列表,即主机id以逗号分隔;G@表示已grain格式描述;S@表示已IP子网或地址格式描述。

      示例:探测group2被控主机的连通性,其命令为:salt -N group2 test.ping .

6.) -C --compound,根据条件运算符not、and、or去匹配不一样规则的主机信息。示例:探测SN100开头而且操做系统版本为CentOS的主机连通性,命令以下:

?
1
salt -C 'E@^SN100-* and G@os:Centos' test.ping 

其中,not语句不能做为第一个条件执行,不过能够经过如下方法来规避,示例:探测非SN100开头的主机连通性,其命令为:salt -C '* and not E@^SN100-*' test.ping。

7) -S --ipcidr,根据被控主机的IP地址或IP子网进行匹配,示例以下:

?
1
2
salt -S 192.168.0.0/16 test.ping
salt -S 192.168.1.10 test.ping

salt-run命令:

判断minion端是否链接到master端

?
1
2
3
4
5
6
语法:salt-run [options] [runner.func]
 
salt-run manage.status         #查看全部minion状态
salt-run manage.down           #查看全部没在线minion
salt-run manged.up             #查看全部在线minion
salt-run manage.versions       #查看版本

Salt job id管理

?
1
2
3
4
5
salt '*' test.ping -v
 
salt '*' saltutl.running  #显示minion当前正在运行的job
 
salt '*' saltutl.kill_job jid   #强制退出远程执行的job进程.

1、ZeroMQ描述

  咱们进行自动化运维大多数状况下,是咱们的服务器数量已经远远超过人工SSH维护的范围,SaltStack能够支数以千计,甚至更多的服务器,这些性能的提供主要来自于ZeroMQ,由于SaltStack地城是基于ZeroMQ进行高效的网络通讯,ZMQ用于node与node间的通讯,node能够是主机也能够能够是进程。

2、ZeroMQ简介

        ZeroMQ(咱们一般还会OMQ,Zmq等来表示)是一个简单好用的传输层,像框架同样的一个套接字库,他使用的socket编程更加简单、简洁和性能更高,它仍是一个消息处理队列库,可在多个线程、内核和主机核之间弹性伸缩。

  发布与订阅

            ZeroMQ支持Publish/Subscribe,即发布与订阅模式,咱们常常简称Pub/Sub
            如图:
            
            Salt Master运行两个网络服务,其中一个是ZeroMQ Pub系统,默认监听4505端口,能够经过修改/etc/salt/master配置文件的publish_port参数设置,它是salt的消息发布系统,若是查看4505端口,会发现全部Minion链接到Master的4505端口,TCP状态持续保持为ESTABLISHED

            [root@salt-client ~]# lsof -i :4505
            COMMAND    PID USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
            salt-mini 2630 root   24u  IPv4  41122      0t0  TCP 172.16.17.12:41314->salt:4505 (ESTABLISHED)
            这样Salt Master发布一个消息,全部链接到4505这个Pub端口上的Minion都会接受到这个消息,而后每一个Minion会再判断本身是否须要执行这个消息。        

  请求与响应

            ZeroMQ支持Request-Reply,即请求与响应模式,咱们常常简称REQ/REP
            如图:
            
            Salt Master运行的第二个网络服务就是ZeroMQ REP系统,默认监听4506端口,能够经过修改/etc/salt/master配置文件的ret_port参数设置,他是salt客户端与服务端通讯的端口,好比说Minion执行某个命令后的返回值就是发送Master的4506这个REP端口。
            因为咱们在最初安装了python-setproctitle软件包,因此咱们能够直接看到Salt Master启动的进程的名称。     

 [root@ops-node1 ~]# ps aux | grep salt
            /usr/bin/salt-master -d ProcessManager  #中心进程管理器
            /usr/bin/salt-master -d _clear_old_jobs  #清除旧的Jobs文件及更新fileserver
            /usr/bin/salt-master -d Publisher       #将任务PUB到Minion端
            /usr/bin/salt-master -d EventPublisher  #Event Publisher进程
            /usr/bin/salt-master -d ReqServer_ProcessManager #ReqServer进程管理器
            /usr/bin/salt-master -d MWorker  #工做进程
            /usr/bin/salt-master -d MWorker  #工做进程
            /usr/bin/salt-master -d MWorker  #工做进程
            /usr/bin/salt-master -d MWorker  #工做进程
            /usr/bin/salt-master -d MWorker  #工做进程
            /usr/bin/salt-master -d MWorkerQueue #将Ret接口(ROUTER)数据转发到Worker(DEALER)
相关文章
相关标签/搜索