python腳本實現集羣檢測和管理

python腳本實現集羣檢測和管理

  場景是這樣的:一個生產機房,會有不少的測試機器和生產機器(也就是30臺左右吧),因爲管理較爲混亂致使了哪臺機器有人用、哪臺機器沒人用都不清楚,從而產生了一個想法--利用一臺機器來管理全部的機器,記錄設備責任人、設備使用狀態等等信息....那麼,爲何選擇python,python足夠簡單而且擁有豐富的第三方庫的支持。前端

最初的想法

  因爲剛參加工做不久,對這些東西也都沒有接觸過,輪崗到某個部門須要作出點東西來(項目是什麼還沒狀況,就要作出東西來,沒辦法硬着頭皮想點子吧)。。。python

  本想作一個簡單點的自動化測試的工具,但這項目的測試方法和測試用例暫時不能使用這種通用的測試手段(輸入和輸出都肯定不了),從而做罷...mysql

  

  

  那麼作點什麼東西,常常發現同事們問208誰用的?201誰用的?那IP是個人!!!你是否是把我得網線給拔掉了?242那機器究竟是哪臺?web

  忽然間,春天來了,是否是能夠作一個系統用來檢測IP和記錄設備的使用人,甚至能夠按須要在某臺設備上運行一個腳本或命令?把這個矮矬窮的想法和leader溝經過後,確承認以作,那麼就開始吧!!!ajax

設計思想

  該系統的大概思想:sql

  1.  要得到全部服務器的各類信息,須要在任意一臺服務器上部署一個agent做爲信息獲取的節點,定時向管理服務器節點發送服務器信息數據。shell

  2.  server做爲綜合管理節點,接收並儲存agent提交的信息。數據庫

  3.  爲了方便使用,採用web頁面的形式作展現。bootstrap

  

開發工具選擇

  1. 開發語言:python前端框架

    之因此選擇python,簡單,第三方庫豐富,不用造輪子

  2. 數據庫:mysql

    簡單、易用

  3. webpy:web框架

    入門簡單、部署方便

  4. bootstrap:前端框架

    不要關心太多前端問題

  5. paramiko:python庫,遵循SSH2協議,支持以加密和認證的方式,進行遠程服務器的鏈接

    經過SSH方式鏈接agent服務器:遠程運行命令、傳輸文件

  6. scapy: python庫,可用來發送、嗅探、解析和僞造網絡數據包,這裏用來掃描IP

  7. MySQLdb: 鏈接mysql

  8. shell 和 python腳本接口: 爲其餘人提供shell腳本的接口

經驗分享

  1. 前端對我來講是新東西,歷來沒弄過,頁面的動畫效果,腳本運行時的過渡都是須要考慮的,開始考慮利用倒計時,可是這個時間是不可控的,後來採用ajax來處理這個問題

  2. agent要自動部署到每臺機器,並能夠經過server來控制刷新時間

  3. 創建一個可擴展的表是很是重要的,並且一些重要的信息須要寫入磁盤,在數據庫失效的狀況下,能夠從磁盤獲取數據

  4. 數據庫的鏈接,若是長時間沒有操做的話會超時,要考慮到

  ... ...

  項目結構--webpy

    1. website.py爲webpy的主程序,設置了url映射

    2. model.py爲webpy的url映射類,處理請求和返回

    3. static中存放靜態資源

    4. scripts用來存放處理的腳本,這裏起的名字有些問題 

    

 

  鏈接數據庫

    使用MyQSLdb鏈接mysql,在這裏我沒有使用webpy提供的數據庫接口,而是本身封裝了一套  

  ssh遠程鏈接服務器  

    paramiko實現ssh鏈接、與數據傳輸、執行命令和腳本

def executecmd(cmd, host, port=22, user='root', passwd='root'):
    try:
        s = paramiko.SSHClient()
        s.set_missing_host_key_policy(paramiko.AutoAddPolicy())
    s.connect(host, port, user, passwd, timeout = 10)
    except Exception as e:
        s.close()
        print e
        print 'connet error...'
        return 

    try:
        stdin,stdout,stderr=s.exec_command(cmd)
        #print 'Host: %s......' %host
        res = stdout.readlines()
    except Exception as e:
        print 'exec_commmand error...'
    s.close()
    return res

