Python遠程部署利器Fabric詳解-轉載

  • 2019 年 11 月 24 日
  • 筆記

Fabric是一個Python的庫,它提供了豐富的同SSH交互的接口,可以用來在本地或遠程機器上自動化、流水化地執行Shell命令。因此它非常適合用來做應用的遠程部署及系統維護。其上手也極其簡單,你需要的只是懂得基本的Shell命令。本文將為大家詳細介紹Fabric的使用。

內容索引

安裝Fabric

首先Python的版本必須是2.7以上,可以通過下面的命令查看當前Python的版本:

1

$ python –V

Fabric的官網是www.fabfile.org,源碼託管在Github上。你可以clone源碼到本地,然後通過下面的命令來安裝。

1

$ python setup.py develop

在執行源碼安裝前,你必須先將Fabric的依賴包Paramiko裝上。所以,個人還是推薦使用pip安裝,只需一條命令即可:

1

$ pip install fabric

第一個例子

萬事從Hello World開始,我們創建一個」fabfile.py」文件,然後寫個hello函數:

Python

1 2

def hello():     print 「Hello Fabric!」

現在,讓我們在」fabfile.py」的目錄下執行命令:

1

$ fab hello

你可以在終端看到」Hello Fabric!」字樣。

簡單解釋下,」fabfile.py」文件中每個函數就是一個任務,任務名即函數名,上例中是」hello」。」fab」命令就是用來執行」fabfile.py」中定義的任務,它必須顯式地指定任務名。你可以使用參數」-l」來列出當前」fabfile.py」文件中定義了哪些任務:

1

$ fab –l

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

Python

1 2

def hello(name, value):     print 「Hello Fabric! %s=%s」 % (name,value)

此時執行hello任務時,就要傳入參數值:

1

$ fab hello:name=Year,value=2016

Fabric的腳本建議寫在」fabfile.py」文件中,如果你想換文件名,那就要在」fab」命令中用」-f」指定。比如我們將腳本放在」script.py」中,就要執行:

1

$ fab –f script.py hello

執行本地命令

「fabric.api」包里的」local()」方法可以用來執行本地Shell命令,比如讓我們列出本地」/home/bjhee」目錄下的所有文件及目錄:

Python

1 2 3 4

from fabric.api import local def hello():     local(『ls -l /home/bjhee/』)

「local()」方法有一個」capture」參數用來捕獲標準輸出,比如:

Python

1 2

def hello():     output = local(『echo Hello』, capture=True)

這樣,Hello字樣不會輸出到屏幕上,而是保存在變量output里。」capture」參數的默認值是False。

執行遠程命令

Fabric真正強大之處不是在執行本地命令,而是可以方便的執行遠程機器上的Shell命令。它通過SSH實現,你需要的是在腳本中配置遠程機器地址及登錄信息:

Python

1 2 3 4 5 6 7 8

from fabric.api import run, env env.hosts = [『example1.com』, 『example2.com』] env.user = 『bjhee』 env.password = 『111111』 def hello():     run(『ls -l /home/bjhee/』)

「fabric.api」包里的」run()」方法可以用來執行遠程Shell命令。上面的任務會分別到兩台服務器」example1.com」和」example2.com」上執行」ls -l /home/bjhee/」命令。這裡假設兩台服務器的用戶名都是」bjhee」,密碼都是6個1。你也可以把用戶直接寫在hosts里,比如:

Python

1

env.hosts = [『[email protected]』, 『[email protected]』]

如果你的」env.hosts」里沒有配置某個服務器,但是你又想在這個服務器上執行任務,你可以在命令行中通過」-H」指定遠程服務器地址,多個服務器地址用逗號分隔:

另外,多台機器的任務是串行執行的,關於並行任務的執行我們在之後會介紹。

如果對於不同的服務器,我們想執行不同的任務,上面的方法似乎做不到,那怎麼辦?我們要對服務器定義角色:

Python

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26

from fabric.api import env, roles, run, execute, cd env.roledefs = {     『staging』: [『[email protected]』,『[email protected]』],     『build』: [『[email protected]』] } env.passwords = {     『staging』: 『11111』,     『build』: 『123456』 } @roles(『build』) def build():     with cd(『/home/build/myapp/』):         run(『git pull』)         run(『python setup.py』) @roles(『staging』) def deploy():     run(『tar xfz /tmp/myapp.tar.gz』)     run(『cp /tmp/myapp /home/bjhee/www/』) def task():     execute(build)     execute(deploy)

現在讓我們執行:

1

$ fab task

這時Fabric會先在一台build服務器上執行build任務,然後在兩台staging服務器上分別執行deploy任務。」@roles」裝飾器指定了它所裝飾的任務會被哪個角色的服務器執行。

