編程學習網 > 編程語言 > Python > Python遠程部署工具Fabric詳解教程
2023
07-26

Python遠程部署工具Fabric詳解教程

Fabric是Python的一個模塊,基于SSH提供了豐富的交互接口,可以用來在本地或遠程機器上自動化的執行Shell命令,非常適合用來做應用的遠程部署及系統維護。


Fabric底層基于paramiko(paramiko是用于ssh連接的庫)。

應用
安裝Fabric
$ pip install fabric
小試牛刀
Fabric默認的腳本文件是fabfile.py,創建該文件并定義以hello函數:

def hello():
    print("Hello Fabric!")
可以使用參數-l來列出當前fabfile.py中定義了哪些任務,然后在fabfile.py目錄下執行命令可以看到輸出結果:

$ fab -l
Available commands:

    hello
    
$ fab hello
Hello Fabric!

Done.
fabfile.py中每個函數代表一個任務,任務名即函數名。fab命令用來執行fabfile.py中定義的任務,它必須顯示的指定任務名。

任務也可以帶參數,比如我們將hello函數改為:

def hello(name, value):
    print("Hello Fabric! %s %s." % (name, value))
此時執行hello任務時需要傳入參數:

$ fab hello:name=Year,value=2017
Fabric默認執行的腳本是fabfile.py,如果要換腳本文件需要使用-f指定。比如我們將hello任務放到script.py中就要執行:

$ fab -f script.py hello:name=Year,value=2017
執行本地命令
fabfile.py內容如下:

#-*- coding:utf-8 -*-
from fabric.api import local

def taskA():
    local('touch fab.out && echo "fabric" >> fab.out')

def taskB():
    # capture參數可以捕獲標準輸出存到變量,默認為False
    output = local('echo "Hello World."', capture=True)
    print(output)
執行任務:

$ fab taskA taskB
執行遠程命令
Fabric真正強大在于可以很方便的執行遠程機器上的Shell命令,它基于SSH實現。

#-*- coding:utf-8 -*-
from fabric.api import run, env

# env被稱為環境字典,用來配置一些運行環境相關的信息
env.hosts = ['192.168.1.100', '192.168.1.101']
env.user = 'user'
env.password = 'passwd'

def taskA():
    run('cd /usr/local/webserver/php && ls -l')
    run('sudo /usr/local/webserver/nginx/sbin/nginx -t')
env.hosts是設置機器列表的,也可以把用戶直接寫到hosts里:

env.hosts = ['user@192.168.1.100', 'user@192.168.1.101']
如果代碼中沒有設置env.hosts,也可以在執行任務時通過-H參數進行指定:

$ fab -H 192.168.1.100 taskA
環境字典fabric.state.env是作為全局單例實現的,為方便使用也包含在fabric.api中。env中的鍵通常也被稱為環境變量。

幾個常用的環境變量如下:

user:可以通過設置env.user來指定Fabric建立SSH連接時使用的用戶名(默認使用本地用戶名)。
password:用來顯式設置默認連接或者在需要的時候提供sudo密碼。如果沒有設置密碼或密碼錯誤,Fabric將會提示你輸入。
passwords:密碼字典,針對不同的機器設置密碼。
warn_only:布爾值,用來設置Fabric是否在檢測到遠程錯誤時退出。
hosts:全局主機列表。
roledefs:定義角色名和主機列表的映射字典。
如果對于不同的服務器想執行不同的任務,上面的程序就做不到了,我們需要對服務器定義角色:

#-*- coding:utf-8 -*-
from fabric.api import env, roles, run, execute, cd

env.roledefs = {
    'dev': ['user1@10.216.224.65', 'user2@10.216.224.66'],
    'online': ['user3@45.33.108.82']
}

# host strings必須由username@host:port三部分構成,缺一不可,否則運行時還是會要求輸入密碼
env.passwords = {
    'user1@10.216.224.65:22': 'passwd1',
    'user2@10.216.224.66:22': 'passwd2',
    'user3@45.33.108.82:22': 'passwd3'
}

@roles('dev')
def taskA():
    with cd('/usr/local/webserver'):
        run('pwd')

@roles('online')
def taskB():
    run('pwd')

def task():
    execute(taskA)
    execute(taskB)
然后執行task任務即可:

$ fab task
Fabric會在dev機器上執行taskA任務,然后在online機器上執行taskB任務。@roles裝飾器指定了它所裝飾的任務會被哪個角色的服務器執行。

SSH自動登陸
上面的例子都是將登陸密碼寫到腳本文件里的,這樣做不安全,推薦的方法是設置SSH KEY自動登陸。登陸本地機器生成KEY:

$ ssh-keygen -t rsa -f ~/.ssh/id_rsa_fabric
生成密鑰對之后將公鑰添加到遠程服務器的~/.ssh/authorized_keys文件中,就可以實現自動登陸了。

#-*- coding:utf-8 -*-
from fabric.api import env, roles, run, execute, cd

