event學習

近期在學習saltstack的event模塊,發現這個模塊用處很大。於是乎將這個模塊的知識總結下,方便後面學習使用。

原理:基於本地的zeromq pub和pull socket。

作用:(自己的理解)

1、結合returner用作審計。

2、結合reactor用作觸發器。

3、用於第三方程序。


先在master上開啓event監聽,運行ipython,執行如下代碼:

import sys
sys.path.append("/opt/app/salt/lib/python2.6/site-packages")
import salt
event = salt.utils.event.MasterEvent("/opt/app/salt/run/master")
for eachevent in event.iter_events(full=True):
    print eachevent
    print '------------------------'

wKioL1POKaCR3UOXAARbuxpUaYU284.jpg

這個是執行結果,每條數據是個字典,每條數據就是個event事件,每個event事件是由tag和data兩部分組成。只要看tag以"salt/job"開頭的就行了,其他的是爲了兼容舊版本產生的信息。salt/new/jid/new表示任務信息,包含jid、目標minions等等。salt/job/jid/ret/id表示minion返回的結果,包含任務是否成功執行的信息。


我們在master執行這個命令:

salt '192.168.110.132' cmd.run 'sleep 6;echo "haha"'

wKiom1POGxWD9yw2AAVdKxywIbM895.jpg

上面的結果是怎麼回事呢?下面來解釋下(這裏需要多謝saltstack中國用戶組的幫助)


首先master下發命令後,會等待timeout時間(默認5s,可以在配置裏設置),如果所有minion在這個時間內都返回了結果,則直接退出,如果有minion超過timeout事件還沒有返回,則會自動觸發一個saltutil.find_job任務,會向所有minion發送,去檢查任務是否執行。如果minion返回任務正在執行的結果,則master再等待一個timeout週期,如果期間返回了執行結果則退出,否則這樣一直循環。如果期間觸發的find_job任務沒有返回結果,則認爲任務沒有執行,認爲minion出現問題,不再通信。


上面監聽event時,有個對象是event,看了源代碼之後,發現主要的方法:get_event,iter_events,fire_event。在ipython中可以直接看出來的。


get_event(wait=5,tag='',full=False,use_pending=False),這個方法默認等待5s就退出了,默認監聽所有事件,full=True代表返回tag和data的完整信息,full=False表示只返回data信息,use_pending=True表示將信息寫入列表中,會消耗很大的內存,不會使用的。

wKiom1POJQ7gT6l5AAECuY2_sYc550.jpg

iter_events(tag='',full=False),這個方法產生一個生成器,長期用於過濾某些事件,默認是過濾所有事件。


fire_event(data,tag,timeout=1000),這個方法用於觸發一個event事件,timeout是zeromq的連接過期時間,單位是ms。data必須是字典,tag表示標籤。

觸發事件代碼:

import sys
sys.path.append("/opt/app/salt/lib/python2.6/site-packages")

import salt.utils.event
sock_dir = '/opt/app/salt/run/master'
payload = {'sample-msg': 'this is a test',
           'example': 'this is the same test'}

event = salt.utils.event.SaltEvent('master', sock_dir)
event.fire_event(payload, 'tag')


監聽結果:

wKiom1POKByCHArVAAChshVt6BI711.jpg


也可以使用命令行觸發

salt-call event.fire '{"data":"haha"}' 'tag'


上面用的都是/opt/app/salt/run/master裏的socket,那/opt/app/salt/run/minion的socket怎麼使用。這裏需要涉及到minion的id

import sys
sys.path.append("/opt/app/salt/lib/python2.6/site-packages")

import salt
event = salt.utils.event.SaltEvent('minion', '/opt/app/salt/run/minion',id='haha')
for eachevent in event.iter_events(full=True):                  
    print eachevent                                             
    print '------------------------'


在id爲'haha'的minion端觸發兩個事件

/opt/app/salt/bin/salt-call event.fire '{"data":"haha"}' 'tag'

/opt/app/salt/bin/salt-call event.fire_master '{"data":"haha"}' 'tag'

執行結果如下:

wKiom1POLmmCrKMNAAEH3ObdZZA165.jpg

會發現兩個的tag不一樣,第一個是event.fire執行的結果,第二個是event.fire_master的執行結果。

區別:event.fire是在minion觸發一個本地的event,而event.fire_master是從minion觸發一個遠程的event,這個event會發送到master上,也就是說master的標籤是tag,而minion接受的事件tag是fire_master,至於爲什麼是fire_master,這個是源代碼(salt/modules/event.py)裏寫死的。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章