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教程歡迎持續關注編程學習網。
掃碼二維碼 獲取免費視頻學習資料
- 本文固定鏈接: http://www.stbrigidsathleticclub.com/post/11216/
- 轉載請注明:轉載必須在正文中標注并保留原文鏈接
- 掃碼: 掃上方二維碼獲取免費視頻資料
查 看2022高級編程視頻教程免費獲取