Saltstack 的学习总结

Saltstack 的学习总结

一 、Saltstack的简介

   SaltStack采用 C/S模式,server端就是saltmasterclient端就是minionminionmaster之间通过ZeroMQ消息队列通信。minion上线后先与master端联系,把自己的pub key发过去,这时master端通过salt-key-L命令就会看到minionkey,接受该minion-key后,也就是masterminion已经互信。master可以发送任何指令让minion执行了,salt有很多可执行模块,比如说cmd模块,在安装minion的时候已经自带了,它们通常位于你的python库中,locate salt | grep/apps/ns1/python/bin/salt 可以看到salt自带的所有东西。这些模块是python写成的文件,里面会有好多函数,如cmd.run,当我们执行/apps/ns1/python/bin/salt'*' cmd.run 'uptime'的时候,master下发任务匹配到的minion上去,minion执行模块函数,并返回结果。master监听45054506端口,4505对应的是ZMQPUBsystem,用来发送消息,4506对应的是REPsystem是来接受消息的。

具体步骤如下

1.       SaltstackMasterMinion之间通过ZeroMq进行消息传递,使用了ZeroMq的发布-订阅模式,连接方式包括tcpipc

2.       salt命令,将cmd.runls命令从salt.client.LocalClient.cmd_cli发布到master,获取一个Jodid,根据jobid获取命令执行结果。

3.       master接收到命令后,将要执行的命令发送给客户端minion

4.       minion从消息总线上接收到要处理的命令,交给minion._handle_aes处理

5.       minion._handle_aes发起一个本地线程调用cmdmod执行ls命令。线程执行完ls后,调用minion._return_pub方法,将执行结果通过消息总线返回给master

6.       master接收到客户端返回的结果,调用master._handle_aes方法,将结果写的文件中

7.       salt.client.LocalClient.cmd_cli通过轮询获取Job执行结果,将结果输出到终端。

二、saltstack 的安装

(略)

 

三、Salt常用命令(远程执行命令)

 1、salt该命令执行salt的执行模块,通常在master端运行,也是我们最常用到的命令

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

如: /apps/ns1/python/bin/salt '*' test.ping

2、salt-run 该命令执行runner(salt带的或者自定义的,runner以后会讲),通常在master端执行,比如经常用到的manage

    /apps/ns1/python/bin/salt-run [options] [runner.func]

/apps/ns1/python/bin/salt-run manage.status   ##查看所有minion状态

/apps/ns1/python/bin/salt-run manage.down     ##查看所有没在线minion

/apps/ns1/python/bin/salt-run manged.up      ##查看所有在线minion

3、salt-key 密钥管理,通常在master端执行

/apps/ns1/python/bin/salt-key [options]

/apps/ns1/python/bin/salt-key -L             ##查看所有minion-key

/apps/ns1/python/bin/salt-key -a<key-name>   ##接受某个minion-key

/apps/ns1/python/bin/salt-key -d<key-name>   ##删除某个minion-key

/apps/ns1/python/bin/salt-key -A             ##接受所有的minion-key

/apps/ns1/python/bin/salt-key -D             ##删除所有的minion-key

4、salt-call 该命令通常在minion上执行,minion自己执行可执行模块,不是通过master下发job

         salt-call [options] <function> [arguments]

salt-call test.ping           ##自己执行test.ping命令

salt-call cmd.run 'ifconfig'  ##自己执行cmd.run函数

5、salt-cp 分发文件到minion,不支持目录分发,通常在master运行

salt-cp [options] '<target>' SOURCEDEST

salt-cp '*' testfile.html /tmp

salt-cp 'test*' index.html /tmp/a.html

6salt-master master运行命令

salt-master [options]

salt-master           ##前台运行master

salt-master -d        ##后台运行master

salt-master -l debug   ##前台debug输出

7、  salt-minion minion运行命令

salt-minion [options]

salt-minion           ##前台运行

salt-minion -d        ##后台运行

salt-minion -l debug   ##前台debug输出

四、saltstack 的常用模块以及API

       简介

 Saltstack 提供了十分丰富的功能模块,涉及操作系统的基础信息、常用工具支持等。可以参看更多模块的相关信息:

https://docs.saltstack.com/en/latest/ref/modules/all/index.html

