更快的获取salt-minion连接状态

Python 2017-05-19

起步

使用 SaltStack 架构,有时需要查看master与minion之间是否能联通.一般采用

salt '*' test.ping

对所有客户机进行检测.当客户机数量达到1000+台后,这个命令会很慢,耗时1分钟多.

更快的方法

在wheel模块中有个minios的方法:

Wheel system wrapper for connected minions

salt.wheel.minions.connected()

List all connected minions on a salt-master

在封装的saltapi里面调用:

connected_list = saltapi.wheel("https://127.0.0.1:4507", fun='minions.connected')

耗时只要5-6秒.

原因

salt-master与每个salt-minion都会有个长连接,他们之间也会发心跳包. test.ping 的方式会下发命令到每个客户机,而 minions.connected 则是查看长连接在不在,因此速度快.

具体看代码, minions.connected 代码在 salt/utils/wheel.py 中:

# -*- coding: utf-8 -*-
'''
Wheel system wrapper for connected minions
'''

# Import Python libs
from __future__ import absolute_import

# Import Salt libs
from salt.utils.cache import CacheCli
import salt.config
import salt.utils.minions

def connected():
    '''
    List all connected minions on a salt-master
    '''
    opts = salt.config.master_config(__opts__['conf_file'])

    if opts.get('con_cache'):
        cache_cli = CacheCli(opts)
        minions = cache_cli.get_cached()
    else:
        minions = list(salt.utils.minions.CkMinions(opts).connected_ids())
    return minions

可以看出它会优先有 get_cached() 缓存中获取. connected_ids()的代码在 salt/utils/minions.py 中(有简化):

def connected_ids(self, subset=None, show_ipv4=False, include_localhost=False):
    '''
    Return a set of all connected minion ids, optionally within a subset
    '''
    minions = set()
    if self.opts.get('minion_data_cache', False):
        search = self.cache.ls('minions')
        addrs = salt.utils.network.local_port_tcp(int(self.opts['publish_port']))
        if '127.0.0.1' in addrs or '0.0.0.0' in addrs:
            # Add in possible ip addresses of a locally connected minion
            addrs.discard('127.0.0.1')
            addrs.discard('0.0.0.0')
            addrs.update(set(salt.utils.network.ip_addrs(include_loopback=include_localhost)))

        for id_ in search:
            try:
                mdata = self.cache.fetch('minions/{0}'.format(id_), 'data')
            except SaltCacheError:
                continue
            if mdata is None:
                continue
            minions.add(id_)

    return minions

根据salt-key查看是否在长连接池中是否有数据 self.cache.fetch('minions/{0}'.format(id_), 'data') ,没有通过下发命令的方式,省了很多时间,而且又准确.


本文由 hongweipeng 创作,采用 知识共享署名 3.0,可自由转载、引用,但需署名作者且注明文章出处。

赏个馒头吧