设为首页 收藏本站
查看: 4262|回复: 0

[经验分享] saltstack编译安装与小马运维开发

[复制链接]

尚未签到

发表于 2015-9-16 10:08:06 | 显示全部楼层 |阅读模式
  http://potaski.blog.iyunv.com/3099084/1317853
  本系列文章由初学者写,高手就不要浪费时间了
  
  环境:centos6.2 minimum(最小化安装)
  特点:无外网
  
  测试机没有外网,就自己手动源码安装把,的确是要累一些...做个笔记记录一下
  官方文档说:安装需求
  python >=2.6 <3.0
  zeromq >=2.1.9
  pyzmp >=2.1.9
  pycrypto
  msgpack-python
  yaml
  jinja2
  
  
  ===== 安装流水帐如下了 =====
  先安装了salt-0.17,然后一发不可收拾...
  
  启动master报错 - ImportError: No module named yaml
  解决
  PyYAML-3.10.tar.gz
  https://pypi.python.org/pypi/PyYAML/3.10#downloads
  
  启动master报错 - ImportError: No module named jinja2
  解决
  Jinja2-2.7.1.tar.gz
  https://pypi.python.org/pypi/Jinja2/2.7.1
  安装jinja2报错 - error: Could not find suitable distribution for Requirement.parse('markupsafe')
  解决
  MarkupSafe-0.18.tar.gz
  https://pypi.python.org/simple/MarkupSafe/
  
  启动master报错 - ImportError: No module named zmq
  解决
  pyzmq-13.1.0.tar.gz
  https://pypi.python.org/pypi/pyzmq/13.1.0#downloads
  安装pyzmq报错,其中有一段 - Failed with default libzmq, trying again with /usr/local
  解决
  libzmq-master.zip
  https://github.com/zeromq/libzmq
  
  启动master报错 - ImportError: No module named M2Crypto
  M2Crypto-0.21.1.tar.gz
  https://pypi.python.org/pypi/M2Crypto/0.21.1
  安装m2crypto报错 - /usr/include/openssl/opensslconf.h:31: Error: CPP #error ""This openssl-devel package does not work your architecture?"". Use the -cpperraswarn option to continue swig processing.
  error: command 'swig' failed with exit status 1
  解决
  msgpack-python-0.3.0.tar.gz
  https://pypi.python.org/pypi/msgpack-python/0.3.0
  
  然后发现master和minion在运行一段时间后会报以下错误 - NameError: global name 'AES' is not defined
  只好在源码中搜索了
  [iyunv@DFS-1 salt]# grep -R AES /usr/lib/python2.6/site-packages/salt/
  /usr/lib/python2.6/site-packages/salt/crypt.py: from Crypto.Cipher import AES
  然后google了一下Crypto.Cipher,解决
  解决:
  https://pypi.python.org/pypi/pycrypto/2.6
  ========================
  
  整理一下安装过程:
  unzip libzmq-master.zip
  cd libzmq-master
  ./autogen.sh
  cd ..
  tar zxf PyYAML-3.10.tar.gz
  cd PyYAML-3.10
  /usr/bin/python setup.py install > install.log
  cd ..
  tar zxf MarkupSafe-0.18.tar.gz
  cd MarkupSafe-0.18
  /usr/bin/python setup.py install > install.log
  cd ..
  tar zxf Jinja2-2.7.1.tar.gz
  cd Jinja2-2.7.1
  /usr/bin/python setup.py install > install.log
  cd ..
  tar zxf pyzmq-13.1.0.tar.gz
  cd pyzmq-13.1.0
  /usr/bin/python setup.py install > install.log
  cd ..
  tar zxf M2Crypto-0.21.1.tar.gz
  cd M2Crypto-0.21.1
  sed -i 's/python/\/usr\/bin\/python/g' fedora_setup.sh
  # 注:我的默认python版本为2.5,此举为切换运行环境到centos6.2自带的python2.6上
  ./fedora_setup.sh install
  cd ..
  tar zxf msgpack-python-0.3.0.tar.gz
  cd msgpack-python-0.3.0
  /usr/bin/python setup.py install > install.log
  cd ..
  tar zxf pycrypto-2.6.tar.gz
  cd pycrypto-2.6
  /usr/bin/python setup.py install > install.log
  cd ..
  tar zxf salt-0.17.0.tar.gz
  cd salt-0.17.0
  /usr/bin/python setup.py install > install.log
  cd ..
  
  注:安装完后salt在启动后仍然发现一个缺包的warning
  [WARNING ] virtualenv not installed, please install first
  virtualenv是啥呢,搜索得
  https://pypi.python.org/pypi/virtualenv/
  不影响使用,慢慢再深入学习
  
  salt运行
  源码安装后,还需要手动拷贝配置文件模板到/etc/salt/内
  cp salt-0.17.0/conf/master /etc/salt/
  cp salt-0.17.0/conf/minion /etc/salt/
  salt的master与minion安装方式相同,启动不同的服务即可。正确安装完毕后可以看到一批salt命令
  [iyunv@DFS-1 ~]# salt
  salt salt-call salt-cp salt-key salt-master salt-minion salt-run salt-ssh salt-syndic
  启动master:会启动4505、4506端口
  [iyunv@DFS-1 ~]# salt-master
  启动minion:不启动任何端口
  [iyunv@DFS-1 ~]# salt-minion
  
  salt配置
  基本上按配置文件模板启动就可以使用,测试中进行了一些自定义
  [iyunv@DFS-1 salt]# diff master master.bak |grep "<"
  < default_include: /data1/salt/master.d/*.conf # 我在这里单独进行file_root、pillar_root、nodegroup的配置
  < publish_port: 4505
  < user: root
  < max_open_files: 100000
  < worker_threads: 1
  < ret_port: 4506
  < pidfile: /tmp/salt-master.pid
  < root_dir: /data1/salt
  < pki_dir: /data1/salt/pki/master
  < cachedir: /data1/salt/cache/master
  < auto_accept: True # 自动认证,免除一些手续
  minion的配置没有做任何改动(除了minion id)
  
  本文出自 “我是闪电~我是闪电~” 博客,请务必保留此出处http://potaski.blog.iyunv.com/3099084/1317853
  
  
  
  http://blog.iyunv.com/app_ops/article/details/17147083

SaltStack的非标准安装

  先解释下题目吧,什么是"SaltStack的非标准安装"。
  简单先介绍下环境,笔者所运维的环境基本上以CentOS为主,有少部分Ubuntu。CentOS系统的版本也从5.4到6.4都有包括,进尔导致salt所依赖的python语言环境的版本也从2.4.3到2.6.6都有。因为是线上的系统,系统版本的升级或者python版本的升级,都有可能带来一定的风险性。所以从本意上来说,这次做的salt安装,最好不要对线上环境有任何的影响。(做过运维的都知道,最好不要对稳定的环境做任何的变化。)
  
  好了,基本的思路定了,再看下新版salt的安装需求:

  •   Python 2.6 >= 2.6 <3.0
  •   ZeroMQ >= 2.1.9
  •   pyzmq >= 2.1.9
  •   PyCrypto
  •   msgpack-python
  •   YAML
  •   Jinja2
  这个列表,给了我们提供了一个好消息,一个坏消息。
  先说坏消息:因为我们的python版本不统一,有部分系统的python版本不在支持的范围内;如果强行安装,可能会导致稳定性的问题。
  再说好消息:既然有了安装需求,我们可以自定义安装,这样可以做到完全不影响系统环境。
  
  既然已经决定了我们要走"自定义安装"的道路,那么我们就"兵马未行,粮草先动"。(本文就当个教程写了,之前的探索过程就不写了)

  •   准备所需要的程序包。
      Jinja2-2.7.1.tar.gz
      M2Crypto-0.21.1.tar.gz
      MarkupSafe-0.18.tar.gz
      PyYAML-3.10.tar.gz
      Python-2.7.5.tgz
      msgpack-python-0.1.12.tar.gz
      pycrypto-2.6.1.tar.gz
      pyzmq-13.1.0.zip
      salt-0.17.1.tar.gz
      setuptools-1.1.6.tar.gz
      yaml-0.1.4.tar.gz
      zeromq-4.0.1.tar.gz
  •   安装前的准备。
      安装目录:/usr/local/SaltStack (我们的目标很明确)
  •   开始安装,下面是我写的一个很简单的脚本。
      master和minion的安装部署是一样的,区别只是使用的配置文件不同。
      M2Crypto的安装,请根据系统的具体环境参考安装说明



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88


#!/bin/bash                                                                                                                                      
#
# Author : john.lee.cn.do@gmail.com
# Date    : 2013.10.25
# Desc    : Install Salt
# Usage  : bash install.sh
#
   
export LANG=C
_IP=`ifconfig |grep 'inet addr'|grep -v '127.0.0.1'|sed 's/[ ]*/ /'|awk '{print $2}'|awk -F: '{print $NF}'|head -n 1`
_MASTER=172.17.37.207
   
_PATH=/usr/local/src/SaltStack
# Install Python
cd $_PATH
tar zxvf Python-2.7.5.tgz
cd Python-2.7.5
./configure --prefix=/usr/local/SaltStack/python-2.7.5
make && make install
   
   
export _PYTHON=/usr/local/SaltStack/python-2.7.5/bin/python
   
