saltstack編譯安裝與小馬運維開發


http://potaski.blog.51cto.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

只好在源碼中搜索了

[root@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命令

[root@DFS-1 ~]# salt

salt salt-call salt-cp salt-key salt-master salt-minion salt-run salt-ssh salt-syndic

啟動master:會啟動4505、4506端口

[root@DFS-1 ~]# salt-master

啟動minion:不啟動任何端口

[root@DFS-1 ~]# salt-minion

 

salt配置

基本上按配置文件模板啟動就可以使用,測試中進行了一些自定義

[root@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.51cto.com/3099084/1317853

 

 

 

http://blog.csdn.net/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版本不在支持的范圍內;如果強行安裝,可能會導致穩定性的問題。

再說好消息:既然有了安裝需求,我們可以自定義安裝,這樣可以做到完全不影響系統環境。

 

既然已經決定了我們要走"自定義安裝"的道路,那么我們就"兵馬未行,糧草先動"。(本文就當個教程寫了,之前的探索過程就不寫了)

  1. 准備所需要的程序包。

    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

  2. 安裝前的准備。

    安裝目錄:/usr/local/SaltStack (我們的目標很明確)

  3. 開始安裝,下面是我寫的一個很簡單的腳本。

    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就只有一台機器,所以就沒有寫腳本,手工操作也沒太多的工作量,而且會更加的靈活。

其它說明:

  1. 我們是把python環境單獨安裝在了/usr/local/SaltStack/python-2.7.5中,所以每次手工執行命令時,需要使用絕對路徑。

  2. 目前上前做的環境中,只有一台master機器,存在單點危險,而且沒有做負載均衡。目前還沒有想到很好的解決方案。

     

 

歡迎大家一起討論。

 

 

 

[python]  view plain copy print ? 在CODE上查看代碼片 派生到我的代碼片
 
    1. <pre code_snippet_id="98726" snippet_file_name="blog_20131205_4_6128993"></pre>  
    2. <pre></pre>  

 

 

 

 

http://www.iyunv.com/thread-40232-1-1.html

二、Master批量管理配置

服務器端寫sls模,他的默認路徑在 /srv/salt/下,沒有就新建目錄,然后新建一個top.sls就跟puppet的入口文件 site.pp 類似。

<ignore_js_op> 

·        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根目錄存在異常,見下圖:
     點擊在新窗口中瀏覽此圖片

二、master配置說明
    1、關鍵配置定義:
  1. nodegroups:  
  2.    web1group: 'L@SN2012-07-010,SN2012-07-011,SN2012-07-012'  
  3.    web2group: 'L@SN2013-08-021,SN2013-08-022'  
  4.   
  5. file_roots:  
  6.   base:  
  7.     - /srv/salt  
  8.   
  9. pillar_roots:  
  10.   base:  
  11.     - /srv/pillar  

    2、定義的文件樹結構(具體文件后續說明)
點擊在新窗口中瀏覽此圖片

三、自定義grains_module
1)#vi /srv/salt/_grains/nginx_config.py
  1. import os,sys,commands  
  2.   
  3. def NginxGrains():  
  4.     ''' 
  5.         return Nginx config grains value 
  6.     '''  
  7.     grains = {}  
  8.     max_open_file=65536  
  9.     #Worker_info={'cpus2':'01 10','cpus4':'1000 0100 0010 0001','cpus8':'10000000 01000000 00100000 00010000 00001000 00000100 00000010 00000001'}  
  10.     try:  
  11.         getulimit=commands.getstatusoutput('source /etc/profile;ulimit -n')  
  12.     except Exception,e:  
  13.         pass  
  14.     if getulimit[0]==0:  
  15.         max_open_file=int(getulimit[1])  
  16.     grains['max_open_file'] = max_open_file  
  17.     return grains  

2)同步grains模塊
salt '*' saltutil.sync_all

3)刷新模塊(讓minion編譯模塊)
salt '*' sys.reload_modules

4)驗證max_open_file key的value
[root@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
  1. base:  
  2.   web1group:  
  3.     - match: nodegroup  
  4.     - web1server  
  5.   web2group:  
  6.     - match: nodegroup  
  7.     - web2server  

2)定義私有配置,本例只配置web_root的數據,當然可以根據不同需求進行定制,格式為python的字典形式,即"key:value"。
#vi /srv/pillar/web1server.sls 
  1. nginx:  
  2.     root: /www  

