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版本不在支持的范圍內;如果強行安裝,可能會導致穩定性的問題。
再說好消息:既然有了安裝需求,我們可以自定義安裝,這樣可以做到完全不影響系統環境。
既然已經決定了我們要走"自定義安裝"的道路,那么我們就"兵馬未行,糧草先動"。(本文就當個教程寫了,之前的探索過程就不寫了)
-
准備所需要的程序包。
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機器,存在單點危險,而且沒有做負載均衡。目前還沒有想到很好的解決方案。
歡迎大家一起討論。
- <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> 
· 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/
一、設備環境說明
有兩組web業務服務器,組名分別為web1group與web2group,設備硬件配置、web根目錄存在異常,見下圖:
二、master配置說明
1、關鍵配置定義:
- nodegroups:
- web1group: 'L@SN2012-07-010,SN2012-07-011,SN2012-07-012'
- web2group: 'L@SN2013-08-021,SN2013-08-022'
- file_roots:
- base:
- - /srv/salt
- pillar_roots:
- base:
- - /srv/pillar
2、定義的文件樹結構(具體文件后續說明)
三、自定義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
[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
- base:
- web1group:
- - match: nodegroup
- - web1server
- web2group:
- - match: nodegroup
- - web2server
2)定義私有配置,本例只配置web_root的數據,當然可以根據不同需求進行定制,格式為python的字典形式,即"key:value"。
#vi /srv/pillar/web1server.sls
- nginx:
- root: /www
#vi /srv/pillar/web2server.sls
- nginx:
- 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
- base:
- '*':
- - nginx
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
(由於非第一次運行,看不到配置文件比對的信息)
5)驗證結果:
1、登錄root@SN2013-08-021
#vi /etc/nginx/nginx.conf
2、登錄root@SN2012-07-010
#vi /etc/nginx/nginx.conf
=========================================================
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命令就好了。
2、資產管理。
資產管理主要分為硬件資產和軟件資產,硬件資產由saltsatck的grains來采集,軟件資產的收集由saltstack下發執行采集腳本來完成。所有的這些操作都自動完成(采集、入庫、展示)。打碼的地方太多我用PS來打吧!
3、版本發布。
版本發布實現功能
a、能從操作者本地上傳zip更新包,更新到正式環境或測試環境。如果更新到測試環境經過測試后沒有問題再推送到正式環境。也可以直接更新到正式環境。
b、開發人員提供包名后,根據包名從ftp服務器下載zip更新包,更新到正式環境或測試環境。如果更新到測試環境后沒有問題再推送到正式環境。也可以直接更新到正式環境。
c、能夠回滾到上一個版本(測試或正式環境)。
4、數據展示。
主要做的是Zabbix監控數據的展示,分類、分應用、分主機。原始數據由Zabbix采集,然后另外的機器用ZabbixAPI向Zabbix取監控數據存放到rrd文件,最后由RRDTool繪圖展示監控數據。
硬件監控數據展示分類沿用Zabbix自身的分類,軟件應用監控數據的分類采用再繪圖時的自定義的分類。
點擊一台主機,監控數據默認展示的是1天的監控數據。
點擊圖可以進入該監項在過去1天、1周、1月、1年的監控圖,默認30秒刷新一次(也可以手動刷新)
點擊1天的監控圖,可以進入該監控項2小時的監控圖,默認30秒刷新,也可以手動刷新。
轉載請注明出處:http://www.xiaomastack.com/2014/09/20/yunweipingtai2/ 謝謝!
11 Comments
Add your comment
==========
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 ~]
#wget https://pypi.python.org/packages/source/p/pip/pip-1.5.6.tar.gz#md5=01026f87978932060cc86c1dc527903e --no-check-certificate
[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
.__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/
配置管理篇(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/ 謝謝!
配置管理篇(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/ 謝謝!
1、安裝
安裝saltstack用EPEL源安裝簡單快捷,實際部署的時候可以將saltstack相關的rpm包放到本地的yum源用本地源安裝。
安裝EPEL源:
|
1
2
|
[root@saltstack ~]
#wget -c http://dl.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm
[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
.__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
;
$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
;
$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
;
$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);
//不帶參數的
?>
|
運行結果如下:
這些函數還可以封裝成一個類,方便調用。如果要求不高這樣也可以滿足要求了。
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” 具體信息如下圖:
但是明明是存在 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部分僵屍子進程問題
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
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
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&tgt=%s&fun=%s"
%
(target, fun))
elif
arg_num
=
=
1
:
ch.setopt(ch.POSTFIELDS,
"client=local&tgt=%s&fun=%s&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/ 謝謝!
















請問這個能分享和共同學習一下?
最近也在邊學邊寫運維平台,剛好也是用django;方便給下代碼嗎?感謝!
我一哥們兒開源了一個,也是用的Django,你可以參考下:
https://github.com/binbin91/oms你好,我現在已經做好一部分自動化運維平台django+bootstrap實現,完成資產管理,部分配置管理,堡壘機全部功能,現在想接入zabbix告警報表,看你的做的不錯,能共享下嗎,可以QQ私聊,你需要我的也可以共享。代碼寫的爛 現在主要是思路 希望慢慢優化,完善 。謝謝 QQ:1873447820
已加,不過我的zabbix告警報表沒有接到平台上。
方便發一下代碼給我參考一下么,我也一直想開發這樣一個平台
已發郵件
小馬哥,搞的不錯開源么?
小馬哥?
今天剛上班,呵呵
每個公司的運維環境和需求不一樣,還有就是代碼不夠好就不開源了,望見諒。