# Install setuptools
cd $_PATH
tar zxvf setuptools-1.1.6.tar.gz
cd setuptools-1.1.6
$_PYTHON setup.py install
   
# Install MarkupSafe
cd $_PATH
tar zxvf MarkupSafe-0.18.tar.gz
cd MarkupSafe-0.18
$_PYTHON setup.py install
   
# Install jinja2
cd $_PATH
tar zxvf Jinja2-2.7.1.tar.gz
cd Jinja2-2.7.1
$_PYTHON setup.py install
   
   
# Install  msgpack-python
cd $_PATH
tar zxvf msgpack-python-0.1.12.tar.gz
cd msgpack-python-0.1.12
$_PYTHON setup.py install
   
# Install  pycrypto
cd $_PATH
tar zxvf pycrypto-2.6.1.tar.gz
cd pycrypto-2.6.1
$_PYTHON setup.py install
   
# Install PyYAML
cd $_PATH
tar zxvf PyYAML-3.10.tar.gz
cd PyYAML-3.10
$_PYTHON setup.py install
   
# Install zeromq
cd $_PATH
tar zxvf zeromq-4.0.1.tar.gz
cd zeromq-4.0.1
./configure --prefix=/usr/local/SaltStack/zeromq-4.0.1
make && make install
   
   
# Install pyzmq
cd $_PATH
unzip pyzmq-13.1.0.zip
cd pyzmq-13.1.0
$_PYTHON setup.py install --zmq=/usr/local/SaltStack/zeromq-4.0.1
   
# Install  M2Crypto
# Need yum install swig
cd $_PATH
tar zxvf M2Crypto-0.21.1.tar.gz
cd M2Crypto-0.21.1
# Modify python path in fedora_setup.sh
bash fedora_setup.sh  install
   
   
# Install Salt
cd $_PATH
tar zxvf salt-0.17.1.tar.gz
cd salt-0.17.1
$_PYTHON setup.py install
  
4.  因为master和minion的区别,只是配置文件的不同,在请参考官方文档(salt的配置文件模板在salt-0.17.1/conf)
  5.  启动脚本。
  既然我们把路径都已经修改了,那么我们的启动脚本也要修改一下了。
  salt-minion(此例中,将配置文件也放在了/etc/salt中,如果进行了修改,可以修改脚本即可。)



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107


#!/bin/sh
#                                                                                                                                                
# Salt minion
###################################
   
# LSB header
   
### BEGIN INIT INFO
# Provides:           salt-minion
# Required-Start:     $local_fs $remote_fs $network $named $time
# Should-Start:         $time ypbind smtp
# Required-Stop:        $local_fs $remote_fs $network $named $time
# Should-Stop:          ypbind smtp
# Default-Start:      3 5
# Default-Stop:       0 1 2 6
# Short-Description:  Salt minion daemon
# Description:        This is the Salt minion daemon that can be controlled by the Salt master.
### END INIT INFO
   
   
# chkconfig header
   
# chkconfig: 345 97 04
# description:  This is the Salt minion daemon that can be controlled by the Salt master.
#
# processname: /usr/bin/salt-minion
   
   
SALTMINION=/usr/local/SaltStack/python-2.7.5/bin/salt-minion
PYTHON=/usr/local/SaltStack/python-2.7.5/bin
   
# Sanity checks.
[ -x $SALTMINION ] || exit 0
   
# Source function library.
. /etc/rc.d/init.d/functions
   
SERVICE=salt-minion
PROCESS=salt-minion
CONFIG_ARGS=" -c /etc/salt"
RETVAL=0
   
start() {
        if [ $(pidofproc $PROCESS) ]; then
              RETVAL=$?
              echo -n "already running"
        else
              echo -n $"Starting salt-minion daemon: "
              daemon --check $SERVICE $SALTMINION -d $CONFIG_ARGS
              RETVAL=$?
        fi
    echo
    return $RETVAL
}
   
stop() {
    echo -n $"Stopping salt-minion daemon: "
    killproc $PROCESS
    RETVAL=$?
    echo
}
   
restart() {
   stop
   start
}
   
# See how we were called.
case "$1" in
    start|stop|restart)
        $1
        ;;
    status)
        if [ -f $SUSE_RELEASE ]; then
            echo -n "Checking for service salt-minion "
            checkproc $SALTMINION
            rc_status -v
        elif [ -f $DEBIAN_VERSION ]; then
            if [ -f $LOCKFILE ]; then                                                                                                            
                RETVAL=0
                echo "salt-minion is running."
            else
                RETVAL=1
                echo "salt-minion is stopped."
            fi
        else
            status $PROCESS
            RETVAL=$?
        fi
        ;;
    condrestart)
        [ -f $LOCKFILE ] && restart || :
        ;;
    reload)
        echo "can't reload configuration, you have to restart it"
        if [ -f $SUSE_RELEASE ]; then
            rc_status -v
        else
            RETVAL=$?
        fi
        ;;
    *)
        echo $"Usage: $0 {start|stop|status|restart|condrestart|reload}"
        exit 1
        ;;
esac
exit $RETVAL
  
因为master就只有一台机器,所以就没有写脚本,手工操作也没太多的工作量,而且会更加的灵活。
  其它说明:

  •   我们是把python环境单独安装在了/usr/local/SaltStack/python-2.7.5中,所以每次手工执行命令时,需要使用绝对路径。
  •   目前上前做的环境中,只有一台master机器,存在单点危险,而且没有做负载均衡。目前还没有想到很好的解决方案。
      
  
  欢迎大家一起讨论。
  
  
  



[python] view plaincopyprint? DSC0000.png DSC0001.png

    • <pre code_snippet_id="98726" snippet_file_name="blog_20131205_4_6128993"></pre>  
    • <pre></pre>

  
  
  
  
  http://www.iyunv.com/thread-40232-1-1.html
  二、Master批量管理配置
  服务器端写sls模,他的默认路径在 /srv/salt/下,没有就新建目录,然后新建一个top.sls就跟puppet的入口文件 site.pp 类似。
  <ignore_js_op>
DSC0002.png
  ·        Base: 默认的的起点配置项:
  ·        '*':这个引号内的是匹配对象,针对所有受控主机
  ·        rd.sc:就是指资源文件/srv/salt/rd/sc.sls
  <ignore_js_op>
  
  看rd目录下的资源文件
  <ignore_js_op>
  
  利用py模式的sls配置文件(其实就是python脚本,只要返回yaml格式的字典文件就好了),我们可以将以上的操作简化成1步,思路如下:
1,/srv/pillar/top.sls中编写配置:
  base: '*': - custom
  2,使用py模式编写/srv/pillar/custom/init.sls,自动读取pillar配置,例如salt id是:10.1.1.1-centos.game.web,那么project为game,然后根据获取的pillar_root组合成路径/srv/pillar/custom/game/10.1.1.1-centos.game.web.yaml,利用yaml模块从文件中读取信息,返回字典
3,在/srv/salt/top.sls文件中匹配所有的minion
  ‘*’:  - centos.public_services
  4,/srv/salt/centos/public_services/init.sls文件使用py模式编写,配置会获取对应的minion的pillar信息,如果包含mysql配置信息且配置正确的话,则返回mysql实例的配置。
  那现在要怎么使用呢,很简单,例如你的id为10.1.1.1-centos.game.web,首先在/srv/pillar/custom/目录下建个game目录(从salt id获取的项目名),然后在game目录先新建文件10.1.1.1-centos.game.web.yaml,里面写上配置信息:
  mysql:  ports:    - 3306    - 3307    - 3308  version:  '5_5_25'
最后执行命令:salt 10.1.1.1-centos.game.web state.highstate -v -t 300
  静静的等待执行完成就好了!
  =======================
  http://blog.liuts.com/post/240/


Saltstack是一个具备puppet与func功能为一身的集中化管理平台,saltstack基于python实现,功能十分强大,各模块融合度及复用性极高,官方极力推荐作为云计算平台的基础架构。轻松维护成千上万台服务器不是问题,现分享作者基于saltstack实现一个集中化的配置管理平台,以Nginx配置例子展开,涉及salt的grains、grains_module、pillar、States、jinja(template)等,本文适合有salt基础的同学阅读。
一、设备环境说明
    有两组web业务服务器,组名分别为web1group与web2group,设备硬件配置、web根目录存在异常,见下图:
    DSC0003.png
二、master配置说明
    1、关键配置定义:

    2、定义的文件树结构(具体文件后续说明)
DSC0004.png
三、自定义grains_module
1)#vi /srv/salt/_grains/nginx_config.py

  • import os,sys,commands  

  • def NginxGrains():  
  •     '''
  •         return Nginx config grains value
  •     '''  
  •     grains = {}
  •     max_open_file=65536
  •     #Worker_info={'cpus2':'01 10','cpus4':'1000 0100 0010 0001','cpus8':'10000000 01000000 00100000 00010000 00001000 00000100 00000010 00000001'}  
  •     try:  
  •         getulimit=commands.getstatusoutput('source /etc/profile;ulimit -n')  
  •     except Exception,e:  
  •         pass  
  •     if getulimit[0]==0:  
  •         max_open_file=int(getulimit[1])  
  •     grains['max_open_file'] = max_open_file
  •     return grains  