env.hosts = ['10.216.224.65', '10.216.224.66']
env.user = 'user'
env.key_filename = '~/.ssh/id_rsa_fabric'

def taskA():
    with cd('/usr/local/webserver'):
        run('pwd')
authorized_keys文件權限只所有者可寫,其他用戶均無寫權限,否則sshd將認為不安全不允許使用該文件導致還需要輸入密碼認證。

上下文管理器
Fabric的上下文管理器是一系列與Python的with語句配合使用的方法,它可以在with語句塊內設置當前工作環境的上下文。

#-*- coding:utf-8 -*-
from fabric.api import env, lcd, local, cd, path, settings, shell_env, prefix, sudo, run

env.hosts = ['10.216.224.66']
env.user = 'user'
env.key_filename = '~/.ssh/id_rsa_fabric'

def task():
    # 設置本地工作目錄
    with lcd('/usr/local/webserver'):
        local('touch local.out')

    # 設置遠程機器的工作目錄
    # sudo功能類似run方法,以超級用戶權限執行遠程命令
    with cd('/usr/local/webserver'):
        sudo('touch remote.out')

    # 添加遠程機器的path路徑
    # 出了with語句path又回到原來的值
    with path('/usr/local/webserver'):
        run('echo $PATH')
    run('echo $PATH')

    # 設置Fabric環境變量參數
    # fabric.api.env
    # warn_only設置為True,遇到錯誤不會退出
    with settings(warn_only=True):
        run('echo $USER')

    # shell_env可以用來臨時設置遠程和本機上的Shell環境變量
    with shell_env(JAVA_HOME='/opt/java'):
        run('echo $JAVA_HOME')
        local('echo $JAVA_HOME')

    # 設置命令執行前綴,等同于 run('echo Hi && pwd')
    with prefix('echo Hi'):
        run('pwd')
        local('pwd')
錯誤處理
默認情況下,Fabric在任務遇到錯誤時就會退出,如果我們希望捕獲這個錯誤而不是退出任務的話,就要開啟warn_only參數。在上面介紹settings()上下文管理器時,我們已經看到了臨時開啟warn_only的方法了,如果要全局開啟,有兩個方法:

在執行fab時加上-w參數
$ fab -w task
設置env.warn_only環境參數為True
#-*- coding:utf-8 -*-
from fabric.api import env

env.warn_only = True
現在遇到錯誤時,控制臺會打出一個警告信息,然后繼續執行后續任務。那我們怎么捕獲錯誤并處理呢?像local/run/sudo/get/put等函數都有返回值,當返回值的succeeded屬性為True時,說明執行成功,反之就是失??;也可以檢查返回值的failed屬性,為True表示執行失敗,有錯誤發生。

#-*- coding:utf-8 -*-
from fabric.api import env, local, cd, put

env.hosts = ['10.216.224.66']
env.user = 'user'
env.key_filename = '~/.ssh/id_rsa_fabric'
env.warn_only=True

def task():
    with cd('/data/server'):
        local('touch /data/server/README.md')
        upload = put('/data/server/README.md', 'README.md')
        if upload.failed:
            put('/data/server/README.md', 'README.md', use_sudo=True)
并行執行
Fabric在多臺機器上執行任務時默認情況下是串行的。Fabric支持在多臺服務器上并行執行任務,并行可以有效的加快執行速度。開啟并行執行有如下兩個方法:

在執行fab命令時加上-w參數
$ fab -P task
設置env.parallel環境參數為True
#-*- coding:utf-8 -*-
from fabric.api import env
env.parallel = True
以上是對任務并行做一個全局控制。如果只想對某一個任務做并行的話,我們可以在任務函數上加上@parallel裝飾器,這樣即便全局并行未開啟,被@parallel裝飾的任務也會并行執行:

#-*- coding:utf-8 -*-
from fabric.api import env, run, parallel

env.hosts = ['10.216.224.65', '10.216.224.66']
env.user = 'user'
env.key_filename = '~/.ssh/id_rsa_fabric'

@parallel
def taskA():
    run('echo "parallel"')

def taskB():
    run('echo "serial"')
假如全局并行已開啟,我們想讓某個任務串行執行,我們可以在任務函數上加上@serial裝飾器,這樣即便并行已開啟,被@serial裝飾的任務也會串行執行:

#-*- coding:utf-8 -*-
from fabric.api import env, run, serial

env.hosts = ['10.216.224.65', '10.216.224.66']
env.user = 'user'
env.key_filename = '~/.ssh/id_rsa_fabric'
env.parallel = True

def taskA():
    run('echo "parallel"')

@serial
def taskB():
    run('echo "serial"')

Fabric常規用法這里就基本介紹完了,詳細的可以參考官方文檔。

以上就是Python遠程部署工具Fabric詳解教程的詳細內容,想要了解更多Python教程歡迎持續關注編程學習網。

掃碼二維碼 獲取免費視頻學習資料

Python編程學習

查 看2022高級編程視頻教程免費獲取