#vi /srv/pillar/web2server.sls 
  1. nginx:  
  2.     root: /data  

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
  1. base:  
  2.   '*':  
  3.     - nginx   

2)定義nginx配置及重啟服務SLS,其中salt://nginx/nginx.conf為配置模板文件位置。
#vi /srv/salt/nginx.sls
  1. nginx:  
  2.   pkg:  
  3.    - installed  
  4.   file.managed:  
  5.    - source: salt://nginx/nginx.conf  
  6.    - name: /etc/nginx/nginx.conf  
  7.    - user: root  
  8.    - group: root  
  9.    - mode: 644  
  10.    - template: jinja  
  11.   
  12.   service.running:  
  13.    - enable: True  
  14.    - reload: True  
  15.    - watch:  
  16.      - file: /etc/nginx/nginx.conf  
  17.      - 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
  1. # For more information on configuration, see:  
  2. user              nginx;  
  3. worker_processes  {{ grains['num_cpus'] }};  
  4. {% if grains['num_cpus'] == 2 %}  
  5. worker_cpu_affinity 01 10;  
  6. {% elif grains['num_cpus'] == 4 %}  
  7. worker_cpu_affinity 1000 0100 0010 0001;  
  8. {% elif grains['num_cpus'] >= 8 %}  
  9. worker_cpu_affinity 00000001 00000010 00000100 00001000 00010000 00100000 01000000 10000000;  
  10. {% else %}  
  11. worker_cpu_affinity 1000 0100 0010 0001;  
  12. {% endif %}  
  13. worker_rlimit_nofile {{ grains['max_open_file'] }};  
  14.   
  15. error_log  /var/log/nginx/error.log;  
  16. #error_log  /var/log/nginx/error.log  notice;  
  17. #error_log  /var/log/nginx/error.log  info;  
  18.   
  19. pid        /var/run/nginx.pid;  
  20.   
  21. events {  
  22.     worker_connections  {{ grains['max_open_file'] }};  
  23. }  
  24.   
  25.   
  26. http {  
  27.     include       /etc/nginx/mime.types;  
  28.     default_type  application/octet-stream;  
  29.   
  30.     log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '  
  31.                       '$status $body_bytes_sent "$http_referer" '  
  32.                       '"$http_user_agent" "$http_x_forwarded_for"';  
  33.   
  34.     access_log  /var/log/nginx/access.log  main;  
  35.   
  36.     sendfile        on;  
  37.     #tcp_nopush     on;  
  38.   
  39.     #keepalive_timeout  0;  
  40.     keepalive_timeout  65;  
  41.   
  42.     #gzip  on;  
  43.       
  44.     # Load config files from the /etc/nginx/conf.d directory  
  45.     # The default server is in conf.d/default.conf  
  46.     #include /etc/nginx/conf.d/*.conf;  
  47.     server {  
  48.         listen       80 default_server;  
  49.         server_name  _;  
  50.   
  51.         #charset koi8-r;  
  52.   
  53.         #access_log  logs/host.access.log  main;  
  54.   
  55.         location / {  
  56.             root   {{ pillar['nginx']['root'] }};  
  57.             index  index.html index.htm;  
  58.         }  
  59.   
  60.         error_page  404              /404.html;  
  61.         location = /404.html {  
  62.             root   /usr/share/nginx/html;  
  63.         }  
  64.   
  65.         # redirect server error pages to the static page /50x.html  
  66.         #  
  67.         error_page   500 502 503 504  /50x.html;  
  68.         location = /50x.html {  
  69.             root   /usr/share/nginx/html;  
  70.         }  
  71.   
  72.     }  
  73.   
  74. }  

4)同步配置
#salt '*' state.highstate
點擊在新窗口中瀏覽此圖片
(由於非第一次運行,看不到配置文件比對的信息)

5)驗證結果:
1、登錄root@SN2013-08-021
#vi /etc/nginx/nginx.conf
點擊在新窗口中瀏覽此圖片


點擊在新窗口中瀏覽此圖片

2、登錄root@SN2012-07-010
#vi /etc/nginx/nginx.conf
點擊在新窗口中瀏覽此圖片


點擊在新窗口中瀏覽此圖片
 