2)同步grains模块
salt '*' saltutil.sync_all
3)刷新模块(让minion编译模块)
salt '*' sys.reload_modules
4)验证max_open_file key的value
[iyunv@SN2013-08-020 _grains]# salt '*' grains.item max_open_file              
SN2013-08-022:
  max_open_file: 1024
SN2013-08-021:
  max_open_file: 1024
SN2012-07-011:
  max_open_file: 1024
SN2012-07-012:
  max_open_file: 1024
SN2012-07-010:
  max_open_file: 1024
四、配置pillar
    本例使用分组规则定义pillar,即不同分组引用各自的sls属性
1)定义入口top.sls
#vi /srv/pillar/top.sls

2)定义私有配置,本例只配置web_root的数据,当然可以根据不同需求进行定制,格式为python的字典形式,即"key:value"。
#vi /srv/pillar/web1server.sls

#vi /srv/pillar/web2server.sls

3)验证配置结果:
#salt 'SN2013-08-021' pillar.data nginx
SN2013-08-021:
    ----------
    root:
        /data
#salt 'SN2012-07-010' pillar.data nginx
SN2012-07-010:
    ----------
    root:
        /www
五、配置States
1)定义入口top.sls
#vi /srv/salt/top.sls

2)定义nginx配置及重启服务SLS,其中salt://nginx/nginx.conf为配置模板文件位置。
#vi /srv/salt/nginx.sls

  • nginx:
  •   pkg:
  •    - installed
  •   file.managed:  
  •    - source: salt://nginx/nginx.conf
  •    - name: /etc/nginx/nginx.conf
  •    - user: root  
  •    - group: root
  •    - mode: 644  
  •    - template: jinja

  •   service.running:
  •    - enable: True  
  •    - reload: True  
  •    - watch:
  •      - file: /etc/nginx/nginx.conf  
  •      - pkg: nginx

3)Nginx配置文件(引用jinja模板)
功能点:
1、worker_processes参数采用grains['num_cpus'] 上报值(与设备CPU核数一致);
2、worker_cpu_affinity分配多核CPU根据当前设备核数进行匹配,分别为2\4\8\其它核;
3、worker_rlimit_nofile参数与grains['max_open_file'] 获取的系统ulimit -n一致;
4、worker_connections 参数理论上为grains['max_open_file'];
5、 root参数为定制的pillar['nginx']['root']值。
#vi /srv/salt/nginx/nginx.conf

  • # For more information on configuration, see:  
  • user              nginx;
  • worker_processes  {{ grains['num_cpus'] }};  
  • {% if grains['num_cpus'] == 2 %}  
  • worker_cpu_affinity 01 10;
  • {% elif grains['num_cpus'] == 4 %}  
  • worker_cpu_affinity 1000 0100 0010 0001;
  • {% elif grains['num_cpus'] >= 8 %}  
  • worker_cpu_affinity 00000001 00000010 00000100 00001000 00010000 00100000 01000000 10000000;
  • {% else %}  
  • worker_cpu_affinity 1000 0100 0010 0001;
  • {% endif %}
  • worker_rlimit_nofile {{ grains['max_open_file'] }};  

  • error_log  /var/log/nginx/error.log;
  • #error_log  /var/log/nginx/error.log  notice;  
  • #error_log  /var/log/nginx/error.log  info;  

  • pid        /var/run/nginx.pid;

  • events {
  •     worker_connections  {{ grains['max_open_file'] }};  
  • }


  • http {
  •     include       /etc/nginx/mime.types;
  •     default_type  application/octet-stream;

  •     log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '  
  •                       '$status $body_bytes_sent "$http_referer" '  
  •                       '"$http_user_agent" "$http_x_forwarded_for"';  

  •     access_log  /var/log/nginx/access.log  main;

  •     sendfile        on;
  •     #tcp_nopush     on;

  •     #keepalive_timeout  0;
  •     keepalive_timeout  65;

  •     #gzip  on;

  •     # Load config files from the /etc/nginx/conf.d directory
  •     # The default server is in conf.d/default.conf  
  •     #include /etc/nginx/conf.d/*.conf;
  •     server {
  •         listen       80 default_server;
  •         server_name  _;

  •         #charset koi8-r;

  •         #access_log  logs/host.access.log  main;

  •         location / {
  •             root   {{ pillar['nginx']['root'] }};  
  •             index  index.html index.htm;
  •         }

  •         error_page  404              /404.html;
  •         location = /404.html {
  •             root   /usr/share/nginx/html;
  •         }

  •         # redirect server error pages to the static page /50x.html  
  •         #
  •         error_page   500 502 503 504  /50x.html;
  •         location = /50x.html {
  •             root   /usr/share/nginx/html;
  •         }

  •     }

  • }

4)同步配置
#salt '*' state.highstate
DSC0005.png
(由于非第一次运行,看不到配置文件比对的信息)
5)验证结果:
1、登录root@SN2013-08-021
#vi /etc/nginx/nginx.conf
DSC0006.png

DSC0007.png
2、登录root@SN2012-07-010
#vi /etc/nginx/nginx.conf
DSC0008.gif

DSC0009.gif

Tags: saltstack , salt , 运维 , 自动化





hanxiao DSC00010.jpg DSC00011.jpg
2015/03/17 17:31
我知道是什么问题了,是因为minion主机没有设置id号,


hanxiao
2015/03/17 16:16
其实我知道上午的主要问题是什么了,主要是 nodegroup match不成功,但我不知道为什么不成功,master配置文件里已经添加了node group信息


hanxiao
2015/03/17 11:07
感觉 YAML格式要求很严格,行首空格、制表符多一个少一个都不行。我在在配置 pillar 时遇到了问题1、设置了nodegroups :web1group、web2groupsalt -N web1group test.pingvm0:    Truevm1:    True2、然后按书上的写了 top.sls、web1server.sls、web2server.sls刷新 salt '*' saltutil.refresh_pillar


hanxiao
2015/03/17 10:57
感觉YAML的格式要求很严格,行首多一个空格或制表符都不行我在配置pillar时,就有困惑,我使用salt -N web1group test.ping   #正常salt -N web1group test.ping vm1:    Truevm0:    True写了  /srv/pillar/top.sls、web1server.sls、web2server.sls,然后刷新 salt '*' saltutil.refresh_pillar但在master上执行 salt 'vm0' pillar.data nginxvm0:    ----------后来我直接复制了你的sls文件,也不行,这是怎么回事呢,前面的 max_open_file倒测试正常。我是个新手,向你学习


甄码农
2014/11/06 10:03
请教个问题,在master上_grains目录下的python文件同步到minion服务器上的说呢么位置了?grain调试有什么好的方法? 谢谢


网游加速器
2014/08/17 16:55
感觉管理好麻烦的啊


变压器
2014/07/27 20:50
路过,偷偷带走,谢谢分享


园林假山
2014/07/24 08:44
不错,学习学习,欢迎回访


胶水
2014/07/21 16:10
我是来打酱油的,欢迎回访我的博客。


ran
2014/02/21 14:31
saltstack针对编译安装的服务怎么维护呢?怎么进行服务的 - enable: True    - reload: True这两个功能?


张伟
2013/10/23 15:52
哈哈,我被主机名勾引出来了

刘天斯 回复于 2013/10/28 16:18
汗颜~


一路狂飙
2013/10/14 09:18
生成了如何分发呢?

刘天斯 回复于 2013/10/14 18:09
运行#salt '*' state.highstate 就是包含校验、分发,具体项看SLS配置。


藤家具
2013/09/24 17:25
确实很有压力的呀


北南
2013/09/05 16:46
谢谢分享!回去捣鼓下。


chenqing
2013/09/04 12:59
不错,楼主依然强悍。。。  
  =========================================================
  http://www.xiaomastack.com/2014/09/20/yunweipingtai2/
第一个运维平台_第二版

By 小马 · 九月 20, 2014 · 运维开发 · 11 Comments
  其实这个版本与第一个 http://www.xiaomastack.com/2014/07/05/yunweipingtai/ 比已经是脱胎换骨了,该版本后端采用Django,前端用BootStrap。底层还是用的saltsatck、saltAPI、zabbix、zabbixAPI、git等,毕竟整体架构是不能随随便便就改变的。我来简单的介绍下原理和功能。
  1、配置管理。
  配置管理主要用saltstack来做,与saltstack的通信用saltAPI来完成。”执行salt命令“ 的功能就是在WEB界面执行saltstack命令(安全简单选择预置的命令就可以了,关键是命令可以预置这样在应用层就防止了误操作,虽然我们在salt的代码层也做了类似的处理)。”配置下发“ 这个基于salt命令,依次执行salt命令就好了。
DSC00012.jpg
  2、资产管理。
  资产管理主要分为硬件资产和软件资产,硬件资产由saltsatck的grains来采集,软件资产的收集由saltstack下发执行采集脚本来完成。所有的这些操作都自动完成(采集、入库、展示)。打码的地方太多我用PS来打吧!