可以通过/apps/ns1/python/bin/salt ‘*’ sys.list_modules 参看当前版本系统支持的相关模块。

以下是运行/apps/ns1/python/bin/salt ‘*’ sys.list_modules命令后的部分截图


接下来是saltstack的十大常用模块以及对应API的介绍
Saltstack –API的简介

 API的原理是调用master client 模块,创建LocalClient对象,在调用cmd()方法来实现。

示例:通过API实现test.ping

         Importsalt.client

         client= salt.client.LoaclClient()

         ret= client.cmd(‘*’,’test.ping’)

         printret

运行后的结果如下:

Archive 模块

1)  功能:实现系统层面的压缩包调用,支持gunzip、gzip、rar、tar、unrar、unzip等

2)  示例

利用gunzip 对/apps/file/soucrefile.txt.gz 解压

/apps/ns1/python/bin/salt ‘*’ archive.gunzip  /apps/file/soucrefile.txt.gz

 

利用gzip 对/apps/file/soucrefile.txt 解压

/apps/ns1/python/bin/salt ‘*’ archive.gzip  /apps/file/soucrefile.txt

 

3)  API 调用示例:利用gunzip 对/apps/file/soucrefile.txt.gz 解压

Import salt.client

client = salt.client.LocalClient()

ret = client.cmd(‘*’,’archive.gzip’,[‘/apps/file/soucrefile.txt.gz’])

cmd 模块

1)  功能:实现远程的命令行调用执行(默认具备root操作权限)

2)  示例:

获取所有被控主机的内存使用情况

/apps/ns1/python/bin/salt ‘*’ cmd.run “free -m”

 

3)API 调用示例: 获取所有被控主机的内存使用情况

#!_INSX/python/bin/python

# -*- coding:UTF-8 -*-

Import salt.client

Client = salt.client.LocalClient()

Ret = Client.cmd(‘*’,’cmd.run’,[‘free –m’])

cp模块

1)  实现远程文件、目录的复制,以及下载url 文件操作等

2)  示例

将指定被控主机的/etc/hosts 文件复制到被控制主机本地的file 目录下(/apps/file)

/apps/ns1/python/bin/salt ‘*’ cp.cache_local_file  /etc/hosts

 

将主服务器file_roots指定位置下的目录复制到被控主机

/apps/ns1/python/bin/salt ‘*’ cp.get_dir  salt://path/to/dir/  /minion/dest

 

下载URL内容到被控主机指定位置

/apps/ns1/python/bin/salt ‘*’ cp.get_url  http://www.slashdot.org  /tmp/index.html

 

3)  API调用示例:下载URL内容到被控主机指定位置

#!_INSX/python/bin/python

# -*- coding:UTF-8 -*-

Import salt.client

Client = salt.client.LocalClient()

Ret = Client.cmd(‘*’,’cp.get_url’,[‘http://www.slashdot.org’,’ /tmp/index.html’])

cron模块

1)  功能:控主机的crontab操作

2)  示例:

查看指定被控主机、root用户的crontab清单

/apps/ns1/python/bin/salt ‘*’ cron.row_cron root

 

为指定的被控主机、root用户添加/usr/local/weekly任务作业

/apps/ns1/python/bin/salt ‘*’ cron.set_job root ‘*’ ‘*’ ‘*’‘*’ 1 /usr/local/weekly

 

删除指定的被控主机、root用户crontab的/usr/local/weekly任务作业

/apps/ns1/python/bin/salt ‘*’ cron.rm_job root/usr/local/weekly

 

3)  API调用:删除指定的被控主机、root用户crontab的/usr/local/weekly任务作业

#!_INSX/python/bin/python

# -*- coding:UTF-8 -*-

Import salt.client

Client = salt.client.LocalClient()

Ret = Client.cmd(‘*’,’cron.rm_job’,[‘root’,’/usr/local/weekly’])

dnsutil模块

1)  功能:实现被控主机通用DNS相关操作

2)  示例:

添加指定被控主机hosts的主机配置项

/apps/ns1/python/bin/salt ‘*’ dnsutil.hosts_append/etc/hosts 127.0.01 ad1.yuk.com ,d2.yuk.com

 

删除指定被控主机hosts的主机配置项

