項目發(fā)布部署時袖瞻,往往需要花大量的時間去ssh多臺機器,然后逐一敲重復(fù)的命令煞躬,同樣的操作和同樣的命令反復(fù)做肛鹏,作為一個程序員是不能忍受的逸邦,這也是自動化存在的意義,可以大大節(jié)省不必要的時間在扰,python做為一個腳本語言本身就有這方面的優(yōu)勢缕减,fabric 這個庫可以很好的偷懶,本文使用python3芒珠。
安裝
會安裝一大堆包桥狡,提示 Successfully installed 等字樣表示安裝成功,安裝完后皱卓,系統(tǒng)有一個 fab 命令可以使用裹芝。想要了解更多,看 官方文檔 娜汁。
sudo pip3 install fabric3
簡單示例
1嫂易、先見識一下使用效果,然后再看常用的一些命令
例一:執(zhí)行遠程主機命令掐禁,查看主機操作系統(tǒng)炬搭, 'uname -o'
首先創(chuàng)建一個 check.py 文件
from fabric.api import run # 導(dǎo)入api中的run
def look():
run('uname -o') # 執(zhí)行run函數(shù),把用使用的命令傳入
然后使用 fab 命令執(zhí)行穆桂,輸入目標(biāo)主機用戶密碼后即可執(zhí)行命令,并打印結(jié)果
fab -f check.py -H 127.0.0.1 'look' # -f指定文件融虽, -H 指定主機享完,這里我們直接用本地, look 是文件里面的任務(wù)函數(shù)名
輸出的結(jié)果如下:例一執(zhí)行結(jié)果
這里只是一個小示例有额,當(dāng)然不可能每個都自己手動輸入密碼般又,通過配置都可以完成自動化。
例二:多臺遠程主機創(chuàng)建目錄 test 巍佑。
- 創(chuàng)建一個 mk_dir.py 文件:
from fabric.api import *
# 設(shè)置目標(biāo)主機
env.hosts = ['192.168.139.139', '192.168.139.141']
# 設(shè)置多臺主機用戶名及密碼
env.passwords = {
'python@192.168.139.139:22': '12345678',
'python@192.168.139.141:22': '12345678'
}
# 設(shè)置一個任務(wù)
@task
def start():
run('mkdir test')
- 然后執(zhí)行任務(wù)
fab -f mk_dir.py start # start 是任務(wù)名
結(jié)果如下茴迁,可以在兩個主機的 python 用戶家目錄看到 test 文件夾,這樣就可以實現(xiàn)自動連接遠程主機萤衰,并執(zhí)行相應(yīng)的任務(wù)了堕义。例二執(zhí)行結(jié)果
例三:打包本地文件,上傳到目標(biāo)主機脆栋,并校驗 md5 倦卖,然后解壓并執(zhí)行這個文件(該例可以配合后面的命令說明測試)
場景:本地有一個 /home/python/test/test.py 文件,打包成 test.tar.gz 椿争,上傳到目標(biāo)主機的 /home/python/temp 目錄下怕膛,解壓并執(zhí)行。
- 創(chuàng)建一個本地的test.py如下秦踪,用來上傳后執(zhí)行:
print('===========')
print('hello world')
print('===========')
- 創(chuàng)建一個任務(wù)文件 uploadfile.py
from fabric.api import *
env.hosts = ['192.168.139.139', '192.168.139.141']
env.user = 'python' # 多臺主機用戶名密碼相同可以只寫一次
env.password = '12345678'
# 打包
@runs_once # 該裝飾器表示只執(zhí)行一次褐捻,沒有的話默認每臺主機都執(zhí)行一次
def task_tar(): # 該場景本地文件打包本身就只需要執(zhí)行一次
with lcd('/home/python/test'):
local('tar zcvf test.tar.gz test.py')
# 上傳
def task_upload():
run('mkdir -p /home/python/temp')
put('/home/python/test/test.tar.gz', '/home/python/temp/test.tar.gz')
# 驗證md5
def task_md5():
# 計算本地的md5
local_md5 = local('md5sum /home/python/test/test.tar.gz', capture=True).split(' ')[0]
# 計算遠程主機md5
remote_md5 = run('md5sum /home/python/temp/test.tar.gz').split(' ')[0]
print(local_md5)
print(remote_md5)
if remote_md5 == local_md5:
print('上傳成功')
else:
print('上傳出錯')
# 解包并執(zhí)行
def task_exc():
with cd('/home/python/temp'):
run('tar zxvf test.tar.gz')
run('python3 test.py')
# 調(diào)度
@task
def start():
task_tar()
task_upload()
task_md5()
task_exc()
- 執(zhí)行任務(wù):
fab -f uploadfile.py start
- 屏幕輸出結(jié)果如下
[python@ubuntu Test]$ fab -f uploadfile.py start
[192.168.139.139] Executing task 'start'
[localhost] local: tar zcvf test.tar.gz test.py
test.py
[192.168.139.139] run: mkdir -p /home/python/temp
[192.168.139.139] put: /home/python/test/test.tar.gz -> /home/python/temp/test.tar.gz
[localhost] local: md5sum /home/python/test/test.tar.gz
[192.168.139.139] run: md5sum /home/python/temp/test.tar.gz
[192.168.139.139] out: d5e8f717b176270f4c1a4fa72493239a /home/python/temp/test.tar.gz
[192.168.139.139] out:
d5e8f717b176270f4c1a4fa72493239a
d5e8f717b176270f4c1a4fa72493239a
上傳成功
[192.168.139.139] run: tar zxvf test.tar.gz
[192.168.139.139] out: test.py
[192.168.139.139] out:
[192.168.139.139] run: python3 test.py
[192.168.139.139] out: ===========
[192.168.139.139] out: hello world
[192.168.139.139] out: ===========
[192.168.139.139] out:
[192.168.139.141] Executing task 'start'
[192.168.139.141] run: mkdir -p /home/python/temp
[192.168.139.141] put: /home/python/test/test.tar.gz -> /home/python/temp/test.tar.gz
[localhost] local: md5sum /home/python/test/test.tar.gz
[192.168.139.141] run: md5sum /home/python/temp/test.tar.gz
[192.168.139.141] out: d5e8f717b176270f4c1a4fa72493239a /home/python/temp/test.tar.gz
[192.168.139.141] out:
d5e8f717b176270f4c1a4fa72493239a
d5e8f717b176270f4c1a4fa72493239a
上傳成功
[192.168.139.141] run: tar zxvf test.tar.gz
[192.168.139.141] out: test.py
[192.168.139.141] out:
[192.168.139.141] run: python3 test.py
[192.168.139.141] out: ===========
[192.168.139.141] out: hello world
[192.168.139.141] out: ===========
[192.168.139.141] out:
Done.
Disconnecting from 192.168.139.139... done.
Disconnecting from 192.168.139.141... done.
常用命令
常用參數(shù)
- -l : 列出指定文件的任務(wù)函數(shù)名掸茅,只有使用了裝飾器 @task 的才會列出
- -H : 指定目標(biāo)主機,多臺主機用","號分割
- -u:指定遠程用戶名
- -f : 指定fab的任務(wù)文件柠逞,默認的任務(wù)文件名是fabfile.py昧狮,即文件直接命名 fabfile.py ,可以不用 -f 指定文件
- -t:設(shè)置超時時間边苹,單位秒
- -V:查看版本
API
- @task : 函數(shù)裝飾器陵且,裝飾的函數(shù)fab才能調(diào)用
- @runs_once : 函數(shù)裝飾器,裝飾的函數(shù)只執(zhí)行一次
- local : 執(zhí)行本地命令个束,例:local('ls -la')
- run : 執(zhí)行遠程命令慕购,例:run('ls -la')
- lcd : 切換本地目錄,例:lcd('/home/python')
- cd : 切換遠程目錄茬底,例:cd('/home/python')
- put : 上傳本地文件到遠程主機沪悲,例:put('test', '/home/python/')
- get : 從遠程主機下載文件到本地,例:get('/home/python/test', './')
- reboot : 重啟遠程主機阱表,例:reboot()
- sudo : sudo執(zhí)行遠程命令殿如,例:sudo('service nginx start')
主機設(shè)置
- env.host : 設(shè)置目標(biāo)主機
- env.user : 設(shè)置用戶名
- env.port : 設(shè)置目標(biāo)主機端口,默認是22
- env.password : 設(shè)置密碼
- env.passwords : 設(shè)置多臺主機不同的密碼最爬。
個人博客:python遠程自動化部署