DSC00013.jpg
DSC00014.jpg
  3、版本发布。
  版本发布实现功能
  a、能从操作者本地上传zip更新包,更新到正式环境或测试环境。如果更新到测试环境经过测试后没有问题再推送到正式环境。也可以直接更新到正式环境。
  b、开发人员提供包名后,根据包名从ftp服务器下载zip更新包,更新到正式环境或测试环境。如果更新到测试环境后没有问题再推送到正式环境。也可以直接更新到正式环境。
  c、能够回滚到上一个版本(测试或正式环境)。
DSC00015.jpg
  4、数据展示。
  主要做的是Zabbix监控数据的展示,分类、分应用、分主机。原始数据由Zabbix采集,然后另外的机器用ZabbixAPI向Zabbix取监控数据存放到rrd文件,最后由RRDTool绘图展示监控数据。
  硬件监控数据展示分类沿用Zabbix自身的分类,软件应用监控数据的分类采用再绘图时的自定义的分类。
  点击一台主机,监控数据默认展示的是1天的监控数据。
DSC00016.jpg DSC00017.jpg
  点击图可以进入该监项在过去1天、1周、1月、1年的监控图,默认30秒刷新一次(也可以手动刷新)
DSC00018.jpg DSC00019.jpg
  点击1天的监控图,可以进入该监控项2小时的监控图,默认30秒刷新,也可以手动刷新。
DSC00020.jpg
  转载请注明出处:http://www.xiaomastack.com/2014/09/20/yunweipingtai2/ 谢谢!
  
  

11 Comments
Add your comment




  • Turandot 2015/03/18 at 14:54
      请问这个能分享和共同学习一下?

    登录以回复



  • Rainbow 2015/03/07 at 11:58
      最近也在边学边写运维平台,刚好也是用django;方便给下代码吗?感谢!

    登录以回复




    • 小马 2015/03/09 at 13:09
        我一哥们儿开源了一个,也是用的Django,你可以参考下:
      https://github.com/binbin91/oms
      登录以回复




  • Dengwenjia 2015/03/03 at 17:26
      你好,我现在已经做好一部分自动化运维平台django+bootstrap实现,完成资产管理,部分配置管理,堡垒机全部功能,现在想接入zabbix告警报表,看你的做的不错,能共享下吗,可以QQ私聊,你需要我的也可以共享。代码写的烂 现在主要是思路 希望慢慢优化,完善 。谢谢 QQ:1873447820

    登录以回复




    • 小马 2015/03/03 at 17:31
        已加,不过我的zabbix告警报表没有接到平台上。

      登录以回复




  • Ops 2015/03/03 at 13:43
      方便发一下代码给我参考一下么,我也一直想开发这样一个平台

    登录以回复




    • 小马 2015/03/03 at 17:30
        已发邮件

      登录以回复




  • Cosmo 2015/02/22 at 03:16
      小马哥,搞的不错开源么?

    登录以回复




    • Cosmo 2015/02/27 at 18:47
        小马哥?

      登录以回复




      • 小马 2015/03/02 at 10:46
          今天刚上班,呵呵

        登录以回复




    • 小马 2015/03/02 at 10:45
        每个公司的运维环境和需求不一样,还有就是代码不够好就不开源了,望见谅。
        

  
  
  
  
  
  
  ==========
  
  
  
  http://www.xiaomastack.com/2014/11/18/salt-api/
配置管理(3) salt-api安装、配置、使用

By 小马 · 十一月 18, 2014 · SaltStack, 配置管理 · 8 Comments
  salt-api也用了一段时间了,现在从安装、配置、使用三个方面梳理下知识。
1、安装
采用pip安装方便快捷,当然编译安装也很nice。
安装pip采用的编译安装的方式,版本当前最新1.5.6,下载、解压、编译、安装是不变的法则。



1
2
3
4
5
6
7


[iyunv@saltstack ~]#wget https://pypi.python.org/packages/source/p/pip/pip-1.5.6.tar.gz#md5=01026f87978932060cc86c1dc527903e --no-check-certificate
[iyunv@saltstack ~]#tar xvfz pip-1.5.6.tar.gz
[iyunv@saltstack ~]#cd pip-1.5.6
[iyunv@saltstack pip-1.5.6]#python setup.py build
[iyunv@saltstack pip-1.5.6]#python setup.py install
#安装完成后可以用pip freeze查看已安装的packages
[iyunv@saltstack pip-1.5.6]#pip freeze
  安装CherryPy,版本3.2.3



1


[iyunv@saltstack ~]#pip install cherrypy==3.2.3
  安装salt-api,版本0.8.3



1


[iyunv@saltstack ~]#pip install salt-api==0.8.3
  2、配置



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31


[iyunv@saltstack ~]# cd /etc/pki/tls/certs
[iyunv@saltstack certs]# make testcert
umask 77 ; \
    /usr/bin/openssl genrsa -aes128 2048 > /etc/pki/tls/private/localhost.key
Generating RSA private key, 2048 bit long modulus
...+++
..................................................................+++
e is 65537 (0x10001)
Enter pass phrase:    #键入加密短语,4到8191个字符
Verifying - Enter pass phrase:    #确认加密短语
umask 77 ; \
    /usr/bin/openssl req -utf8 -new -key /etc/pki/tls/private/localhost.key -x509 -days 365 -out /etc/pki/tls/certs/localhost.crt -set_serial 0
