自動化運維工具fabric使用教程

 

摘要:當須要同時管理許多服務器時,若是咱們一臺一臺登錄上去操做會顯得費時又費力。此時咱們能夠用fabric這個包提供的API來編寫python腳本完成服務器集羣的統一管理。python

 

核心原理:fabric爲主動ssh至主機執行指定操做,而不是在主機上裝agent接收指令。django

 

 

 

1、安裝api

pip install fabric3  ====>能夠把fabric看作是一個軟件,安裝後提供操做系統級命令「fab」,而後這個軟件開放一些API,能夠經過python去調用服務器

 

 

 

2fab經常使用參數(操做系統級命令「fab」的使用參數)多線程

格式:fab 選項參數運維

經常使用選項參數:ssh

-l:查看目標fab程序可用的函數。(須要和-f結合使用)異步

-f:告訴fab程序去讀取哪一個.py文件函數

-g:指定網關測試

-H:指定須要控制的目標主機,多個主機用「,」隔開

-P:以異步並行方式運行多主機任務,默認爲串行任務。(能夠理解爲多線程執行,默認爲一個線程)

-u:指定主機用戶名

-p:指定主機密碼

 

例:fab -p 密碼 -H 主機1,主機2 --'命令'

    fab -u root -p 密碼 -H '172.20.163.121,172.20.163.126' -- 'ifconfig'   ===>執行此命令後會輸出172.20.163.121172.20.163.126ifconfig信息

 

 

 

 

 

3fabfile腳本編寫

 

3.1、普通場景示例(適用於全部服務器的用戶名、密碼、業務類型都一致的狀況)(即:一個程序對應一個集羣):

 

from fabric.api import *  ===>導入fabric

 

# 全局屬性的設定()

# envfabric.api裏面的一個對象,能夠經過操縱它的各個屬性實現對自動化運維程序的全局參數配置,它的屬性包括目標主機ip、用戶、密碼、角色等

 

# 1env.host:存放目標主機的列表

env.hosts = ['192.168.1.1', '192.168.1.2']

 

# 2env.user:定義用戶名

env.user = 'root'

 

# 3env.port:定義端口

env.port = 22

 

# 4env.password:定義密碼

env.password = '123456'

 

 

@task    ===> 若是沒加@roles@hosts等裝飾器,一旦下面這個函數被執行,則全局env.hosts裏面全部的機器都會運行函數內的命令

def show_net():

    run('ifconfig')  ===>在遠程主機上執行「ifconfig」命令

 

 

if __name__ == '__main__':

    execute(show_net)   ===>若是不使用execute這個函數去執行show_net,則show_net只能用'root@HK:~# fab -f 文件名.py show_net'的方式執行。用了execute後就能夠用'python3 文件名.py'的方式執行了。

===>執行以上代碼後程序會ssh'192.168.1.1', '192.168.1.2'這兩臺機器上執行'ifconfig'命令並返回結果

 

 

 

3.2、將不一樣主機進行分組管理場景(適用於被管理服務器密碼、業務類型不相同的狀況):

 

from fabric.api import *  ===>導入fabric

 

env.user = 'root'   ====> 儘管下面針對每臺主機有用戶名信息了,這裏也須要定義一個全局user,不知爲啥(碰到須要不一樣用戶名的狀況下就歇菜了)

 

# 5env.passwords:定義多臺主機的用戶名、IP地址、端口、密碼(適用於:一堆服務器的密碼不都同樣的狀況)

env.passwords = {

    'root@172.20.163.121:22': '123456',   ====>測試發現去掉"root@"":22"後會報錯

    'root@172.20.163.126:22': '123456',

}

 

 

# 6env.gateway:定義網關  ====>適用於經過跳板機(堡壘機)登錄的方式

# env.gateway = '192.168.1.254'  ===>因沒有環境,因此先把它注掉,這裏只是說明有這個功能而已

 

 

# 7env.roledefs:定義角色分組(可按業務類型將主機進行分組管理)

env.roledefs = {

    'group1': ['172.20.163.121'],

    'group2': ['172.20.163.126']

}

 

@task

@roles('group1', 'group2')    ====>這個函數被執行時會在'group1', 'group2'這兩個組成員上生效

def show():

    run('uname -a')

 

 

@task   

@roles('group1')   ====>這個函數被執行時會在'group1'個組成員上生效

def show_net():

    run('ifconfig')

 

 

@task

@roles('group2')   ====>這個函數被執行時會在'group2'個組成員上生效

def show_mem():

    run('free -m')

 

 