/apps/ns1/python/bin/salt ‘*’ dnsutil.hosts_remove/etc/hosts ad1.yuk.com

 

3)  API 调用:删除指定被控主机hosts的主机配置项

#!_INSX/python/bin/python

# -*- coding:UTF-8 -*-

Import salt.client

Client = salt.client.LoaclClient()

Ret = Client.cmd(‘*’,’dnsutil.hosts_remove’,[‘/etc/hosts’,’ad1.yuk.com’])

file模块

1)  功能:被控主机文件常见操作,包括文件读写、权限、查找、校验等

2)  示例:

校验所有被控主机/etc/fstab文件的md5是否为6254e84e2f6ffa54e0c8d9cb230f5505,一致则返回True

/apps/ns1/python/bin/salt ‘*’  ilechenk_hash

/etc/fstab d5=6254e84e2f6ffa54e0c8d9cb230f5505

 

复制本地所有被控主机本地 /path/to/src 文件到本地的/path/to/dat文件

/apps/ns1/python/bin/salt ‘*’ file.copy /path/to/src   /path/to/dat

 

获取所有被控主机/etc/passwd 的stats 信息

/apps/ns1/python/bin/salt ‘*’  ile.stats /etc/passwd

 

获取所有被控主机/etc/passwd的权限mode,如755,644

/apps/ns1/python/bin/salt ‘*’ file.get_mode /etc/passwd

 

修改所有被控主机/etc/passwd的权限mode为0644

/apps/ns1/python/bin/salt ‘*’ file.set_mode /etc/passwd0644

 

在所有被控主机创建/opt/test目录

/apps/ns1/python/bin/salt ‘*’ file.mkdir /opt/test

 

给所有被控主机的/tmp/test/testc.onf 文件追加内容”maxclient 100”

/apps/ns1/python/bin/salt ‘*’ file.append/tmp/test/testc.onf  ”maxclient 100”

 

删除所有被控主机的/tmp/foo文件

/apps/ns1/python/bin/salt ‘*’ file.remove /tmp/foo

 

3)API调用:删除所有被控主机的/tmp/foo文件

#!_INSX/python/bin/python

Import salt.client

Client = salt.client.LocalClient()

Ret = Client.cmd(‘*’,’file.remove’,[‘/tmp/foo’])

Iptables模块

1)  功能:被控主机iptables支持

2)  示例:

在所有被控端主机追加(append)、插入(insert)iptables规则,其中INPUT为输入链

Salt ‘*’ iptables.append filter INPUT rule = ‘-m state –stateRELATED,ESTABLISHED –J ACCEPT’

 

保存所有被控端主机规则到本地硬盘(/etc/sysconfig/iptales)

/apps/ns1/python/bin/salt ‘*’ iptables.save  etc/sysconfig/iptales

 

3)API调用:在所有被控端主机追加(append)iptables规则,其中INPUT为输入链

#!_INSX/python/bin/python

Import salt.client

Client = salt.client.LocalClient()

Ret = Client.cmd(‘*’,’iptables.append’,[‘filter’,’INPUT’, ‘rule= \’-m state ELATED,ESTABLISHED –J ACCEPT\’’])

Network模块

1)  功能:返回被控主机网络信息

2)  示例:

获取所有被控主机的MAC地址

/apps/ns1/python/bin/salt ‘*’ network.hwaddrs eth0

 

获取所有被控主机的网卡配置信息

/apps/ns1/python/bin/salt ‘*’ network.interfaces

 

获取所有被控主机的IP地址配置信息

/apps/ns1/python/bin/salt ‘*’ network.ip_addrs

 

获取指定被控主机的子网信息

/apps/ns1/python/bin/salt ‘*’ network.subnets

 

3)  API调用:获取指定被控主机的子网信息

#!_INSX/python/bin/python

Import salt.client

Client =salt.client.LocalClient()

Ret = Client.cmd(‘*’,’network.subnets’)

Pkg包管理模块

1)  功能:被控主机程序包管理,如yum、apt-get等

2)  示例:

为所有被控主机安装php环境

/apps/ns1/python/bin/salt ‘*’ pkg.install php

 

卸载所有被控主机的php环境

/apps/ns1/python/bin/salt ‘*’ pkg.remove php

 

升级所有被控主机的软件包

