使用Fabric 批量執行服務器任務


我們的服務器和虛擬機的環境配置都由puppet管理,但有時候需要臨時執行某些任務和操作,比如同時更換500台服務器的密碼、同時更新或者重啟500台虛擬機、在特定幾台服務器上添加或者一個用戶、上傳一個特定文件/腳本到1000台服務器等等。這些任務用Puppet可以做,但是不是最簡潔的辦法。我們需要一種工具能完成大量服務器上的批量操作,並且要簡單可編程,Fabric就是這樣一個基於Python的服務器批量管理庫/工具,Fabric使用ssh(通過paramiko庫)在多個服務器上批量執行任務,我們只需要用Python編寫這些任務腳本並指定要執行這些任務的服務器就可以了。

Fabric 依賴paramiko,所以需要安裝這兩個:

$ sudo pip install fabric
$ sudo pip install paramiko

編寫一個簡單的Fabric 例子,在1台服務器上打印系統信息(uname -s):

$ vi fabfile.py
#!/usr/bin/python

from fabric.api import run

def host_os():
    run('uname -s')

在vpsee.com 這台主機(host)上使用root 帳戶執行上面的任務host_os:

$ fab -H root@vpsee.com host_os
[root@vpsee.com] Executing task 'host_os'
[root@vpsee.com] run: uname -s
[root@vpsee.com] Login password for 'root': 
[root@vpsee.com] out: Linux

Done.
Disconnecting from root@vpsee.com... done.

來看一個更複雜點的例子,在多個服務器(grid00, grid02, …, grid05)上更換root 密碼(假設原密碼是root),注意加上@parallel,這樣任務是並行執行的,在大量服務器上會快很多:

#!/usr/bin/python
# -*- coding: utf-8 -*-
from fabric.api import *
import string
from random import choice
import socket
import paramiko

env.user = 'root'
env.password = 'root'
env.hosts = [ 'grid00', 'grid01', 'grid02', 'grid03', 'grid04', 'grid05']

@task
@parallel
def passwd(user, passwd=False):
    with settings(hide('running', 'stdout', 'stderr'), warn_only=True):
        if isup(env.host):
            if not passwd:
                passwd = genpass()
            sudo("echo -e '%s\n%s' | passwd %s" % (passwd, passwd, user))

def genpass(length=10):
    return ''.join(choice(string.ascii_letters + string.digits) for _ in range(length))

def isup(host):
    print 'connecting host: %s' % host
    timeout = socket.getdefaulttimeout()
    socket.setdefaulttimeout(1)
    up = True
    try:
        paramiko.Transport((host, 22))
    except Exception, e:
        up = False
        print '%s down, %s' % (host, e)
    finally:
        socket.setdefaulttimeout(timeout)
        return up

使用fab -l 查看我們剛編寫的fabfile.py 裡面的可用命令,這個命令就是那個函數名def passwd(user, passwd=False):

$ fab -l
Available commands:

    passwd

使用這個命令批量更換grid00-grid05 的root 密碼為test,passwd 傳遞參數的時候接冒號,並且用戶名和密碼參數用逗號隔開:

$ fab passwd:root,test
[grid00] Executing task 'passwd'
[grid01] Executing task 'passwd'
[grid02] Executing task 'passwd'
[grid03] Executing task 'passwd'
[grid04] Executing task 'passwd'
[grid05] Executing task 'passwd'
connecting host: grid05
connecting host: grid04
connecting host: grid02
connecting host: grid03
connecting host: grid01
connecting host: grid00

Done.

Fabric的強大之處在於可以用Python編寫各種任務(函數),這些任務可以指定到任何服務器上(通過ssh),非常適合管理大量服務器、批量處理任務。另外Fabric工作方式非常簡單容易理解,就是簡單的ssh而已,沒有內幕沒有架構,不像其他工具什麼客戶端服務器端、什麼中間代碼、什麼DSL領域專屬語言(嗯,說的就是puppet, chef) 。Fabric使用起來只需要懂點Python就可以了,不需要學命令、api、框架之類的。我們喜歡簡單 ​​、容易理解的工具。

留言

這個網誌中的熱門文章

Json概述以及python對json的相關操作

Docker容器日誌查看與清理

遠程控制管理工具ipmitool