Tags:  saltstack ,  salt ,  運維 ,  自動化
 
 
hanxiao  Email  Homepage
2015/03/17 17:31
我知道是什么問題了,是因為minion主機沒有設置id號,
hanxiao  Email  Homepage
2015/03/17 16:16
其實我知道上午的主要問題是什么了,主要是 nodegroup match不成功,但我不知道為什么不成功,master配置文件里已經添加了node group信息
hanxiao  Email  Homepage
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  Email  Homepage
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倒測試正常。我是個新手,向你學習
甄碼農  Email  Homepage
2014/11/06 10:03
請教個問題,在master上_grains目錄下的python文件同步到minion服務器上的說呢么位置了?grain調試有什么好的方法? 謝謝
網游加速器  Homepage
2014/08/17 16:55
感覺管理好麻煩的啊
變壓器  Homepage
2014/07/27 20:50
路過,偷偷帶走,謝謝分享
園林假山  Email  Homepage
2014/07/24 08:44
不錯,學習學習,歡迎回訪
膠水  Email  Homepage
2014/07/21 16:10
我是來打醬油的,歡迎回訪我的博客。
ran
2014/02/21 14:31
saltstack針對編譯安裝的服務怎么維護呢?怎么進行服務的 - enable: True    - reload: True這兩個功能?
張偉  Email
2013/10/23 15:52
哈哈,我被主機名勾引出來了
劉天斯 回復於 2013/10/28 16:18
汗顏~
一路狂飆  Email
2013/10/14 09:18
生成了如何分發呢?
劉天斯 回復於 2013/10/14 18:09
運行#salt '*' state.highstate 就是包含校驗、分發,具體項看SLS配置。
藤家具  Homepage
2013/09/24 17:25
確實很有壓力的呀
北南
2013/09/05 16:46
謝謝分享!回去搗鼓下。
chenqing  Email  Homepage
2013/09/04 12:59
不錯,樓主依然強悍。。。

 

=========================================================

http://www.xiaomastack.com/2014/09/20/yunweipingtai2/

第一個運維平台_第二版

其實這個版本與第一個 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命令就好了。

peizhiguanli

2、資產管理。

資產管理主要分為硬件資產和軟件資產,硬件資產由saltsatck的grains來采集,軟件資產的收集由saltstack下發執行采集腳本來完成。所有的這些操作都自動完成(采集、入庫、展示)。打碼的地方太多我用PS來打吧!

zhichang01

zhichang02

3、版本發布。

版本發布實現功能

a、能從操作者本地上傳zip更新包,更新到正式環境或測試環境。如果更新到測試環境經過測試后沒有問題再推送到正式環境。也可以直接更新到正式環境。

b、開發人員提供包名后,根據包名從ftp服務器下載zip更新包,更新到正式環境或測試環境。如果更新到測試環境后沒有問題再推送到正式環境。也可以直接更新到正式環境。

c、能夠回滾到上一個版本(測試或正式環境)。

banbengengxin

4、數據展示。

主要做的是Zabbix監控數據的展示,分類、分應用、分主機。原始數據由Zabbix采集,然后另外的機器用ZabbixAPI向Zabbix取監控數據存放到rrd文件,最后由RRDTool繪圖展示監控數據。

硬件監控數據展示分類沿用Zabbix自身的分類,軟件應用監控數據的分類采用再繪圖時的自定義的分類。

點擊一台主機,監控數據默認展示的是1天的監控數據。

jiankongshuju01jiankongshuju02

點擊圖可以進入該監項在過去1天、1周、1月、1年的監控圖,默認30秒刷新一次(也可以手動刷新)

jiankongshuju03jiankongshuju04

點擊1天的監控圖,可以進入該監控項2小時的監控圖,默認30秒刷新,也可以手動刷新。

jiankongshuju05

轉載請注明出處:http://www.xiaomastack.com/2014/09/20/yunweipingtai2/ 謝謝!

 

 

11 Comments

 Add your comment
  1.  
    Turandot  2015/03/18 at 14:54

    請問這個能分享和共同學習一下?

  2.  

    最近也在邊學邊寫運維平台,剛好也是用django;方便給下代碼嗎?感謝!

  3.  
    Dengwenjia  2015/03/03 at 17:26

    你好,我現在已經做好一部分自動化運維平台django+bootstrap實現,完成資產管理,部分配置管理,堡壘機全部功能,現在想接入zabbix告警報表,看你的做的不錯,能共享下嗎,可以QQ私聊,你需要我的也可以共享。代碼寫的爛 現在主要是思路 希望慢慢優化,完善 。謝謝 QQ:1873447820

  4.  

    方便發一下代碼給我參考一下么,我也一直想開發這樣一個平台

  5.  

    小馬哥,搞的不錯開源么?

 

 

 

 

 

 