/apps/ns1/python/bin/salt ‘*’ pkg.upgrade

 

3)API 调用:卸载所有被控主机的php环境

#!_INSX/python/bin/python

Import salt.client

Client =salt.client.LocalClient()

Ret = Client.cmd(‘*’,’pkg.remove’,[‘php’])

Service服务模块

1)  功能:被控主机程序包服务管理

2)  示例:

开启(enable)、禁用(disables)nginx开机自启动服务

/apps/ns1/python/bin/salt ‘*’ service.enable nginx

/apps/ns1/python/bin/salt ‘*’ service.disable nginx

 

针对nginx服务的reload、restart、start、stop、status操作

/apps/ns1/python/bin/salt ‘*’ service.reload nginx

/apps/ns1/python/bin/salt ‘*’ service.restart nginx

/apps/ns1/python/bin/salt ‘*’ service.start nginx

/apps/ns1/python/bin/salt ‘*’ service.stop nginx

/apps/ns1/python/bin/salt ‘*’ service.status nginx

 

3)  API调用:针对niginx服务的reload操作

#!_INSX/python/bin/python

Import salt.client

Client = salt.client.LocalClient()

Ret = Client.cmd(‘*’,’service.reload’,[‘nginx’])

 

Grains组件

Grains是Saltstack最重要的组件之一,grians的作用是收集被控主机的基本信息,这些信息通常都是一些静态类型的数据,包括被控主机的CPU、内核、操作系统、虚拟化等信息。

 

Grains常用操作命令

示例1:匹配内版本为2.6.32-358.14.1e16.x86_64的主机

         /apps/ns1/python/bin/salt–G ‘kernelrelease:2.6.32-358.14.1e16.x86_64’ cmd.run ‘uname –a’

 

示例2:获取所有主机的grains项信息

/apps/ns1/python/bin/salt ‘*’ grains.ls

 

示例3:获取被控主机单项数据

/apps/ns1/python/bin/salt ‘*’ grains.itemos

定义Grains数据

定义grains数据有两种,其中一种为在被控主机定制配置文件,这种比较方便,但有局限性;另一种是通过主控端扩展模块API来实现,用Python编程动态定义。

被控端主机定制grains数据

         通过手动更新被控主机的grains文件、让master进行采集

1)  在每台被控主机上新建/etc/salt/minion.d/hostinfo.conf文件

Grains:

           Roles:

                    ---webserver

2)  重启salt-minion服务

(1)    Cp/apps/ns1/utils

(2)    ./salt-minion restart

通过主控端master扩展API来实现

         首先,需要明确master上的bash目录,可以到/etc/salt/master配置文件的file_roots处查看,默认为/srv/salt

1)  新建一个_grains目录

Install –d /apps/ns1/srv/salt/_grains

 

2)  在_grains目录下新建一个py文件(例如)

[/srv/salt/_grains/sysprocesss.py]

#!_INSX/python/bin/python
# -*- coding:UTF-8 -*-
import os
import sys
import commands
def Grains_openfile():
   
"""
   
:return: os max open file ofgrains value
    """
   
grains = {}
   
# init default value
   
_open_file = 65536
   
try:
       
getulimit =commands.getstatusoutput('source /etc/profile;ulimit -n')
   
except Exception as e:
       
pass
   
if getulimit[0] == 0:
       
_open_file = int(getulimit[1])
   
grains['max_open_file'] = _open_file
   
print grains
   
return grains

3)  新建文件之后,需要分发到所有Minion上

/apps/ns1/python/bin/salt ‘*’ saltutil.sync_all

 

4)  刷新模块

/apps/ns1/python/bin/salt ‘*’ sys.reload_modules

 

5)  收集数据

/apps/ns1/python/bin/salt ‘*’ grains.item max_open_file

 

6)  运行结果

Pillar组件

Pillar简介

         Pliiar也是Saltstack最重要的组件之一,其主要作用是定义与被控主机相关的任何数据,定义好的的数据可以被其他组件使用,如模板、state、API等,在pillar定义的数据与不同业务特性的被控主机相关联,这样不同被控主机只能看到自己匹配的数据,因此pillar安全性很高,适用于一些比较敏感的数据,这是区别于grains的最关键的一点。

Pillar的定义
主配置文件定义

         Saltstack默认将主控端配置文件中的所有数据都定义到pillar中,而且对所有被控主机开放。可以通过修改/etc/salt/master配置中的pillar_opts:True 或False来定义是否开启或者禁用这项功能。

   运行:/apps/ns1/python/bin/salt‘*’ pillar.data 命令来查看效果

 

SLS文件定义

Pillar 支持在sls文件中定义数据,格式必须符合YAML规范,与SaltStack的组件十分相似。两者文件的配置格式、入口文件top.sls都是一致的。

1)  定义pillar 的主要目录

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

 Pillar_roots:

           Base:

       ---/srv/pillar

同时创建pillar目录,执行命令

           Install  -d /apps/ns1/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

(1)      刷新被控制主机的pillar 信息,执行如下命令。

/apps/ns1/python/bin/salt '*' saltutil.refresh_pillar

 

(2)      查看定义的data.sls数据,执行如下命令。

/apps/ns1/python/bin/salt '*' pillar.data appname flow

 

(3)      运行结果:


Pillar的使用

完成pilllar配置后,接下来简单介绍使用方法。可以在state、模板文件中引用,模板格式为“{{ pillar 变量}}”,例如:

   {{pillar[‘appname’] }}  (一级字典)

   {{pillar[‘flow][‘maxconn’] }}(二级字典)或者{{ salt[‘pillar.get’] (‘flow’:’maxconn’,{}) }}

  

  Python API格式如下:

   Pillar[‘flow’][‘maxconn’]

   Pillar.get(‘flow:appname’, {})

 

操作目标主机

  通过 –I 选项来使用Pillar 来配置被控主机

  /apps/ns1/python/bin/salt-I 'appname:website' test.ping

 

结合grains处理数据的差异性

        首先通过结合grains的id信息来区分不同id的maxcpu的值,其次进行引用观察匹配的信息。我还是延伸‘pillar的定义’的例子将data.sls 修改成如下形式,其中,“if … else …endif”为jinja2的模块语法,jinja2语法可参考:http://jinja.pocoo.org/docs/2.10/templates/

         [/srv/salt/data.sls]

Appname: website

Flow:

   Maxconn: 3000

   Maxmem: 6G

   {% if grains[‘id’] == ‘172.30.154.60’ %}

   Maxcpu: 8

   {% else %}

   Maxcpu: 4

   {% endif %}

编写好data.sls文件后。执行以下步骤:

(1)      刷新被控制主机的pillar 信息,执行如下命令。

/apps/ns1/python/bin/salt '*' saltutil.refresh_pillar

 

(2)      查看定义的data.sls数据,执行如下命令。

/apps/ns1/python/bin/salt '*' pillar.data appname flow

(3)      运行结果:


State介绍

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

https://docs.saltstack.com/en/latest/ref/states/all/index.html

state的定义

state的定义是通过sls文件进行描述的。支持YAML语法,定义的规则如下:

 $ID:

$State:

     —$state: states

其中:

  $ID,定义state的名称,通常采用与描述的对象保存一致的方法,如apache、nginx等。

$State,管理对象的类型,,看参考:

https://docs.saltstack.com/en/latest/ref/states/all/index.html

 $state: states,定制对象的状态

如下例子:

   Apache:

          Pkg:

—installed

     Service:

        —running

       —require:

       —pkg: apache

  注意:第6行是关键字require,它确保了apache服务只有在成功安装软件包后才会启动

State的使用

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

定义pillar

[/srv/pillar/top.sls]

Base:

  “*”:

—apache

在top.sls中引用二级配置有两种方式:一是直接引用,二是创建apache目录,在引用目录中的init.sls文件。

         先执行如下命令:

          Install -d /srv/pillar/apache  或者mkdir/srv/pillar/apache

[/srv/pillar/apache/init.sls]

Pkgs:

{% if grains[‘os_family’]== ‘Debian’ %}

  Apache: apache2

  {% elif grains[‘os_family’] == ‘RedHat’ %}

  Apache: httpd

  {% elif grains[‘os_family’] == ‘Arch’ %}

  Apache: apache

{% endif %}

编写好init.sls文件后。执行以下步骤:

(1)      刷新被控制主机的pillar 信息,执行如下命令。