if __name__ == '__main__':

    execute(show)       ===>執行show函數時group1group2兩個分組內的成員都會執行

    execute(show_net)   ===>執行show-net函數時只有group1分組內成員執行

    execute(show_mem) ===>執行show_mem函數時只有group2分組內成員執行

 

 

 

 

 

 

 

4、本地與遠程運維經常使用API(本地指運行fabric程序端,遠程指被ssh端)

 

# 1local:執行本地命令

語法:local('本地命令')

 

# 2lcd:切換到本地目錄

語法:lcd('本地目錄')

 

例:

def local_cmd():

    with lcd(r'C:\Users\Administrator'):   ===>切換到C:\Users\Administrator目錄(臨時性,執行完with這個總體後仍然處在原來的路徑)

        local('dir')                       ===>C:\Users\Administrator路徑下執行'dir'命令

    local('dir')              ===>執行完with這個總體後再次執行dir發現還處在沒有切換目錄前的路徑

 

 

 

 

 

# 3cd:切換遠程目錄

語法:cd'遠程目錄'

 

# 4run:執行遠程命令

語法:run'遠程命令'

 

例:

def remote_cmd():

    with cd(r'/'):                         ===>切換到/目錄(臨時性,執行完with體仍然處在原來的路徑)

        run('pwd')    ===>此時執行pwd輸出路徑爲'/'

    run('pwd')    ===>此時執行pwd輸出路徑爲'/root'

 

 

 

 

5put:上傳本地文件到遠程主機

語法:put('本地文件', '遠程目錄')

例:

def upload():

    put(r'C:\Users\Administrator\Desktop\django.txt', '/root/111.txt')

 

6get:從遠程主機下載文件到本地

語法:get('遠程文件', '本地目錄')

例:

def download():

    get('/root/get-pip.py', r'C:\Users\Administrator\Desktop\iiii.py')

 

 

 

 

 

 

 

7、異常處理和文件校驗

from fabric.api import *

from fabric.contrib.console import confirm

from fabric.colors import *    ====>文字顏色庫,包含white()yellow()red()blue()green()cyan()magenta()等函數,將字符串丟進去便可爲字符串上色。例:print(yellow('abc')) ===>此時將輸出黃色的'abc'

 

def abnormal():

    # 異常處理

    with settings(warn_only=True):

        result = put(r'./222.txt', '/root/abc.txt')

    if result.failed and not confirm("put file failed,Continue[Y/N]?"):   ===>若是路徑錯誤result.failed將爲真,若是result.failed爲真後彈出交互界面問用戶是否要繼續,若是輸入N,則not 0爲真,則執行abort("Aborting file put task ")

        abort("Aborting file put task ")

 

    # 文件校驗

    with settings(warn_only=True):

        local_md5 = local(r'md5sum ./222.txt', capture=True).split(" ")[0]   # capture做用:這個開啓後輸出結果將再也不打印至屏幕,而是將結果賦給local_md5

        remote_md5 = run('md5sum /root/abc.txt').split(" ")[0]               # run函數不用capture參數,默認既會打印至屏幕,也會賦值給remote_md5

    if local_md5 == remote_md5:

        print(green('校驗經過'))

    else:

        print(red('校驗失敗'))

 

 

 

 

 

confirm說明:

from fabric.contrib.console import confirm

 

a = confirm('是否要繼續?')   ====>confirm將彈出交互界面:'是否要繼續? [Y/n]'    用戶可輸入YN

print(a)    =====>若是用戶輸入的是Y,則此處打印True。若是用戶輸入的是N,則此處打印False

 

 

 

 

 

 

五、裝飾器說明:

 

fab調用裝飾器:@task

若是函數前面加了這個裝飾器就能夠用操做系統級別命令fab直接調用這個函數。若是沒加則沒法用fab直接調用。例:

@task

def remote_cmd():

    run('ifconfig')

root@HK:~# fab -f ssh.py remote_cmd   ====>若是加了@task則能夠直接這麼用,若是沒加則不能這麼用

 

並行裝飾器:@parallel

角色裝飾器:@roles(分組名)

@task

@parallel    ====>當有多個主機要執行下面函數任務時,加上這個裝飾器就能夠起多個進程並行處理了。

@roles('group1', 'group2')    ====>多個分組須要執行下面函數

def remote_cmd():

    run('ifconfig')

 

主機裝飾器:@hosts(主機1,主機2

@task

@parallel    ====>當有多個主機要執行下面函數任務時,加上這個裝飾器就能夠起多個進程並行處理了。

@roles('172.20.163.100', '172.20.163.101')    ====>除了分組方法外,也能夠手工指定哪臺主機要執行下面函數。

def remote_cmd():

    run('ifconfig')

相關文章
相關標籤/搜索