如果某一任務上沒有指定某個角色,但是你又想讓這個角色的服務器也能運行該任務,你可以通過」-R」來指定角色名,多個角色用逗號分隔:

1

$ fab –R build deploy

這樣」build」和」staging」角色的服務器都會運行」deploy」任務了。註:」staging」是裝飾器默認的,因此不用通過」-R」指定。

此外,上面的例子中,服務器的登錄密碼都是明文寫在腳本里的。這樣做不安全,推薦的方式是設置SSH自動登錄,具體方法大家可以去網上搜搜。

SSH功能函數

到目前為止,我們介紹了」local()」和」run()」函數分別用來執行本地和遠程Shell命令。Fabric還提供了其他豐富的功能函數來輔助執行命令,這裡我們介紹幾個常用的:

  1. sudo: 以超級用戶權限執行遠程命令

功能類似於」run()」方法,區別是它相當於在Shell命令前加上了」sudo」,所以擁有超級用戶的權限。使用此功能前,你需要將你的用戶設為sudoer,而且無需輸密碼。具體操作可參見我的這篇文章

Python

1 2 3 4 5 6 7

from fabric.api import env, sudo env.hosts = [『[email protected]』, 『[email protected]』] env.password = 『111111』 def hello():     sudo(『mkdir /var/www/myapp』)

它的工作原理是基於scp命令,使用的方法如下:

Python

1 2 3 4 5 6 7

from fabric.api import env, get env.hosts = [『[email protected]』,] env.password = 『111111』 def hello():     get(『/var/log/myapp.log』, 『myapp-0301.log』)

上述任務將遠程機上」/var/log/myapp.log」文件下載到本地當前目錄,並命名為」myapp-0301.log」。

  1. put(local, remote): 從本地上傳文件到遠程機器上

同get一樣,put方法也是基於scp命令,使用的方法如下:

Python

1 2 3 4 5 6 7

from fabric.api import env, put env.hosts = [『[email protected]』, 『[email protected]』] env.password = 『111111』 def hello():     put(『/tmp/myapp-0301.tar.gz』, 『/var/www/myapp.tar.gz』)

上述任務將本地」/tmp/myapp-0301.tar.gz」文件分別上傳到兩台遠程機的」/var/www/」目錄下,並命名為」myapp.tar.gz」。如果遠程機上的目錄需要超級用戶權限才能放文件,可以在」put()」方法里加上」use_sudo」參數:

Python

1

put(『/tmp/myapp-0301.tar.gz』, 『/var/www/myapp.tar.gz』, use_sudo=True)

該方法類似於Shell中的」read」命令,它會在終端顯示一段文字來提示用戶輸入,並將用戶的輸入保存在變量里:

Python

1 2 3 4 5 6 7 8

from fabric.api import env, get, prompt env.hosts = [『[email protected]』,] env.password = 『111111』 def hello():     filename = prompt(『Please input file name: 『)     get(『/var/log/myapp.log』, 『%s.log』 % filename)

現在下載後的文件名將由用戶的輸入來決定。我們還可以對用戶輸入給出默認值及類型檢查:

Python

1

port = prompt(『Please input port number: 『, default=8080, validate=int)

執行任務後,終端會顯示:

1

Please input port number: [8080]

如果你直接按回車,則port變量即為默認值8080;如果你輸入字符串,終端會提醒你類型驗證失敗,讓你重新輸入,直到正確為止。

  1. reboot: 重啟服務器

看方法名就猜到了,有時候安裝好環境後,需要重啟服務器,這時就要用到」reboot()」方法,你可以用」wait」參數來控制其等待多少秒後重啟,沒有此參數則代表立即重啟:

Python

1 2 3 4 5 6 7

from fabric.api import env, reboot env.hosts = [『[email protected]』,] env.password = 『111111』 def restart():     reboot(wait=60)

上面的restart任務將在一分鐘後重啟服務器。

上下文管理器

Fabric的上下文管理器是一系列與Python的」with」語句配合使用的方法,它可以在」with」語句塊內設置當前工作環境的上下文。讓我們介紹幾個常用的:

  1. cd: 設置遠程機器的當前工作目錄

「cd()」方法在之前的範例中出現過,」with cd()」語句塊可以用來設置遠程機的工作目錄:

Python

1 2 3 4 5 6 7 8

from fabric.api import env, cd, put env.hosts = [『[email protected]』, ] env.password = 『111111』 def hello():     with cd(『/var/www/』):         put(『/tmp/myapp-0301.tar.gz』, 『myapp.tar.gz』)

上例中的文件會上傳到遠程機的」/var/www/」目錄下。出了」with cd()」語句塊後,工作目錄就回到初始的狀態,也就是」bjhee」用戶的根目錄。

  1. lcd: 設置本地工作目錄

「lcd()」就是」local cd」的意思,用法同」cd()」一樣,區別是它設置的是本地的工作目錄:

Python

1 2 3 4 5 6 7 8 9

from fabric.api import env, cd, lcd, put env.hosts = [『[email protected]』, ] env.password = 『111111』 def hello():     with cd(『/var/www/』):         with lcd(『/tmp/』):             put(『myapp-0301.tar.gz』, 『myapp.tar.gz』)

這個例子的執行效果跟上個例子一樣。

  1. path: 添加遠程機的PATH路徑 Python 1 2 3 4 5 6 7 8 9 from fabric.api import env, run, path env.hosts = [『[email protected]』, ] env.password = 『111111』 def hello(): with path(『/home/bjhee/tmp』): run(『echo $PATH』) run(『echo $PATH』)

假設我們的PATH環境變量默認是」/sbin:/bin」,在上述」with path()」語句塊內PATH變量將變為」/sbin:/bin:/home/bjhee/tmp」。出了with語句塊後,PATH又回到原來的值。

  1. settings: 設置Fabric環境變量參數

Fabric環境變量即是我們例子中一直出現的」fabric.api.env」,它支持的參數可以從官方文檔中查到。

Python

1 2 3 4 5 6 7 8

from fabric.api import env, run, settings env.hosts = [『[email protected]』, ] env.password = 『111111』 def hello():     with settings(warn_only=True):         run(『echo $USER』)

我們將環境參數」warn_only」暫時設為True,這樣遇到錯誤時任務不會退出。

  1. shell_env: 設置Shell環境變量

可以用來臨時設置遠程和本地機上Shell的環境變量。

Python

1 2 3 4 5 6 7 8 9

from fabric.api import env, run, local, shell_env env.hosts = [『[email protected]』, ] env.password = 『111111』 def hello():     with shell_env(JAVA_HOME=『/opt/java』):         run(『echo $JAVA_HOME』)         local(『echo $JAVA_HOME』)

錯誤處理

默認情況下,Fabric在任務遇到錯誤時就會退出,如果我們希望捕獲這個錯誤而不是退出任務的話,就要開啟」warn_only」參數。在上面介紹」settings()」上下文管理器時,我們已經看到了臨時開啟」warn_only」的方法了,如果要全局開啟,有兩個辦法:

  1. 在執行」fab」命令時加上」-w」參數

1

$ fab –w hello

並行執行

我們在介紹執行遠程命令時曾提到過多台機器的任務默認情況下是串行執行的。Fabric支持並行任務,當服務器的任務之間沒有依賴時,並行可以有效的加快執行速度。怎麼開啟並行執行呢?辦法也是兩個:

  1. 在執行」fab」命令時加上」-P」參數

1

$ fab –P hello

如果,我們只想對某一任務做並行的話,我們可以在任務函數上加上」@parallel」裝飾器:

Python

1 2 3 4 5 6 7 8

from fabric.api import parallel @parallel def runs_in_parallel():     pass def runs_serially():     pass

這樣即便並行未開啟,」runs_in_parallel()」任務也會並行執行。反過來,我們可以在任務函數上加上」@serial」裝飾器:

Python

1 2 3 4 5 6 7 8

from fabric.api import serial def runs_in_parallel():     pass @serial def runs_serially():     pass

這樣即便並行已經開啟,」runs_serially()」任務也會串行執行。

補充

這個部分用來補充Fabric的一些特別功能:

  • 終端輸出帶顏色

我們習慣上認為綠色表示成功,黃色表示警告,而紅色表示錯誤,Fabric支持帶這些顏色的輸出來提示相應類型的信息:

Python

1 2 3 4 5 6

from fabric.colors import * def hello():     print green(「Successful」)     print yellow(「Warning」)     print red(「Error」)

通過」execute()」方法,可以在一個」fab」命令中多次調用同一任務,如果想避免這個發生,就要在任務函數上加上」@runs_once」裝飾器。

Python

1 2 3 4 5 6 7 8 9

from fabric.api import execute, runs_once @runs_once def hello():     print 「Hello Fabric!」 def test():     execute(hello)     execute(hello)

現在不管我們」execute」多少次hello任務,都只會輸出一次」Hello Fabric!」字樣

更多內容請參閱Fabric的官方文檔。本篇中的示例代碼可以在這裡下載

原創文章,轉載請註明: 轉載自URl-team

本文鏈接地址: Python遠程部署利器Fabric詳解-轉載

  1. 學習—用 Python 和 OpenCV 檢測和跟蹤運動對象
  2. 使用pyaiml機械人模塊快速做個和你智能對話的大腦
  3. 讓樹莓派開機運行Python腳本
  4. 阿里雲學生主機壓力測試與優化防禦腳本
  5. Linux查看實時帶寬流量情況以及查看端口信息
  6. wordpress解決谷歌字體問題–與谷歌字體的戰爭!