/apps/ns1/python/bin/salt '*' saltutil.refresh_pillar

 

(2)      查看定义的data.sls数据,执行如下命令。

/apps/ns1/python/bin/salt '*' pillar.data pkgs

定义state

[/srv/salt/top.sls]

Base:

   ‘*”:

                   —apache

[/srv/salt/apache/init.sls]

Apache:

         Pkg:

                   —installed

                   —name:  {{ pillar[‘pkgs’][‘apache’] }}

         Sevice:

                   —name:  {{ pillar[‘pkgs’][‘apache’] }}

                   —require:

                            —pkg: {{pillar[‘pkgs’][apache’] }}

执行state

/apps/ns1/python/bin/salt'*' state.highstate

 

Saltstack事件系统与反应系统(event and reacter system)

简介

Master和Minion是基于ZMQ通信的。它们通信的消息队列就是一些事件。反应系统就是基于事件系统的。一条消息其实就是一个事件,事件通常是一个字典数据,这个字典数据通常包含tag,这个tag是用来区分用途过滤消息的。

事件系统(event system)
捕捉事件(list event)
事件代码

官方网给的事件捕捉程序eventlisten 可见:

https://github.com/saltstack/salt/blob/develop/tests/eventlisten.py

打开网址,复制下载,不要直接wget

运行程序

Master: python  eventlisten.py                        ##捕捉master端的event直接运行即可

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

发送事件(fire event)
Matert 发给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是你mastersock_dir

>>> data = event.get_event()

>>> print(data)       ##查看内容

>>> data = event.get_event(wait=10, tag='auth') ##wait是指timeout时间,默认5s,tag来过滤事件,可省略

>>> print(data)               

>>> for data inevent.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/minionminion端的sock_dir,minion_id是该Minionid

>>> data = event.get_event()

>>> print(data)

>>> for data inevent.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

修改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

建立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 %}

 

下面来解释一下这两个文件,reactersls文件是支持jinja的,所以第一行是通过jinja来判断,reactersls支持两个变量datatag, 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

Returners

默认所有minion返回的值都会发送到master端,我们可以看到,returner就是让Minion把返回的值发给其它地方,如redis,MySQL,或者一个文本下面我们来自定义一个returner

1.建立自定义returner

mkdir -p /srv/salt/_returners;

vim mysql.py  ##就用官方给的例子吧,修改其中mysqlHost,userpass

内容见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查看

扩展salt

扩展salt简述

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

可执行模块 Execution Modules

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

Grains

扩展grainsgrains是一些静态信息,可能好多我们需要的没有,我们可以通过编写grains模块自定义grains

状态模块 State Module

如我们常用的pkg.install,file.managed

Returners

我们可以自定义returner,将返回的数据发送到其他存储,只要符合固定的格式就行了

Runner

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

自定义可执行模块

所有可执行modulehttps://github.com/saltstack/salt/tree/develop/salt/modules,或http://docs.saltstack.com/ref/modules/all/index.html?highlight=full%20list%20builtin

建立自定义模块目录,通常所有自定义模块放在该目录下

mkdir /srv/salt/_modules

编写模块

vim test.py

#!_INSX/python/bin/python
# -*- 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__是包含了所有Pillargrains字典,__salt__是所有可执行函数对象的字典,通常最常使用的就是这三个变量了。再往下面是定义了函数install,salt中一般不用’%s’ %var这种格式化形式,而是使用字符串的format方法,具体使用见百度。下面就是通过__salt__执行了cmd.run这个函数来运行yum命令,很简单吧,最后把结果返回回去。

测试

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

自定义grains

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

自定义returner

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

#!_INSX/python/bin/python
# -*- coding:UTF-8 -*-

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中。

应用实例

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

创建模块方法文件

mkdir /srv/salt/_modules

默认没有此文件,自己生成一个

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

#!_INSX/python/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

 

然后先测试备份方法

      salt ‘*’ cp_bakfile.CpFile 1234  /tmp/test    #id + 路径上节点服务器上查看,存在

 

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

salt '*' cp_bakfile.RollBack 1234

参考

[1] 刘天斯. Python自动化运维:技术与最佳实践[M].北京.机械工业出版社.2014.11 169-186

[2] http://outofmemory.cn/saltstack/salt


  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值