def executefile(file, host, port=22, user='root', passwd='root'):
    try:
        s = paramiko.SSHClient()
        s.set_missing_host_key_policy(paramiko.AutoAddPolicy())
    s.connect(host, port, user, passwd,timeout=5)
        t = paramiko.Transport((host, port))
        t.connect(username=user, password=passwd)
        sftp =paramiko.SFTPClient.from_transport(t)
    except Exception as e:
        s.close()
        print e
        print 'connet error...'
        return ''

    try:
        filename = os.path.basename(file)
        if filename.find('.sh') >= 0:
            sftp.put(path+'/'+file, '/tmp/tmp_test.sh')
            stdin,stdout,stderr=s.exec_command('sh /tmp/tmp_test.sh 2>/dev/null', timeout=5)
        else:
            sftp.put(path+'/'+file, '/tmp/tmp_test.py')
            stdin,stdout,stderr=s.exec_command('python /tmp/tmp_test.py', timeout=5)
        #stdin,stdout,stderr=s.exec_command('rm -rf /tmp/tmp_test* 2>/dev/null') 
        res = stdout.readlines()
        s.exec_command('rm -rf /tmp/tmp_test* 2>/dev/null') 
    except Exception as e:
        s.exec_command('rm -rf /tmp/tmp_test* 2>/dev/null') 
        print 'timeout error...'
        print e
        return ''
    return res
View Code

  IP掃描

    使用scapy進行IP掃描

def pro(ip, cc, handle):
    global dict
    dst = ip + str(cc)
    packet = IP(dst=dst, ttl=20)/ICMP()
    reply = sr1(packet, timeout=TIMEOUT)
    if reply:
        print reply.src,' is online'
        tmp = [1, reply.src]
        handle.write(reply.src + '\n')
        #handle.write(reply.src+" is online"+"\n")
 
def main():
    threads=[]
    ip = '192.168.1.1'
    s = 2
    e = 254
    f=open('ip.log','w')
    for i in range(s, e):
        t=threading.Thread(target=pro,args=(ip,i,f))
        threads.append(t)
    print "main Thread begins at ",ctime()
    for t in threads :
        t.start()
    for t in threads :
        t.join()
    print "main Thread ends at ",ctime()
View Code

  批量添加ssh-key

home_dir = '/home/xx'
id_rsa_pub = '%s/.ssh/id_rsa.pub' %home_dir

if not  id_rsa_pub:
    print 'id_rsa.pub Does not exist!'
    sys.exit(0)

file_object = open('%s/.ssh/config' %home_dir ,'w')
file_object.write('StrictHostKeyChecking no\n')
file_object.write('UserKnownHostsFile /dev/null')
file_object.close()


def up_key(host,port,user,passwd):
    try:
        s = paramiko.SSHClient()
    s.set_missing_host_key_policy(paramiko.AutoAddPolicy())
    s.connect(host, port, user, passwd)

        t = paramiko.Transport((host, port))
        t.connect(username=user, password=passwd, timeout=3)
        sftp =paramiko.SFTPClient.from_transport(t)

        print 'create Host:%s .ssh dir......' %host
        stdin,stdout,stderr=s.exec_command('mkdir ~/.ssh/')
        print 'upload id_rsa.pub to Host:%s......' %host
        sftp.put(id_rsa_pub, "/tmp/temp_key")
        stdin,stdout,stderr=s.exec_command('cat /tmp/temp_key >> ~/.ssh/authorized_keys && rm -rf /tmp/temp_key')
        print 'host:%s@%s auth success!\n' %(user, host)
        s.close()
        t.close()
    except Exception, e:
        #import traceback
        #traceback.print_exc()
        print 'connect error...'
        print 'delete ' + host  + ' from database...'
        delip(host)
        #delete from mysql****
        try:
            s.close()
            t.close()
        except:
            pass
View Code

 

知識共享許可協議
本做品採用 知識共享署名-非商業性使用-相同方式共享 3.0 未本地化版本許可協議進行許可。歡迎轉載,請註明出處:
轉載自: cococo點點 http://www.cnblogs.com/coder2012
相關文章
相關標籤/搜索