1.在scripts.py文件中salt_minion()函数如下代码:

minion = salt.cli.daemons.Minion()
minion.start()

2.在daemons.py文件中类Minion的start执行如下代码

class Minion(parsers.MinionOptionParser, DaemonsMixin)
    ....


1.解析命令行参数及配置文件

2.执行start方法前先执行prepare()方法,检查启动的必须项是否配置,并且必须的环境目录是否存在


self.minion = salt.minion.Minion(self.config)
self.minion.tune_in()

3.在minion.py文件中的tune_in()方法中执行如下代码

self.sync_connect_master()

4.在minion.py中sync_connect_master()方法如下

sync_connect_master()方法会一直阻塞,直到连接master为止
代码如下:
self._connect_master_future = self.connect_master()

该方法调用self.connect_master()方法


5.connect_master方法如下:

master, self.pub_channel = yield self.eval_master(self.opts, self.timeout, self.safe)
yield self._post_master_init(master)

6.self.eval_master()方法如下:

pub_channel = salt.transport.client.AsyncPubChannel.factory(self.opts, **factory_kwargs)
yield pub_channel.connect()

#AsyncPubChannel类用于生成一个类来创建到master的Publisher的一个订阅通道

该类的factory方法会返回return salt.transport.zeromq.AsyncZeroMQPubChannel(opts, **kwargs)

salt.transport.zeromq.AsyncZeroMQPubChannel类在实例化时操作如下:

self.auth = salt.crypt.AsyncAuth(self.opts, io_loop=self.io_loop)
self.serial = salt.payload.Serial(self.opts)
self.context = zmq.Context()
self._socket = self.context.socket(zmq.SUB)


最终先调用AsyncZeroMQPubChannel.connect()方法

connect方法中的代码如下:
if not self.auth.authenticated:
    yield self.auth.authenticate()

self.publish_port = self.auth.creds['publish_port']
self._socket.connect(self.master_pub)
#可以看出在连接之前的操作是进行认证操作


7.salt-minion的认证流程如下:

self.pub_path = os.path.join(self.opts['pki_dir'], 'minion.pub')
self.rsa_path = os.path.join(self.opts['pki_dir'], 'minion.pem')
self.mpub = 'minion_master.pub'

#先检查minion的公钥和私钥文件是否存在,如果不存在,便创建;同时指定保存master的公钥的文件名
是minion_master.pub



channel = salt.transport.client.ReqChannel.factory(self.opts, crypt='clear')
creds = self.sign_in(channel=channel)

向master发送签名认证
auth['master_uri'] = tcp://192.168.56.101:4506

认证时是向master的4506端口发送消息
sign_in_payload = self.minion_sign_in_payload()

sign_in_payload是发送的具体消息内容及格式
minion_sign_in_payload()方法生成了向master发送认证消息的内容
代码如下:
payload = {}
payload['cmd'] = '_auth'
payload['id'] = self.opts['id']

序列化前的包:
message = {'load': {'cmd': '_auth', 'id': 'zhu1', 'pub': '-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqicJ8L2vmjeEpSfi1TEE\nZzdPo5Ibgo5a+EvQtMqzm/elKhWjNSp82PE9Fl5BuGgexk9P0+kwpAEws6vWNgyG\nJuTow+PYhVMWU6B0P+pMcdm7YxcqKczvHXmH6ugzLt1uQmwcW0RjL2POGxgLyprL\nM1isdX/bSLnMabtAfsORv7q7BmsJaXIxtdFwH8yDuJRvluia448OjHU4ugQr+yWj\nfRuqOzR5UFk0K4CivPt6E/E7DdxJV4j1OSsnGXi5XPLoJ7dACQne6/2xOlSkb6tZ\neQBC/HdfWTflD4LYSlrsVlQTl1+DDmYHQL7eCYg0zC34xi+DC+Qd0MJ1DOPiRwWq\nswIDAQAB\n-----END PUBLIC KEY-----'}, 'enc': 'clear'}

序列化后:
'\x82\xa4load\x83\xa3cmd\xa5_auth\xa2id\xa4zhu1\xa3pub\xda\x01\xc2-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqicJ8L2vmjeEpSfi1TEE\nZzdPo5Ibgo5a+EvQtMqzm/elKhWjNSp82PE9Fl5BuGgexk9P0+kwpAEws6vWNgyG\nJuTow+PYhVMWU6B0P+pMcdm7YxcqKczvHXmH6ugzLt1uQmwcW0RjL2POGxgLyprL\nM1isdX/bSLnMabtAfsORv7q7BmsJaXIxtdFwH8yDuJRvluia448OjHU4ugQr+yWj\nfRuqOzR5UFk0K4CivPt6E/E7DdxJV4j1OSsnGXi5XPLoJ7dACQne6/2xOlSkb6tZ\neQBC/HdfWTflD4LYSlrsVlQTl1+DDmYHQL7eCYg0zC34xi+DC+Qd0MJ1DOPiRwWq\nswIDAQAB\n-----END PUBLIC KEY-----\xa3enc\xa5clear'

#master收到该包后
在zeromq.py文件ZeroMQReqServerChannel类的handle_message方法
if payload['enc'] == 'clear' and payload.get('load', {}).get('cmd') == '_auth':
    stream.send(self.serial.dumps(self._auth(payload['load'])))


具体处理是在self._auth(payload['load'])中

salt/transport/mixins/auth.py 文件中定义_auth方法

8. _auth方法具体执行如下:

1.salt.utils.verify.valid_id(self.opts, load['id'])  #验证minion发送过来的id的有效性,如果
          id的名字正好是/etc/salt/pki/master下面的子目录则出错
2.是否超过配置文件中设置的最大连接数


