最近在看minion的啓動的源代碼,一路曲折啊,通過一番努力,終於理解了流程。如今記錄下,方便之後查閱。
css
整體來講流程以下:html
一、解析命令行參數和minion配置文件,獲得options和config字典python
二、設置日誌(salt.log.setup.setup_logfile_logger負責)socket
三、設置pidfileide
四、根據master參數決定調用salt.minion.MultiMinion或者salt.minion.Minion初始化函數
五、調用tune_in方法加密
解析命令行參數和配置文件調用的是salt.Minion,這個類極其複雜,使用了高級概念元類,多重繼承。我看的時候特別暈,只是理解了大概。spa
對應文件是salt/__init__.py,這個文件中的Minion類是salt.utils.parsers.MinionOptionParser的子類。命令行
下面代碼對應文件是salt/utils/parsers.py。日誌
class MinionOptionParser(MasterOptionParser): __metaclass__ = OptionParserMeta # 元類 description = ( 'The Salt minion, receives commands from a remote Salt master.' ) # ConfigDirMixIn config filename attribute _config_filename_ = 'minion' # LogLevelMixIn attributes # LOGS_DIR = '/var/log/salt' _default_logging_logfile_ = os.path.join(syspaths.LOGS_DIR, 'minion') # 設置self.config字典的 def setup_config(self): return config.minion_config(self.get_config_file_path(), minion_id=True)
設置日誌,調用的是salt.log.setup.setup_logfile_logger函數,主要是設置handler,loglevel,formatter。用到的是logging模塊。對應的文件是salt/log/setup.py
初始化是通常調用的是salt.minion.Minion,若是設置的多個masters,則會調用salt.minion.MultiMinion。這裏以salt.minion.Minion講解過程。對應文件是salt/minion.py
salt.minion.Minion初始化過程以下:
一、驗證ZMQ的版本
二、獲取grains
三、向ret端口發送驗證請求,獲取master的aes和pub端口
四、獲取pillar數據
五、裝載可用的minion模塊和returners
六、設置schedule
向ret端口發送驗證請求,進行數字簽名過程以下:
對應的接口是salt.crypt.Auth
一、調用get_keys方法load key,若是沒有則生成密鑰對,密鑰保存到minion.pem,公鑰保存到minion.pub,而後再load key,使用的模塊是M2Crypto.RSA
二、進行數字簽名,向master_ip:4506發送請求
請求格式:
payload = {
'enc':'clear',
'load':{
'cmd':'_auth',
'id':minion的id,
'pub':minion.pub的內容,
}
}
返回格式:
payload = {
'aes':加密的數據,
'enc':'pub',
'pub_key':key,
'publish_port':'4505',
'sig':加密的數據
}
三、將pub_key字段對應的數據寫入minion_master.pub
四、對aes和sig字段對應的數據解密,代碼以下
key = self.get_keys() key_str = key.private_decrypt(payload['aes'], RSA.pkcs1_oaep_padding) if 'sig' in payload: m_path = os.path.join(self.opts['pki_dir'], self.mpub) if os.path.exists(m_path): try: mkey = RSA.load_pub_key(m_path) except Exception: return '', '' digest = hashlib.sha256(key_str).hexdigest() m_digest = mkey.public_decrypt(payload['sig'], 5) if m_digest != digest: return '', '' else: return '', '' if '_|-' in key_str: return key_str.split('_|-') else: if 'token' in payload: token = key.private_decrypt(payload['token'], RSA.pkcs1_oaep_padding) return key_str, token elif not master_pub: return key_str, ''
獲取grains數據主要調用的是salt.loader.grains,這個方法會間接去調用salt.loader.Loader類,對應文件是salt/loader.py,這個是調用imp模塊加載模塊的。
獲取pillar數據主要調用的是salt.pillar.get_pillar,對應文件是salt/pillar/__init__.py。
後期會針對pillar和grains的獲取詳細介紹下,或者看看saltstack中國用戶組的介紹。
tune_in的這個方法屬於salt.minion.Minion的。流程以下:
一、獲取pub和pull的地址,默認是文件,經過ipc通訊
二、綁定pub和pull
三、建立sub socket鏈接master的pub地址並保持長鏈接
四、執行死循環,觸發event
這裏只是大概的記錄下流程,寫的不怎麼詳細,還請你們海涵。
接下來的任務就是研究salt-minion去處理一個job的流程。
參考:
http://www.saltstack.cn/projects/cssug-kb/wiki/Salt-zeromq-01
http://www.saltstack.cn/projects/cssug-kb/wiki/Salt-pillar-01
http://devopstarter.info/yuan-ma-jie-du-saltstackyun-xing-ji-zhi-zhi-job-runtime/