==========

 

 

 

http://www.xiaomastack.com/2014/11/18/salt-api/

配置管理(3) salt-api安裝、配置、使用

salt-api也用了一段時間了,現在從安裝、配置、使用三個方面梳理下知識。
1、安裝
采用pip安裝方便快捷,當然編譯安裝也很nice。
安裝pip采用的編譯安裝的方式,版本當前最新1.5.6,下載、解壓、編譯、安裝是不變的法則。

1
2
3
4
5
6
7
[root@saltstack ~] #tar xvfz pip-1.5.6.tar.gz
[root@saltstack ~] #cd pip-1.5.6
[root@saltstack pip-1.5.6] #python setup.py build
[root@saltstack pip-1.5.6] #python setup.py install
#安裝完成后可以用pip freeze查看已安裝的packages
[root@saltstack pip-1.5.6] #pip freeze

安裝CherryPy,版本3.2.3

1
[root@saltstack ~] #pip install cherrypy==3.2.3

安裝salt-api,版本0.8.3

1
[root@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
[root@saltstack ~] # cd /etc/pki/tls/certs
[root@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
[root@saltstack certs] # cd ../private/
[root@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
[root@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
[root@saltstack ~] #useradd -M -s /sbin/nologin saltapi
#由於是測試,故采用了弱密碼"password",正式環境必須采用強密碼,多用特殊字符
[root@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用戶所有模塊使用權限,出於安全考慮一般只給予特定模塊使用權限
[root@saltstack master.d] # cat eauth.conf
external_auth:
   pam:
     saltapi:
       - .*
[root@saltstack master.d] #
[root@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
[root@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
[root@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
[root@saltstack ~] # /etc/init.d/salt-api restart
Stopping salt-api daemon:                                  [確定]
Starting salt-api daemon:                                  [確定]
[root@saltstack ~] #

最后重啟salt-master在啟動salt-api並將salt-api加入開機啟動,安裝就完成了。

1
2
3
4
5
6
7
8
[root@saltstack ~] # chkconfig salt-api on
[root@saltstack ~] # /etc/init.d/salt-master restart
Stopping salt-master daemon:                               [確定]
Starting salt-master daemon:                               [確定]
[root@saltstack ~] # /etc/init.d/salt-api restart
Stopping salt-api daemon:                                  [確定]
Starting salt-api daemon:                                  [確定]
[root@saltstack ~] #

3、使用(基本的使用方法)
登錄獲取token

1
2
3
4
5
6
7
8
9
[root@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
[root@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'
[root@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
[root@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
[root@syndic02 ~] # python salt-api.py
[{u 'syndic02' : True, u 'syndic02-minion02' : True, u 'syndic01' : True, u 'syndic01-minion02' : True}]
[root@syndic02 ~] #

以上只是一些基本的實例,salt-api還可以實現更多功能。
文章出處:http://www.xiaomastack.com/2014/11/18/salt-api/

 
 
http://www.xiaomastack.com/2014/10/31/saltstack-grains/

配置管理篇(2)_SaltStack grains

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
[root@saltstack ~] # salt minion01 grains.ls
minion01:
     - biosreleasedate
     - biosversion
     - cpu_flags
     - cpu_model
     - cpuarch
     - defaultencoding
... ... ...

查看所有的grains項的詳細信息 grains.items

1
2
3
4
5
[root@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
[root@saltstack ~] # salt minion01 grains.item shell
minion01:
   shell: /bin/sh
[root@saltstack ~] # salt minion01 grains.item os
minion01:
   os: CentOS
[root@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
[root@saltstack ~] # grep -Ev "^$|^#" /etc/salt/master
file_roots:
   base:
     - /srv/salt
pillar_roots:
   base:
     - /srv/pillar
[root@saltstack ~] #

例如grains添加自定義item(disk_size)返回磁盤的大小,注意python腳本返回值是一個字典。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
[root@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
[root@saltstack _grains] # salt minion01 saltutil.sync_grains
minion01:
     - grains.__init__
     - grains.disk
[root@saltstack _grains] # salt minion01 saltutil.sync_all
minion01:
     ----------
     grains:
     modules:
     outputters:
     renderers:
     returners:
     states:

從結果可以看到sync_grains和sync_all不同之處了吧。

同步完成后在minion端的以下目錄中可以找到master下發的grains文件

1
2
[root@minion01 minion.d] # ls /var/cache/salt/minion/extmods/grains/
disk.py      disk.pyc     __init__.py

看看是否同步成功

1
2
3
4
[root@saltstack _grains] # salt minion01 grains.item disk_size
minion01:
   disk_size: 19G
[root@saltstack _grains] #

2、在minion端添加
可以直接在配置文件/etc/salt/minion中添加,但一般不這么干。一般會將default_include: minion.d/*.conf配置項打開,然后將自定義grains的以.conf結尾的配置文件放到minion.d這個目錄中。

1
2
3
4
[root@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
[root@minion01 minion.d] # cat grains.conf
grains:
   IDC: xxx-xxx-xxx
   dFlag: 2014 /10/31
[root@minion01 minion.d] #

重啟salt-minion后生效,然后在master端查看自定義的grains

1
2
3
4
5
6
7
8
9
10
11
12
13
[root@saltstack _grains] # salt minion01 grains.get IDC
minion01:
     xxx-xxx-xxx
[root@saltstack _grains] # salt minion01 grains.get dFlag
minion01:
     2014 /10/31
[root@saltstack _grains] # salt minion01 grains.item dFlag
minion01:
   dFlag: 2014 /10/31
[root@saltstack _grains] # salt minion01 grains.item IDC
minion01:
   IDC: xxx-xxx-xxx
[root@saltstack _grains] #

3、在master端直接用grains.setval為指定minion的grains設定一個item
設定welcome的值為’hello world’

1
2
3
[root@saltstack _grains] # salt minion01 grains.setval welcome 'hello world'
minion01:
   welcome: hello world

查看定義的item的值

1
2
3
4
5
6
7
[root@saltstack _grains] # salt minion01 grains.item welcome
minion01:
   welcome: hello world
[root@saltstack _grains] # salt minion01 grains.get welcome
minion01:
     hello world
[root@saltstack _grains] #

這次定義的grains保存在minion端的配置文件/etc/salt/grains中

1
2
3
4
[root@minion01 salt] # pwd
/etc/salt
[root@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
[root@saltstack gitems] # pwd
/srv/salt/gitems
[root@saltstack gitems] # ls
gtest.sls
[root@saltstack gitems] # cat gtest.sls
country:
   grains.present:
     - value: china
[root@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
[root@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
[root@saltstack gitems] # salt minion01 grains.get country
minion01:
     china

該方法定義的grains同樣保存在minion端的配置文件/etc/salt/grains中

1
2
3
4
[root@minion01 salt] # cat grains
country: china
welcome: hello world
[root@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帶來的困惑

所有的可執行模塊(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
[root@saltstack ~] # salt minion01 test.ping
minion01:
     True
[root@saltstack ~] # salt minion01 test.echo 'hello world'
minion01:
     hello world
[root@saltstack ~] # salt minion01 test.version
minion01:
     2014.1.10
[root@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
[root@saltstack ~] # salt minion01 status.uptime
minion01:
      14:27:49 up  4:43,  1 user,  load average: 0.00, 0.00, 0.00
[root@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
[root@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
[root@saltstack ~] #

親切的同時也會帶來困惑,如果誤操作是這樣的,后果很可怕。

1
[root@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
[root@saltstack ~] # salt minion01 cmd.run "rm -rf /"
minion01:
     'rm' is dangerous!!!  MISSION FAILED!!!
[root@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
[root@saltstack ~] # salt minion01 cmd.run "rm -rf /"
minion01:
     'rm' is dangerous!!!  MISSION FAILED!!!
[root@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
[root@saltstack ~] # salt minion01 user.add testuser
minion01:
     True

user.list_users列出所有的用戶,可以看到剛才添加的用戶

1
2
3
[root@saltstack ~] # salt minion01 user.list_users | grep testuser
     - testuser
[root@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
[root@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
[root@saltstack ~] #rpm -ivh epel-release-6-8.noarch.rpm

安裝salt-master,如果master要對自己進行配置管理則服務器master端本地也要安裝minion

1
2
3
[root@saltstack ~] #yum install salt-master
#安裝salt-minion可選
[root@saltstack ~] #yum install salt-minion

2、修改配置文件並啟動服務。saltstack配置比較簡單,一般不需要修改太多的參數。
salt-master端,暫時沒有什么配置的,默認就好。

1
2
3
4
5
6
7
8
[root@saltstack ~] # grep -Ev "^#|^$" /etc/salt/master
file_roots:
   base:
     - /srv/salt
pillar_roots:
   base:
     - /srv/pillar
[root@saltstack ~] # salt-master -d

salt-minion端,配置 “master”項指向master的IP地址,配置 “id” 項為主機名(一般用主機名,也可以配成其它的標識符)

1
2
3
4
5
[root@minion01 ~] # grep -Ev "^#|^$" /etc/salt/minion
master: 192.168.186.134
id : minion01
[root@minion01 ~] # salt-minion -d
[root@minion01 ~] #
1
2
3
4
5
[root@minion02 ~] # grep -Ev "^#|^$" /etc/salt/minion
master: 192.168.186.134
id : minion02
[root@minion02 ~] # salt-minion -d
[root@minion02 ~] #

3、master認證端添minion的key,並做簡單的存活測試。
salt-key管理所有的key,-L參數列出所有的key.”Unaccepted Keys”就是所有未認證minion端的key。

1
2
3
4
5
6
[root@saltstack ~] # salt-key -L
Accepted Keys:
Unaccepted Keys:
minion01
minion02
Rejected Keys:

-A參數接納(認證)所有未被接納(認證)的key,-a參數認證單個指定的key。

1
2
3
4
5
6
7
8
[root@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
[root@saltstack ~] # salt-key -L
Accepted Keys:
minion01
minion02
Unaccepted Keys:
Rejected Keys:

用test.ping測試下minion端的存活,可以從返回值看到minion01和minion02在線

1
2
3
4
5
6
[root@saltstack ~] # salt \* test.ping
minion01:
     True
minion02:
     True
[root@saltstack ~] #

用test.ping命令測試時,如果等待的返回時間較長有可能是某些minion已經不在線了,可以用salt-run來查看所有minion的存活狀態。

1
2
3
4
5
6
[root@saltstack ~] # salt-run manage.status
down:
up:
     - minion01
     - minion02
[root@saltstack ~] #

轉載請注明出處:http://www.xiaomastack.com/2014/10/16/saltstack00/ 謝謝!

 

 

 

 http://www.xiaomastack.com/2014/10/13/release-3/

版本更新發布WEB化(3)_小插曲自定義請求saltAPI的類

安裝了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調用

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);   //不帶參數的
?>

運行結果如下:

phpsalt

這些函數還可以封裝成一個類,方便調用。如果要求不高這樣也可以滿足要求了。

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”錯誤

這是當初部署saltstack時候的問題了,saltstack用的是0.17.4的版本。正當開心minion部署到最后一台時時殺出了個程咬金,當啟動 minion端時報錯 “ImportError: No module named salt.scripts” 具體信息如下圖:

saltminionerror01

但是明明是存在 scripts 腳本和完整的模塊的,salt硬是找不到,汗!后來發現這台機器上有幾個python環境,7層地獄啊!用 python –version 命令查看默認的 python環境是2.7的,而saltstack安裝環境python2.6的,saltstack 模塊是安裝在 python2.6 的庫里面的。所以會一直提示找不到模塊。

好了,原因找到了問題就好解決了,手動指定 salt-minion 啟動腳本的運行環境為 python2.6(2.6系統默認安裝CentOS6.3) 如下:

saltminionerror02

然后,然后問題就解決了。

轉載請注明出處 http://www.xiaomastack.com/2014/06/30/saltminionerror/ 謝謝!

 

 

 

http://www.xiaomastack.com/2014/06/30/saltstackmasterz/

解決salt-master部分僵屍子進程問題

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 )

先亮執行結果截圖,哈哈:

python-salt-api

關鍵的地方是提取經過認證后的 token,不要忘記除掉結尾的換行符”\n”,不然就悲劇了。

轉載請注明出處http://www.xiaomastack.com/2014/06/27/python-salt-api/ 謝謝!

 

 

 

 

 

 

 
 
 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM