salt 编写代码
salt远程执行底层原理
1
2
3
4
5
6
7salt底层通信是通过zeroMQ完成的,采用了zeroMQ的订阅发布模式.在订阅发布模式中Pub将消息发送到总线,所有的Sub接收到来自总线的消息后,根据自己的订阅条件来接收特定的消息.对应于salt中就是master将事件发布到消息总线,minion订阅并监听事件,然后minion会查看事件是否和自己匹配以确定是否需要执行.
salt master启动时会监听两个端口,默认是4505和4506
* 4506 salt master Ret接口,支持认证,文件服务,结果收集等
* 4505 salt master pub接口,提供远程执行命令发送功能
salt minion 启动时从配置文件中获取master地址,如果为域名,则进行解析.解析后,会连接master的4506端口(Ret)进行key认证.认证通过,会获取master的publish_port(4505),然后连接publish_port订阅来自master pub接口任务. 当master下发操作指令时,所有的minion都能接收到,然后minion会检查本机是否匹配.如果匹配,则执行.执行完毕后,把结果发送到master的4506(ret)由master进行处理.命令发送通信完全是异步的,并且命令包很小.此外,这些命令包通过maqpack进行序列化后数据会进一步压缩,所以salt网络负载非常低执行模块的构成结构
1
2
3
4
5
6
7
8
9
10
11
12例如: test.sleep
def sleep(length):
"""
Instruct the minion to initiate a process that will sleep for a given period of timezone
CLI Example:
.. code-block::bash
salt '*' test.sleep 20
"""
time.sleep(int(length))
return True
综上,salt的执行模块函数其实就是python函数,但通过结合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* 创建模块存放位置(默认)
[root@saltserver ~]# mkdir -p /srv/salt/_modules
* 编写模块
[root@saltserver ~]# vim /srv/salt/_modules/hello.py
def world():
"""
This is my first function.
CLI Example:
salt '*' hello.world
"""
return 'Hello, world!'
* 把模块推送到所有minion上
[root@saltserver ~]# salt '*' saltutil.sync_modules
192.168.13.187:
- modules.hello
[root@saltserver ~]# salt '*' sys.list_modules|grep hello
- hello
* 在所有minion上执行模块
[root@saltserver ~]# salt '*' hello.world
192.168.13.187:
Hello, world!交叉调用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* __salt__函数
[root@saltserver ~]# vim /usr/local/python27/lib/python2.7/site-packages/salt/modules/useradd.py
ret = __salt__['cmd.run_all'](cmd, python_shell=False)
综上,我们可以通过"__salt__"调用所有其他执行模块,就像使用salt命令一样简单
* __grains__和__pillar__函数
[root@saltserver ~]# vim /usr/local/python27/lib/python2.7/site-packages/salt/modules/aptpkg.py
if __grains__.get('os_family') in ('Kali', 'Debian', 'neon'):
if __grains__['os'] in ('Ubuntu', 'Mint', 'neon'):
综上,可以看出__grains__类似于grain模块,可以获取主机的信息并使用
同样,__pillar__类似于pillar模块
* __virtual__函数
__virtual__函数作用很特殊.salt在加载执行模块时,__virtual__函数可以帮助salt完成以下两项工作:
1.帮助salt决定是否要加载这个模块
2.需要时可以重新命名该模块
例如:
[root@saltserver ~]# vim /usr/local/python27/lib/python2.7/site-packages/salt/modules/aptpkg.py
# Define the module's virtual name
__virtualname__ = 'pkg'
def __virtual__():
'''
Confirm this module is on a Debian based system
'''
if __grains__.get('os_family') in ('Kali', 'Debian', 'neon'):
return __virtualname__
elif __grains__.get('os_family', False) == 'Cumulus':
return __virtualname__
return (False, 'The pkg module could not be loaded: unsupported OS family')
在模块加载时执行"__virtual__"函数,"__virtual__"函数通过"__grains__"函数判断操作系统是否为'kali'或'debian','neno',并返回"__virtualname__"值,而"__virtualname__"的值将作为模块名使用.如果返回值为False,则模块中函数将不被加载;如果返回值为True,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* 编写模块
[root@saltserver ~]# vim /srv/salt/_modules/prank.py
# -*- coding:utf-8 -*-
"""
The top nth processes which take up CPU and Memory space usage are available through this module,aditionaly;the module can get the system load information.
"""
# import python libs
import os
# import salt libs
import salt.utils
def cpu(n):
"""
Return the top nth processes which take up the cpu usage for this minion
CLI Example:
salt '*' prank.cpu <n>
"""
cmd = "ps aux|sort -k3 -nr|head -n%s" % str(n)
output = __salt__['cmd.run_stdout'](cmd)
res = []
for line in output.splitlines():
res.append(line)
return res
def mem(n):
"""
Return th top nth processes which take up the memory usage for this minion
CLI example:
salt '*' prink.mem <n>
"""
cmd = "ps aux|sort -k4 -nr|head -n%s" % str(n)
output = __salt__['cmd.run_stdout'](cmd)
res = []
for line in output.splitlines():
res.append(line)
return res
def load():
"""
Return the load averages for this minion
CLI Example:
salt '*' prink.load
"""
load_avg = os.getloadavg()
return {'1-min': load_avg[0],'5-min':load_avg[1],'15-min':load_avg[2]}
* 同步模块
[root@saltserver ~]# salt '*' saltutil.sync_modules
192.168.13.187:
- modules.prank
* 查看模块帮助
[root@saltserver ~]# salt '192.168.13.187' sys.doc prank
prank.cpu:
Return the top nth processes which take up the cpu usage for this minion
CLI Example:
salt '*' prank.cpu <n>
prank.load:
Return the load averages for this minion
CLI Example:
salt '*' prink.load <n>
prank.mem:
Return th top nth processes which take up the memory usage for this minion
CLI example:
salt '*' prink.mem <n>
* 执行模块
[root@saltserver ~]# salt '*' prank.load
192.168.13.187:
----------
1-min:
0.0
15-min:
0.0
5-min:
0.0