/etc/salt/pki/master/minions   #master存储minion的公钥路径

3.验证id 是否在拒绝的范围内
4.验证接收的id是否已经存在,如果存在便比较公钥是否一致
...................
..................

返回给minion端的信息:
{'publish_port': 4505, 'pub_key': '-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArz3tnfbciMqsQmdKh4WP\nTxAuWHCDXle3aeQO0nawL0XO4b6VQr3Wjd6Ac6cDdnuEKEOO2Oy95hP9U7+WUvx+\nbtpf/bFPNVKPQC5lPW0eY3kkL3yiZsohWvYLYHpymoW6dTIeXcSkLqCo+FSDyiou\n4CgqVUM290zGK7Kq8Z/b497IUyf6ARvprhgTv3u6mk7fC5BUEm7MlONLyZXSiuOL\nsKeqEjEG7QonCvYJ46Onfz2jBCxr0IY/jbaunTqHmV0jW33oS9JPIh8z6KpFxhDX\ng3SX/SumGhJo3Q3JiHSmPStjSdiU8+mIM3oYzTDMHxTXfDA6Tg2+tePa3oqZd4+l\n4QIDAQAB\n-----END PUBLIC KEY-----', 'enc': 'pub', 'sig': '}t\xf2S\xd4 \x85R:\xd5\x06)\xae\x93<\xfc\xb3\xa1"\xf0\xb8\xa8\xa9\xb6\xff\xe4\x96\xadb\xa6\xe1?Q?S\xc0\xda\x1f\xbe\xe8\'\x96\x1c\x9eT\x14]\xc2K\xbb\xbb#jR\xacU\xa9\xbbr\xad>^\t\'\x995%\x1f\xcc\x97dT\xc9Vm\x80\x15\xe2\xd4\x96NY\xaf4\xb4\x85\xcb\x0b/\x15\x0b\x1c\x82R\xa5Q\x99\xdb`7\'"\xc3\x8569`k\xf3_\xc6)\xbe|\x89r\xe0@\x02\x81\xdd\xea1\xee\xdf&\xfb\x1bH\x0el\x82\xa2\x81\x9e\xa1\xca\xdf\x81\x9f"}\x08\xc2\x8aeGLU\xcc-Utb\xdb\x03\x16\x18\xbe\x02\x17u5f\xa07\xb8\x8c\xe1\x7fC:\xe7\x84\xdb\xb9;Uh\r3\xdd\xdb\x05\x95\x0c\x9dV/\xb7\xbd\x99\\\x93+\x86\xe9[Hx\xd8\xbb\xfd\xe9\x93\x81\x96\xee\xb5\x9b$9;&@\xf7\xf3s\xd1\x1f\xff\x1dT\xa4o"%T\xa9\xdcBtw\xf5\xf9b\x1f2vW\xae\x9f\xe0\xcb\xae\x882\x85\xd7\'\xa2\x87+\xcc\xbe}', 'aes': '\x07\xa7\xa3\xba*\xc9\x8b\xe8]S\x8fa\x8e\xf0W{Y\xc3h6\xab\xe3dU\xe9X\xfe\x92\xda\x1c\xe07\xdf\xd9=K 1\x87\x03\x05?g\x7f\x03O1\xd7\x0f\xeb\x148\x08I\xc6z\x12Um\t\x0b\xa4\xa5r\xd5\xfb\x85<163\xeaYh\x1e\x07\x07\x1b\xe5#\xba\xf5^[o\x8b\x8a/\xd1\x91\x1e\x03\x95\xd8\x90\'\xe1\x88\xf4\xcd\xfb\xbf\tc(R\xce\x07\xbc\xd9\xe6\xafb\xa4\xf7\x04.\x85\x19\xfb7\t?\xedK=al\xa2\xfd\x80\xae\x08\x15\xf2\x069!E\xdb\x18\x06\xbd\x12\x10\x13g\x103$i\x86[\xecr\x90\xd5\xbd\xd3\xccsu\\\xa8\x86\xc2\xf5b\x0b\x7f\xc3;d\xb4%\xde\xb8\xffSG5\x90\x84\xefKV\xb2{\x02\xa6(Vj\xe6\x9fyS\xff\xf9\x97\xe5f\x9c\xc0\x87\xe8\xd0\r>\x17>\xe9`j\xd3\xa4\x8f\xeb\xa9\xed\x7f@\x15\xf6\x18.\xd5=\xf3\xa6P\xcd0\x17\xf4\xdb\x8c@Z}\x84pg\xaeH\xec\xc4\xcd\xa5!\xef"\xac3y\xd0'}
('salt/auth', {'_stamp': '2017-01-06T09:14:08.763899', 'act': 'accept', 'id': 'zhu1', 'pub': '-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqicJ8L2vmjeEpSfi1TEE\nZzdPo5Ibgo5a+EvQtMqzm/elKhWjNSp82PE9Fl5BuGgexk9P0+kwpAEws6vWNgyG\nJuTow+PYhVMWU6B0P+pMcdm7YxcqKczvHXmH6ugzLt1uQmwcW0RjL2POGxgLyprL\nM1isdX/bSLnMabtAfsORv7q7BmsJaXIxtdFwH8yDuJRvluia448OjHU4ugQr+yWj\nfRuqOzR5UFk0K4CivPt6E/E7DdxJV4j1OSsnGXi5XPLoJ7dACQne6/2xOlSkb6tZ\neQBC/HdfWTflD4LYSlrsVlQTl1+DDmYHQL7eCYg0zC34xi+DC+Qd0MJ1DOPiRwWq\nswIDAQAB\n-----END PUBLIC KEY-----', 'result': True})