Enter pass phrase for /etc/pki/tls/private/localhost.key:    #再次输入相同的加密短语
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [XX]:CN    #都可以选填
State or Province Name (full name) []:Shanghai
Locality Name (eg, city) [Default City]:Shanghai
Organization Name (eg, company) [Default Company Ltd]:
Organizational Unit Name (eg, section) []:
Common Name (eg, your name or your server's hostname) []:
Email Address []:1989051805@qq.com
[iyunv@saltstack certs]# cd ../private/
[iyunv@saltstack private]# openssl rsa -in localhost.key -out localhost_nopass.key
Enter pass phrase for localhost.key:    #输入之前的加密短语
writing RSA key
  如果遇到这样的错误



1
2
3
4
5
6


[iyunv@saltstack certs]# make testcert
umask 77 ; \
    /usr/bin/openssl req -utf8 -new -key /etc/pki/tls/private/localhost.key -x509 -days 365 -out /etc/pki/tls/certs/localhost.crt -set_serial 0
unable to load Private Key
139696733648712:error:0906D06C:PEM routines:PEM_read_bio:no start line:pem_lib.c:703:Expecting: ANY PRIVATE KEY
make: *** [/etc/pki/tls/certs/localhost.crt]
  删掉文件/etc/pki/tls/private/localhost.key文件,然后再make testcert。
为salt-api创建用户并设定密码,用户名没有特别要求,我就用saltapi好了。



1
2
3


[iyunv@saltstack ~]#useradd -M -s /sbin/nologin saltapi
#由于是测试,故采用了弱密码"password",正式环境必须采用强密码,多用特殊字符
[iyunv@saltstack ~]# passwd saltapi
  新增加配置文件/etc/salt/master.d/api.conf和/etc/salt/master.d/eauth.conf



1
2
3
4
5
6
7
8
9
10
11
12
13


#该配置文件给予saltapi用户所有模块使用权限,出于安全考虑一般只给予特定模块使用权限
[iyunv@saltstack master.d]# cat eauth.conf
external_auth:
  pam:
    saltapi:
      - .*
[iyunv@saltstack master.d]#
[iyunv@saltstack master.d]# cat api.conf
rest_cherrypy:
  port: 8888
  ssl_crt: /etc/pki/tls/certs/localhost.crt
  ssl_key: /etc/pki/tls/private/localhost_nopass.key
[iyunv@saltstack master.d]#
  寻找salt-api的启动脚本,我比较懒就不自己写了,在页面https://github.com/saltstack/salt-api/releases下载salt-api的tar.gz包,启动脚本在解压包的这个位置./pkg/rpm/salt-api。
不过提供的脚本貌似有个小的bug,就是使用restart参数时,salt-api能够stop但是不能start,如下:



1
2
3


[iyunv@saltstack ~]# /etc/init.d/salt-api restart
Stopping salt-api daemon:                                  [确定]
Starting salt-api daemon:                                  [失败]
  我估计可能是有些相关资源在下次启动前没有来得及释放造成的,解决方法很简单在脚本的restart函数的stop和start之间加上sleep语句。



1
2
3
4
5


restart() {
   stop
   sleep 1
   start
}
  然后重启就没有问题了



1
2
3
4


[iyunv@saltstack ~]# /etc/init.d/salt-api restart
Stopping salt-api daemon:                                  [确定]
Starting salt-api daemon:                                  [确定]
[iyunv@saltstack ~]#
  最后重启salt-master在启动salt-api并将salt-api加入开机启动,安装就完成了。



1
2
3
4
5
6
7
8


[iyunv@saltstack ~]# chkconfig salt-api on
[iyunv@saltstack ~]# /etc/init.d/salt-master restart
Stopping salt-master daemon:                               [确定]
Starting salt-master daemon:                               [确定]
[iyunv@saltstack ~]# /etc/init.d/salt-api restart
Stopping salt-api daemon:                                  [确定]
Starting salt-api daemon:                                  [确定]
[iyunv@saltstack ~]#
  3、使用(基本的使用方法)
登录获取token



1
2
3
4
5
6
7
8
9


[iyunv@syndic02 ~]# curl -k https://192.168.186.134:8888/login -H "Accept: application/x-yaml" -d username='saltapi' -d password='password' -d eauth='pam'
return:
- eauth: pam
  expire: 1416324685.2597771
  perms:
  - .*
  start: 1416281485.2597761
  token: 6171a922a9718ccb40e94ee7c8eb8768f4eea4e5
  user: saltapi
  获取token后就可以使用token通信



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16


#相当于在salt-master本地执行salt \* test.ping
[iyunv@syndic02 ~]# curl -k https://192.168.186.134:8888/ -H "Accept: application/x-yaml" -H "X-Auth-Token: 6171a922a9718ccb40e94ee7c8eb8768f4eea4e5" -d client='local' -d tgt='*' -d fun='test.ping'
return:
- syndic01: true
  syndic01-minion02: true
  syndic02: true
  syndic02-minion02: true

#相当于在salt-master本地执行salt \* test.echo 'hello world'
[iyunv@syndic02 ~]# curl -k https://192.168.186.134:8888/ -H "Accept: application/x-yaml" -H "X-Auth-Token: 6171a922a9718ccb40e94ee7c8eb8768f4eea4e5" -d client='local' -d tgt='*' -d fun='test.echo' -d arg='hello world'
return:
- syndic01: hello world
  syndic01-minion02: hello world
  syndic02: hello world
  syndic02-minion02: hello world
[iyunv@syndic02 ~]#
  运维开发这样使用还是不方便的,下面写的是一个salt-api的类(其它的文章也提到过)可以参考。



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53


#!/usr/bin/env python
#coding=utf-8

import urllib2, urllib, json, re

class saltAPI:
    def __init__(self):
        self.__url = 'https://192.168.186.134:8888'       #salt-api监控的地址和端口如:'https://192.168.186.134:8888'
        self.__user =  'saltapi'             #salt-api用户名
        self.__password = 'password'          #salt-api用户密码
        self.__token_id = self.salt_login()

    def salt_login(self):
        params = {'eauth': 'pam', 'username': self.__user, 'password': self.__password}
        encode = urllib.urlencode(params)
        obj = urllib.unquote(encode)
        headers = {'X-Auth-Token':''}
        url = self.__url + '/login'
        req = urllib2.Request(url, obj, headers)
        opener = urllib2.urlopen(req)
        content = json.loads(opener.read())
        try:
            token = content['return'][0]['token']
            return token
        except KeyError:
            raise KeyError

    def postRequest(self, obj, prefix='/'):
        url = self.__url + prefix
        headers = {'X-Auth-Token'   : self.__token_id}
        req = urllib2.Request(url, obj, headers)
        opener = urllib2.urlopen(req)
        content = json.loads(opener.read())
        return content['return']

    def saltCmd(self, params):
        obj = urllib.urlencode(params)
        obj, number = re.subn("arg\d", 'arg', obj)
        res = self.postRequest(obj)
        return res

def main():
    #以下是用来测试saltAPI类的部分
    sapi = saltAPI()
    params = {'client':'local', 'fun':'test.ping', 'tgt':'*'}
    #params = {'client':'local', 'fun':'test.ping', 'tgt':'某台服务器的key'}
    #params = {'client':'local', 'fun':'test.echo', 'tgt':'某台服务器的key', 'arg1':'hello'}
    #params = {'client':'local', 'fun':'test.ping', 'tgt':'某组服务器的组名', 'expr_form':'nodegroup'}
    test = sapi.saltCmd(params)
    print test

if __name__ == '__main__':
    main()
  测试效果



1
2
3


[iyunv@syndic02 ~]# python salt-api.py
[{u'syndic02': True, u'syndic02-minion02': True, u'syndic01': True, u'syndic01-minion02': True}]
[iyunv@syndic02 ~]#
  以上只是一些基本的实例,salt-api还可以实现更多功能。
文章出处:http://www.xiaomastack.com/2014/11/18/salt-api/



http://www.xiaomastack.com/2014/10/31/saltstack-grains/
配置管理篇(2)_SaltStack grains

By 小马 · 十月 31, 2014 · SaltStack, 配置管理 · Leave a comment
  grains主要负责采集并返回客户端minion的一些基本信息, saltstack自带grains模块可以采集机器的很多基本信息,对于比较特别的信息grains可以在客户端或服务器端自定义item后采集,不管是那种方式自定义grains的item,最终grains的item值都是由客户端minion采集完成后上报给服务端master的,采集动作只在启动客户端或有新的grains添加时触发,grains采集上报的数据可以作为资产管理的元数据。一个客户端在启动时就将自定义或基本的item信息值读取到内存了,这些值是个常量在下次重启客户端之前不会改变。
  先看看怎样使用,然后瞧瞧怎样自定义(4种自定义方法)
查看所有的grains项 grains.ls



1
2
3
4
5
6
7
8
9


[iyunv@saltstack ~]# salt minion01 grains.ls
minion01:
    - biosreleasedate
    - biosversion
    - cpu_flags
    - cpu_model
    - cpuarch
    - defaultencoding
... ... ...
  查看所有的grains项的详细信息 grains.items



1
2
3
4
5


[iyunv@saltstack ~]# salt minion01 grains.items
minion01:
  biosreleasedate: 07/02/2012
  biosversion: 6.00
... ... ...
  查看grains指定的item信息



1
2
3
4
5
6
7
8
9
10
11


[iyunv@saltstack ~]# salt minion01 grains.item shell
minion01:
  shell: /bin/sh
[iyunv@saltstack ~]# salt minion01 grains.item os
minion01:
  os: CentOS
[iyunv@saltstack ~]# salt minion01 grains.item ipv4
minion01:
  ipv4:
      127.0.0.1
      192.168.186.135
  grains添加自定义items
  1、在master端添加
在配置文件file_roots指定的目录(默认是/srv/salt)下创建_grains目录,编写可以返回一个字典的py文件(需要懂点python)。



1
2
3
4
5
6
7
8


[iyunv@saltstack ~]# grep -Ev "^$|^#" /etc/salt/master
file_roots:
  base:
    - /srv/salt
pillar_roots:
  base:
    - /srv/pillar
[iyunv@saltstack ~]#
  例如grains添加自定义item(disk_size)返回磁盘的大小,注意python脚本返回值是一个字典。



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18


[iyunv@saltstack _grains]# cat disk.py
#coding=utf-8
import os

def disk_size():
    ''' get disk size '''

    disk = os.statvfs("/")
    capacity = disk.f_bsize * disk.f_blocks
    ret = int(float(capacity)/1000/1000/1000)
    if ret > 1000:
        obj = ret/1000.0
        disk_size = ("%.1f" % obj) + 'T'
    else:
        ret = str(ret)
        disk_size = ret + 'G'

    return {'disk_size': disk_size}
  用saltutil.sync_grains或者saltutil.sync_all将自定义的grains item 同步到minion端,如果只同步grains建议使用saltutil.sync_grains。



1
2
3
4
5
6
7
8
9
10
11
12
13


[iyunv@saltstack _grains]# salt minion01 saltutil.sync_grains
minion01:
    - grains.__init__
    - grains.disk
[iyunv@saltstack _grains]# salt minion01 saltutil.sync_all
minion01:
    ----------
    grains:
    modules:
    outputters:
    renderers:
    returners:
    states:
  从结果可以看到sync_grains和sync_all不同之处了吧。
  同步完成后在minion端的以下目录中可以找到master下发的grains文件



1
2


[iyunv@minion01 minion.d]# ls /var/cache/salt/minion/extmods/grains/
disk.py      disk.pyc     __init__.py
  看看是否同步成功



1
2
3
4


[iyunv@saltstack _grains]# salt minion01 grains.item disk_size
minion01:
  disk_size: 19G
[iyunv@saltstack _grains]#
  2、在minion端添加
可以直接在配置文件/etc/salt/minion中添加,但一般不这么干。一般会将default_include: minion.d/*.conf配置项打开,然后将自定义grains的以.conf结尾的配置文件放到minion.d这个目录中。



1
2
3
4


[iyunv@minion01 ~]# grep -Ev "^$|#" /etc/salt/minion
default_include: minion.d/*.conf
master: 192.168.186.134
id: minion01
  在minion.d目录中添加并编辑grains.conf文件(文件名随意)



1
2
3
4
5


[iyunv@minion01 minion.d]# cat grains.conf
grains:
  IDC: xxx-xxx-xxx
  dFlag: 2014/10/31
[iyunv@minion01 minion.d]#
  重启salt-minion后生效,然后在master端查看自定义的grains



1
2
3
4
5
6
7
8
9
10
11
12
13


[iyunv@saltstack _grains]# salt minion01 grains.get IDC
minion01:
    xxx-xxx-xxx
[iyunv@saltstack _grains]# salt minion01 grains.get dFlag
minion01:
    2014/10/31
[iyunv@saltstack _grains]# salt minion01 grains.item dFlag
minion01:
  dFlag: 2014/10/31
[iyunv@saltstack _grains]# salt minion01 grains.item IDC
minion01:
  IDC: xxx-xxx-xxx
[iyunv@saltstack _grains]#
  3、在master端直接用grains.setval为指定minion的grains设定一个item
设定welcome的值为’hello world’



1
2
3


[iyunv@saltstack _grains]# salt minion01 grains.setval welcome 'hello world'
minion01:
  welcome: hello world
  查看定义的item的值



1
2
3
4
5
6
7


[iyunv@saltstack _grains]# salt minion01 grains.item welcome
minion01:
  welcome: hello world
[iyunv@saltstack _grains]# salt minion01 grains.get welcome
minion01:
    hello world
[iyunv@saltstack _grains]#
  这次定义的grains保存在minion端的配置文件/etc/salt/grains中



1
2
3
4


[iyunv@minion01 salt]# pwd
/etc/salt
[iyunv@minion01 salt]# cat grains
welcome: hello world
  4、在master端通过states的grains方法也可以自定义grains
为了方便管理,在文件夹/salt/srv下再创建文件夹gitems,然后再该文件夹下编辑新的sls文件gtest.sls



1
2
3
4
5
6
7
8
9


[iyunv@saltstack gitems]# pwd
/srv/salt/gitems
[iyunv@saltstack gitems]# ls
gtest.sls
[iyunv@saltstack gitems]# cat gtest.sls
country:
  grains.present:
    - value: china
[iyunv@saltstack gitems]#
  下发到minion端,并查看新添加的item



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21


[iyunv@saltstack gitems]# salt minion01 state.sls gitems.gtest
minion01:
----------
          ID: country
    Function: grains.present
      Result: True
     Comment: Set grain country to china
     Changes:
              ----------
              country:
                  china

Summary
------------
Succeeded: 1
Failed:    0
------------
Total:     1
[iyunv@saltstack gitems]# salt minion01 grains.get country
minion01:
    china
  该方法定义的grains同样保存在minion端的配置文件/etc/salt/grains中



1
2
3
4


[iyunv@minion01 salt]# cat grains
country: china
welcome: hello world
[iyunv@minion01 salt]#
  转载请注明出处:http://www.xiaomastack.com/2014/10/31/saltstack-grains/ 谢谢!


http://www.xiaomastack.com/2014/10/16/saltstack01/
配置管理篇(1)_SaltStack常用可执行模块(execution modules)及解决rm -f带来的困惑

By 小马 · 十月 16, 2014 · SaltStack, 配置管理 · Leave a comment
  所有的可执行模块(execution modules)可以查看官方文档,记录下我常用到的模块test、status、cmdmod、useradd、system、systemd、file和解决rm -f带来困惑的方法。使用方法除了查看官方文档和手册外,查看源代码(源代码中也详细描述了使用方法和示例)也是一个好的方法。
1、test
test模块提供对minion端有限项的任意测试,常见的有ping、echo、version等,源码在minion端/usr/lib/python2.6/site-packages/salt/modules/test.py,详细的使用方法查源码最直接了。



1
2
3
4
5
6
7
8
9
10


[iyunv@saltstack ~]# salt minion01 test.ping
minion01:
    True
[iyunv@saltstack ~]# salt minion01 test.echo 'hello world'
minion01:
    hello world
[iyunv@saltstack ~]# salt minion01 test.version
minion01:
    2014.1.10
[iyunv@saltstack ~]#
  2、status
status可以查看minion的基本状态如CPU、内存、硬盘、网络等,常见的有all_status、uptime、w、netstats等,源码在minion端/usr/lib/python2.6/site-packages/salt/modules/status.py。
对于all_status方法查看源码可以看到这个版本支持的可查询状态有cpuinfo、cpustatus、… …等



1
2
3
4
5
6
7
8
9
10
11
12
13


def all_status():
    ... ... ...
    return {'cpuinfo': cpuinfo(),
            'cpustats': cpustats(),
            'diskstats': diskstats(),
            'diskusage': diskusage(),
            'loadavg': loadavg(),
            'meminfo': meminfo(),
            'netdev': netdev(),
            'netstats': netstats(),
            'uptime': uptime(),
            'vmstats': vmstats(),
            'w': w()}
  使用方法很简单,例如:



1
2
3
4


[iyunv@saltstack ~]# salt minion01 status.uptime
minion01:
     14:27:49 up  4:43,  1 user,  load average: 0.00, 0.00, 0.00
[iyunv@saltstack ~]#
  3、cmdmod与rm -f带来的困惑
这个模块中的run可以执行在bash里执行的所有命令,很强大但是也得注意在run中执行类似rm这样的命令是很危险的。源码位置在minion端的/usr/lib/python2.6/site-packages/salt/modules/cmdmod.py。
cmd.run执行命令就像在minion端本地执行命令一样亲切。



1
2
3
4
5
6
7


[iyunv@saltstack ~]# salt minion01 cmd.run 'df -hT'
minion01:
    Filesystem    Type    Size  Used Avail Use% Mounted on
    /dev/sda3     ext4     19G  2.5G   15G  15% /
    tmpfs        tmpfs    242M     0  242M   0% /dev/shm
    /dev/sda1     ext4    504M   39M  440M   9% /boot
[iyunv@saltstack ~]#
  亲切的同时也会带来困惑,如果误操作是这样的,后果很可怕。



1


[iyunv@saltstack ~]# salt \* cmd.run "rm -rf /"
  可以修改源代码禁止执行rm这种较危险的命令,打开minion端的文件/usr/lib/python2.6/site-packages/salt/modules/cmdmod.py找到run()函数,在其调用_run()函数的时候判断参数cmd中是否包含rm命令,如果包含了就返回并提示”rm命令很危险,任务执行失败”,这样一来master上cmd.run就不能执行rm命令了。



1
2
3
4
5
6
7
8
9
10


'''
... ... ...
     salt '*' cmd.run "grep f" stdin='one\\ntwo\\nthree\\nfour\\nfive\\n
'''
#在以下位置添加代码
if r'rm ' in cmd:
    return "'rm' is dangerous!!!  MISSION FAILED!!!"
#在以上位置添加代码
ret = _run(cmd,
... ... ...
  修改文件后重启minion后生效,测试下效果



1
2
3
4


[iyunv@saltstack ~]# salt minion01 cmd.run "rm -rf /"
minion01:
    'rm' is dangerous!!!  MISSION FAILED!!!
[iyunv@saltstack ~]#
  可以看出修改已经生效,再也不用担心cmd.run误操作了。不过有个问题就是,在cmdmod模块中不仅cmd.run可以执行rm命令还有cmd.run_all、cmd.run_stdout等都可以执行rm命令,为了更彻底的封掉rm这个命名,仔细看了下代码发现它们最终都是调用的_run()来完成任务的,可以修改_run()这个函数(在/usr/lib/python2.6/site-packages/salt/modules/cmdmod.py文件第213行)来彻底的封掉rm这个命令。



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15


'''
    ... ... ...
    Do the DRY thing and only call subprocess.Popen() once
    '''
    #在以下位置添加代码
    if r'rm ' in cmd:
        ret = {}
        ret['stdout'] = "'rm' is dangerous!!!  MISSION FAILED!!!"
        ret['stderr'] = ''
        ret['pid'] = ''
        ret['retcode'] = 0
        return ret
    #在以上位置添加代码
    if salt.utils.is_true(quiet):
    ... ... ...
  如果是修改_run()函数后就不用修改run()等其它函数了,修改文件后重启minion后生效,测试下效果



1
2
3
4
5
6
7
8
9
10
11
12
13
14


[iyunv@saltstack ~]# salt minion01 cmd.run "rm -rf /"
minion01:
    'rm' is dangerous!!!  MISSION FAILED!!!
[iyunv@saltstack ~]# salt minion01 cmd.run_all "rm -f test"
minion01:
    ----------
    pid:

    retcode:
        0
    stderr:

    stdout:
        'rm' is dangerous!!!  MISSION FAILED!!!
  将修改过的salt-minion打成rpm包后放到本地的yum源,然后重新安装所有的minion端就可以解决rm带来的困惑了。
  
  4、useradd
这个模块主是用来用户管理的,源文件位置在minion端(下同)/usr/lib/python2.6/site-packages/salt/modules/useradd.py,记录几个常用的。
user.add添加新用户



1
2
3


[iyunv@saltstack ~]# salt minion01 user.add testuser
minion01:
    True
  user.list_users列出所有的用户,可以看到刚才添加的用户



1
2
3


[iyunv@saltstack ~]# salt minion01 user.list_users | grep testuser
    - testuser
[iyunv@saltstack ~]#
  user.info查看用户信息



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24


[iyunv@saltstack ~]# salt minion01 user.info testuser
minion01:
    ----------
    fullname:

    gid:
        500
    groups:
        - testuser
    home:
        /home/testuser
    homephone:

    name:
        testuser
    passwd:
        x
    roomnumber:

    shell:
        /bin/bash
    uid:
        500
    workphone:
  user模块还有很多可用的方法,可以根据名称就可以知道其功能了比如



1
2
3
4
5
6
7
8
9
10


user.getent
user.delete name remove=True force=True
user.chworkphone foo "7735550123"
user.chuid foo 4376
user.chshell foo /bin/zsh
user.chroomnumber foo 123
user.chfullname foo "Foo Bar"
user.chgid foo 4376
user.chgroups foo wheel,root True
user.chhome foo /home/users/foo True
  5、system
系统管理模块,能看懂的就不记录了。源码位置/usr/lib/python2.6/site-packages/salt/modules/system.py



1
2
3
4
5


system.halt        #停止正在运行的系统
system.init 3      #切换到字符界面,5是图形界面
system.poweroff
system.reboot
system.shutdown
  6、systemd
系统服务管理模块,源码位置/usr/lib/python2.6/site-packages/salt/modules/systemd.py



1
2
3
4
5
6
7
8
9
10
11
12
13
14


service.available sshd            #查看服务是否可用
service.disable <service name>    #设置开机启动的服务
service.enable <service name>
service.disabled <service name>   #查看服务是不是开机启动
service.enabled <service name>
service.get_disabled              #返回所有关闭的服务
service.get_enabled               #返回所有开启的服务
service.get_all                   #返回所有服务
service.reload <service name>     #重新载入指定的服务
service.restart <service name>    #重启服务
service.start <service name>
service.stop <service name>
service.status <service name>
service.force_reload <service name>  #强制载入指定的服务
  7、file
文件管理模块,这个模块的方法太多,非常强大,选些常用的记一下。源文件/usr/lib/python2.6/site-packages/salt/modules/file.py中有所有方法的功能和使用说明。



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15


file.copy /path/to/src /path/to/dst                    #将master文件拷贝到minion上,salt还有个专门的拷文件的命令salt-cp
file.append /etc/motd "append test."                   #为minion的文件/etc/moth追加内容
file.check_hash /etc/fstab md5=<md5sum>                #检测并对比文件的md5值,并返回布尔值
file.get_hash /etc/passwd    获取文件的md5值
file.check_perms /etc/sudoers '{}' root root 400       #检测并更改文件的用户、组、权限
file.chgrp /etc/passwd root
file.chown /etc/passwd root root
file.directory_exists /tmp                             #检测文件夹是否存在
file.file_exists /etc/passwd
file.get_group /etc/passwd
file.get_user /etc/passwd
file.get_mode /etc/passwd                              #检测文件权限
file.set_mode /etc/passwd 0644                         #设置权限
file.get_gid /etc/passwd
file.get_uid /etc/passwd
  转载请注明出处:http://www.xiaomastack.com/2014/10/16/saltstack01/ 谢谢!


http://www.xiaomastack.com/2014/10/16/saltstack00/
  1、安装
安装saltstack用EPEL源安装简单快捷,实际部署的时候可以将saltstack相关的rpm包放到本地的yum源用本地源安装。
安装EPEL源:



1
2


[iyunv@saltstack ~]#wget -c http://dl.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm
[iyunv@saltstack ~]#rpm -ivh epel-release-6-8.noarch.rpm
  安装salt-master,如果master要对自己进行配置管理则服务器master端本地也要安装minion



1
2
3


[iyunv@saltstack ~]#yum install salt-master
#安装salt-minion可选
[iyunv@saltstack ~]#yum install salt-minion
  2、修改配置文件并启动服务。saltstack配置比较简单,一般不需要修改太多的参数。
salt-master端,暂时没有什么配置的,默认就好。



1
2
3
4
5
6
7
8


[iyunv@saltstack ~]# grep -Ev "^#|^$" /etc/salt/master
file_roots:
  base:
    - /srv/salt
pillar_roots:
  base:
    - /srv/pillar
[iyunv@saltstack ~]# salt-master -d
  salt-minion端,配置 “master”项指向master的IP地址,配置 “id” 项为主机名(一般用主机名,也可以配成其它的标识符)



1
2
3
4
5


[iyunv@minion01 ~]# grep -Ev "^#|^$" /etc/salt/minion
master: 192.168.186.134
id: minion01
[iyunv@minion01 ~]# salt-minion -d
[iyunv@minion01 ~]#



1
2
3
4
5


[iyunv@minion02 ~]# grep -Ev "^#|^$" /etc/salt/minion
master: 192.168.186.134
id: minion02
[iyunv@minion02 ~]# salt-minion -d
[iyunv@minion02 ~]#
  3、master认证端添minion的key,并做简单的存活测试。
salt-key管理所有的key,-L参数列出所有的key.”Unaccepted Keys”就是所有未认证minion端的key。



1
2
3
4
5
6


[iyunv@saltstack ~]# salt-key -L
Accepted Keys:
Unaccepted Keys:
minion01
minion02
Rejected Keys:
  -A参数接纳(认证)所有未被接纳(认证)的key,-a参数认证单个指定的key。



1
2
3
4
5
6
7
8


[iyunv@saltstack ~]# salt-key -A
The following keys are going to be accepted:
Unaccepted Keys:
minion01
minion02
Proceed? [n/Y] y
Key for minion minion01 accepted.
Key for minion minion02 accepted.
  再查看下所有key的情况,可以看到”Accepted Keys”已经认证的key。



1
2
3
4
5
6


[iyunv@saltstack ~]# salt-key -L
Accepted Keys:
minion01
minion02
Unaccepted Keys:
Rejected Keys:
  用test.ping测试下minion端的存活,可以从返回值看到minion01和minion02在线



1
2
3
4
5
6


[iyunv@saltstack ~]# salt \* test.ping
minion01:
    True
minion02:
    True
[iyunv@saltstack ~]#
  用test.ping命令测试时,如果等待的返回时间较长有可能是某些minion已经不在线了,可以用salt-run来查看所有minion的存活状态。



1
2
3
4
5
6


[iyunv@saltstack ~]# salt-run manage.status
down:
up:
    - minion01
    - minion02
[iyunv@saltstack ~]#
  转载请注明出处:http://www.xiaomastack.com/2014/10/16/saltstack00/ 谢谢!
  
  
  
  http://www.xiaomastack.com/2014/10/13/release-3/
版本更新发布WEB化(3)_小插曲自定义请求saltAPI的类

By 小马 · 十月 13, 2014 · 运维开发 · Leave a comment
  安装了saltAPI后就可以在任何一台服务器上调用saltAPI让saltstack执行相关的操作。之前用PHP和python写过相关的调用类,如果有兴趣可以移步以下文章《用PHP实现salt-api调用》和《用Python实现salt-api调用》。思路都是一样的,不过这两篇代码不够优雅。下面再上一个后来用python用写的比较优雅的一个类,看上去会简洁美观很多。



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52


#!/usr/bin/env python
#coding=utf-8

import urllib2, urllib, json, re

class saltAPI:
    def __init__(self):
        self.__url = 'https://saltAPI监控的地址和端口如:192.168.192.168:8000'
        self.__user = '调用saltAPI时的用户名'
        self.__password = '调用saltAPI时的密码'
        self.__token_id = self.salt_login()

    def salt_login(self):
        params = {'eauth': 'pam', 'username': self.__user, 'password': self.__password}
        encode = urllib.urlencode(params)
        obj = urllib.unquote(encode)
        headers = {'X-Auth-Token':''}
        url = self.__url + '/login'
        req = urllib2.Request(url, obj, headers)
        opener = urllib2.urlopen(req)
        content = json.loads(opener.read())
        try:
            token = content['return'][0]['token']
            return token
        except KeyError:
            raise KeyError
         
    def postRequest(self, obj, prefix='/'):
        url = self.__url + prefix
        headers = {'X-Auth-Token'   : self.__token_id}
        req = urllib2.Request(url, obj, headers)
        opener = urllib2.urlopen(req)
        content = json.loads(opener.read())
        return content['return']

    def saltCmd(self, params):
        obj = urllib.urlencode(params)
        obj, number = re.subn("arg\d", 'arg', obj)
        res = self.postRequest(obj)
        return res

def main():
    #以下是用来测试saltAPI类的部分
    sapi = saltAPI()
    params = {'client':'local', 'fun':'test.ping', 'tgt':'某台服务器的key'}
    #params = {'client':'local', 'fun':'test.echo', 'tgt':'某台服务器的key', 'arg1':'hello'}
    #params = {'client':'local', 'fun':'test.ping', 'tgt':'某组服务器的组名', 'expr_form':'nodegroup'}
    test = sapi.saltCmd(params)
    print test

if __name__ == '__main__':
    main()
  转载请注明出处:http://www.xiaomastack.com/2014/10/13/release-3/ 谢谢!
  
  
  http://www.xiaomastack.com/2014/06/26/php-salt-api/
用PHP实现salt-api调用

By 小马 · 六月 26, 2014 · 运维开发 · Leave a comment
  saltstack由于其强大的配置部署及管理功能,是越来越火,被很多运维人员所认可。由于最近要开发一个运维平台,底层用到了salt-api来实现。如果你是入门的用户可以参考saltstack安装的bolg http://blog.coocla.org/category/saltstack 还有很多优秀的blog,可以百度神马的很多的,还有我们的saltstack中文站也可以逛逛  http://www.saltstack.cn/ 。
  安装salt-api请参考 http://www.saltstack.cn/projects/cssug-kb/wiki/salt-api-deploy-and-use
  经过saltsatck和salt-api的学习后,开始了苦逼的堆代码的工作,首先用PHP实现了对salt-api的访问,后来由于别的需求也实现了Python对salt-api的访问。
  下面的代码是最初的比较原始的版本saltapi.php,不过功能够用了。



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61


<?php
function get_token(){
global $token;
$url = 'https://ip:8000/login'; //ip是已经配好的api地址如 192.168.1.22
$ch = curl_init($url);
curl_setopt($ch,CURLOPT_POST,TRUE);
curl_setopt($ch,CURLOPT_SSL_VERIFYHOST,2);
curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,False);
curl_setopt($ch,CURLOPT_HTTPHEADER, Array('Accept: application/x-yaml'));
curl_setopt($ch,CURLOPT_POSTFIELDS, 'username=你的用户名&password=用户对应的密码&eauth=pam');
curl_setopt($ch,CURLOPT_RETURNTRANSFER,TRUE);
$token = curl_exec($ch);
$token = strstr($token, 'token', false);  //取登录后返回字符串中的token
$token = strstr($token, 'user', true);
$token = explode(" ",$token)[1];
curl_close($ch);
$token = rtrim($token,"\n"); //删掉token字符串最后面的'\n',不然后面死活登不上去
}

//适用于带一个或不带参数的salt exc模块如 salt \* test.ping 或 salt \* test.echo "hello"这样的模块
function exc_salt($tgt, $fun, $arg, $arg_num){
global $token;
global $report;
$url = 'https://ip:8000/';
$ch = curl_init($url);
curl_setopt($ch,CURLOPT_POST,TRUE);
curl_setopt($ch,CURLOPT_SSL_VERIFYHOST,2);
curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,False);
curl_setopt($ch,CURLOPT_HTTPHEADER,Array('Accept: application/x-yaml',"X-Auth-Token: $token"));
if ($arg_num)
    curl_setopt($ch,CURLOPT_POSTFIELDS,"client=local&tgt=$tgt&fun=$fun&arg=$arg");
else
    curl_setopt($ch,CURLOPT_POSTFIELDS,"client=local&tgt=$tgt&fun=$fun");
curl_setopt($ch,CURLOPT_RETURNTRANSFER,TRUE);
$report = curl_exec($ch);
curl_close($ch);
return $report;
}

//适用于带两个参数的salt exc模块
function exc_salt_2($tgt, $fun, $arg_1, $arg_2){
global $token;
global $report;
$url = 'https://ip:8000/';
$ch = curl_init($url);
curl_setopt($ch,CURLOPT_POST,TRUE);
curl_setopt($ch,CURLOPT_SSL_VERIFYHOST,2);
curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,False);
curl_setopt($ch,CURLOPT_HTTPHEADER,Array('Accept: application/x-yaml',"X-Auth-Token: $token"));
curl_setopt($ch,CURLOPT_POSTFIELDS,"client=local&tgt=$tgt&fun=$fun&arg=$arg_1&arg=$arg_2");
curl_setopt($ch,CURLOPT_RETURNTRANSFER,TRUE);
$report = curl_exec($ch);
curl_close($ch);
return $report;
}

//以下是测试这个脚本功能的部分,正式上线是得注释掉
get_token();
print exc_salt('主机key', 'test.echo', 'hello', 1); //带一个参数的
print exc_salt('主机key', 'test.ping', '', 0);  //不带参数的
?>
  运行结果如下:
DSC00021.jpg
  这些函数还可以封装成一个类,方便调用。如果要求不高这样也可以满足要求了。
  salt-api手册参考 http://salt-api.readthedocs.org/en/latest/
  如果你的python还可以的话,直接看源代码,也是一样一样的。
  转载请注明出处http://www.xiaomastack.com/2014/06/26/php-salt-api/ 谢谢!
  
  http://www.xiaomastack.com/2014/06/30/saltminionerror/
解决启动salt-minion时“ImportError: No module named salt.scripts”错误

By 小马 · 六月 30, 2014 · SaltStack, 配置管理 · Leave a comment
  这是当初部署saltstack时候的问题了,saltstack用的是0.17.4的版本。正当开心minion部署到最后一台时时杀出了个程咬金,当启动 minion端时报错 “ImportError: No module named salt.scripts” 具体信息如下图:
DSC00022.jpg
  但是明明是存在 scripts 脚本和完整的模块的,salt硬是找不到,汗!后来发现这台机器上有几个python环境,7层地狱啊!用 python –version 命令查看默认的 python环境是2.7的,而saltstack安装环境python2.6的,saltstack 模块是安装在 python2.6 的库里面的。所以会一直提示找不到模块。
  好了,原因找到了问题就好解决了,手动指定 salt-minion 启动脚本的运行环境为 python2.6(2.6系统默认安装CentOS6.3) 如下:

  然后,然后问题就解决了。
  转载请注明出处 http://www.xiaomastack.com/2014/06/30/saltminionerror/ 谢谢!
  
  
  
  http://www.xiaomastack.com/2014/06/30/saltstackmasterz/
解决salt-master部分僵尸子进程问题

By 小马 · 六月 30, 2014 · SaltStack, 配置管理 · Leave a comment
  saltstack在线上稳定的运行了一段时间,最近发现时不时 master 的少量的子进程变成了僵尸进程,最快的解决方法是重启master,但是治标不治本,一段时间后又会出现少量的僵尸进程。开始还以为是master的子进程启少了,如是修改 /etc/salt/master 配置文件增加子线程的数量,但是还是会发现僵尸进程。
  经过一段时间的摸索,发现master端的超时时间默认是 5s 。由于运维平台有更多的采集任务需要master来执行,master在有任务突发的情况下,有些配置的下发或者脚本的执行很容易超时,超时的最直接结果是“配置和操作步骤都没有问题,但是批量执行时会随机的报错,把报错的任务单独执行又完全正确”。
  解决方法是更改 /etc/salt/master 配置文件,将 timeout 项的注释取消,将时间改成 5s 的倍数(这只是我改参数的习惯。其它也行,只要比5s大合适就行)。然后重启 master 就不会出现僵尸进程了。
  转载请注明出处 http://www.xiaomastack.com/2014/06/30/saltstackmasterz/ 谢谢!
  
  
  http://www.xiaomastack.com/2014/06/27/python-salt-api/
  之前写过用PHP实现salt-api调用,由于业务需求又整了个Python版的,实现的思路和PHP一样,这里只贴出访问带1个参数或不带参数salt执行模块的代码,如果需要使用更多的参数,多堆几段代码就好了。如果不懂 saltstack 或 salt-api 建议参考PHP那篇中给的链接先好好学习学习(saltsatck是个运维利器,值得你这么做)。
  先贴出我的代码,不好勿喷:



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57


#!/usr/bin/python
# -*- coding: utf-8 -*-

import pycurl
import StringIO

#登录salt-api,获取token
def api_login():
    global token
    url='https://IP地址:8000/login'
    ch=pycurl.Curl()
    ch.setopt(ch.URL, url)
    info = StringIO.StringIO()
    ch.setopt(ch.WRITEFUNCTION, info.write)
    ch.setopt(ch.POST, True)
    #如果是https就要开启这两行
    ch.setopt(ch.SSL_VERIFYPEER, 0)
    ch.setopt(ch.SSL_VERIFYHOST, 2)
    ch.setopt(ch.HTTPHEADER, ['Accept: application/x-yaml'])
    ch.setopt(ch.POSTFIELDS, 'username=你的用户名&password=对应用户的密码&eauth=pam')
    #要包头信息
    #ch.setopt(ch.HEADER, True)
    #不要包头信息
    ch.setopt(ch.HEADER,False)
    ch.perform()
    html = info.getvalue()
    #提取token
    token = html.split("\n")[-3].replace("\n", '')
    token = token.split(' ')[3]
    info.close()
    ch.close()

def api_exec(target, fun, arg='', arg_num=0):
    global token
    url='https://IP地址:8000/'
    ch=pycurl.Curl()
    ch.setopt(ch.URL, url)
    info = StringIO.StringIO()
    ch.setopt(ch.WRITEFUNCTION, info.write)
    ch.setopt(ch.POST, True)
    ch.setopt(ch.SSL_VERIFYPEER, 0)
    ch.setopt(ch.SSL_VERIFYHOST, 2)
    ch.setopt(ch.HTTPHEADER, ['Accept: application/x-yaml', "X-Auth-Token: %s" %(token)])
    if arg_num == 0:
        ch.setopt(ch.POSTFIELDS, "client=local&amp;tgt=%s&amp;fun=%s" %(target, fun))
    elif arg_num == 1:
        ch.setopt(ch.POSTFIELDS, "client=local&amp;tgt=%s&amp;fun=%s&amp;arg=%s" %(target, fun, arg))
    ch.setopt(ch.HEADER,False)
    ch.perform()
    html = info.getvalue()
    info.close()
    ch.close()
    return html

#测试时用的,做为模块使用时请注释下面两行
api_login()
print api_exec('主机key', 'test.ping', '', 0)
  先亮执行结果截图,哈哈:

  关键的地方是提取经过认证后的 token,不要忘记除掉结尾的换行符”\n”,不然就悲剧了。
  转载请注明出处http://www.xiaomastack.com/2014/06/27/python-salt-api/ 谢谢!
  
  
  
  
  
  



  

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-114333-1-1.html 上篇帖子: saltstack基础使用简版000; 下篇帖子: 来晚了--SALTSTACK要弄起
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表