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


 

摘要:當需要同時管理許多服務器時,如果我們一台一台登陸上去操作會顯得費時又費力。此時我們可以用fabric這個包提供的API來編寫python腳本完成服務器集群的統一管理。

 

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

 

 

 

1、安裝

pip install fabric3  ====>可以把fabric看做是一個軟件,安裝后提供操作系統級命令“fab”,然后這個軟件開放一些API,可以通過python去調用

 

 

 

2fab常用參數(操作系統級命令“fab”的使用參數)

格式:fab 選項參數

常用選項參數:

-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”命令(默認情況下fabric會調用/bin/bash來執行該命令,這時如果你連接的是交換機等CLI命令的設備就會出錯)

 注意:run('show ip route', shell=False) ===>默認情況下fabric會調用/bin/bash來執行該命令,這時如果你連接的是交換機等CLI命令的設備就會出錯,此時將shell參數設為False就可以了

 

 

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

 

# 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

 

 

 

 

 

 

5、裝飾器說明:

 

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')

 

 

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM