Fabric是一個Python庫和命令行工具,旨在爲應用部署和系統管理任務的SSH的流水線式操做,使之更加高效和方便。Fabric提供了一套基本的執行本地和遠程shell命令、上傳和下載文件的操做,包括一些輔助函數,例如驅動正在運行的用戶輸入或者放棄執行。html
Fabric經過把大量頻繁使用的SSH操做寫入到一個腳本中(fabric.py),來遠程執行一些應用部署或者系統維護的任務。Fabric是相似paramiko的一個庫,是對paramiko的再次封裝,因此比使用paramiko更簡單。python
Fabric的優勢:web
角色定義shell
代碼易讀api
封裝了本地、遠程操做tomcat
參數靈活,能偶動態指定host/role等,還有併發執行(基於multiprocessing)bash
完整的日誌輸出服務器
在Linux下安裝方法:網絡
使用pip來安裝 併發
yum install python-pip -y pip install fabric
Fabric經過命令行工具fab來執行定義在fabfile.py中的任務,經常使用的配置和函數以下:
經常使用的fab命令選項和參數:
-l 顯示可用的task
-H 指定host,多個host用逗號分開
-R 指定role,多個role用逗號分開
-P 並分數,默認是串行
-w warn_only,默認爲遇到異常直接放棄執行並退出
-f 指定入口文件,fab默認入口文件是:fabfile.py
fabfile.py文件中經常使用配置和函數:
env.host 主機ip,也可使用fab選項-H參數來指定
env.password SSH密碼,若已經設置好無密碼登陸,則能夠忽略
env.roledefs 角色分組,如:{'web': ['x', 'y'], 'db': ['z']}
local('pwd') 執行本地命令
lcd('/tmp') 切換本地目錄
cd('/tmp') 切換遠程目錄
run('uname -s') 執行遠程命令
sudo('service httpd restart') 執行遠程sudo,注意pty選項
env.exclude_hosts=['10.1.6.159'] 排除10.1.6.159
fabric.operations.open_shell() 打開遠程shell界面。
get 是下載
put 是上傳
下面來一些例子:
#/usr/bin/python #coding:utf8 from fabric.api import * from fabric.colors import * from fabric.context_managers import * env.hosts=['10.1.6.186','10.1.6.159'] env.password='xxxxxx' def task1(): with cd('/home/guol'): run('ls -l')
不一樣的機器執行不一樣的task:
#!/usr/bin/python from fabric.api import * from fabric.colors import * from fabric.context_managers import * env.roledefs={'web1':['10.1.6.186'],'web2':['10.1.6.159']} env.password='xxxxxx' ##須要配置密碼相同,,,, @roles('web1') def task1(): with cd('/home/guol'): run('ls -l') @roles('web2') def task2(): print(green("I'm fabric")) def deploy(): execute(task1) execute(task2) 執行結果: root@vm11:/tmp# fab deploy [10.1.6.186] Executing task 'task1' [10.1.6.186] run: ls -l [10.1.6.186] out: total 0 [10.1.6.186] out: -rw-r--r-- 1 root root 0 Dec 21 13:32 186-local [10.1.6.186] out: [10.1.6.159] Executing task 'task2' I'm fabric Done. Disconnecting from 10.1.6.186... done.
farbic的環境變量:
fabric的環境變量有不少,存放在一個字典中,
fabric.state.env,而它包含在fabric.api中。
爲了方便,咱們通常使用env來指代環境變量。
env環境變量能夠控制不少fabric的行爲,通常經過env.xxx能夠進行設置。
fabric默認使用本地用戶經過ssh進行鏈接遠程機器,不過你能夠經過env.user變量進行覆蓋。
當你進行ssh鏈接時,fabric會讓你交互的讓你輸入遠程機器密碼,若是你設置了env.password變量,則就不須要交互的輸入密碼。
下面介紹一些經常使用的環境變量:
abort_on_prompts 設置是否運行在交互模式下,例如會提示輸入密碼之類,默認是false
connection_attempts fabric嘗試鏈接到新服務器的次數,默認1次
cwd 目前的工做目錄,通常用來肯定cd命令的上下文環境
disable_known_hosts 默認是false,若是是true,則會跳過用戶知道的hosts文件
exclude_hosts 指定一個主機列表,在fab執行時,忽略列表中的機器
fabfile 默認值是fabfile.py在fab命令執行時,會自動搜索這個文件執行。
host_string 當fabric鏈接遠程機器執行run、put時,設置的user/host/port等
hosts 一個全局的host列表
keepalive 默認0 設置ssh的keepalive
loacl_user 一個只讀的變量,包含了本地的系統用戶,同user變量同樣,可是user能夠修改
parallel 默認false,若是是true則會並行的執行全部的task
pool_size 默認0 在使用parallel執行任務時設置的進程數
password ssh遠程鏈接時使用的密碼,也能夠是在使用sudo時使用的密碼
passwords 一個字典,能夠爲每一臺機器設置一個密碼,key是ip,value是密碼
path 在使用run/sudo/local執行命令時設置的$PATH環境變量
port 設置主機的端口
roledefs 一個字典,設置主機名到規則組的映射
roles 一個全局的role列表
shell 默認是/bin/bash -1 -c 在執行run命令時,默認的shell環境
skip_bad_hosts 默認false,爲ture時,會致使fab跳過沒法鏈接的主機
sudo_prefix 默認值"sudo -S -p '%(sudo_prompt)s' " % env 執行sudo命令時調用的sudo環境
sudo_prompt 默認值"sudo password:"
timeout 默認10 網絡鏈接的超時時間
user ssh使用哪一個用戶登陸遠程主機
設置主機列表的方法:
hosts,在上下文環境中咱們稱hosts爲"host strings"
strings指定了username、hostname、port等
組合username@hostname:port。username和port能夠省略,則默認使用本地用戶和22端口。
strings映射單個主機,可是有時候你想把一批主機加入一個組中
roles則提供了一個定義一系列主機的方法,這個映射能夠經過env.rolesdefs來設置
它必須經過fabfile進行設置纔可使用。env.roledefs['webservers'] = ['www1', 'www2', 'www3']
fabric 中傳參數的類型,下面是一個例子:
#!/usr/bin/python from fabric.api import * import fabric.operations from fabric.colors import * from fabric.context_managers import * import datetime env.passwords = {'root@192.168.1.1:22':'redhat123456','root@192.168.1.2:22':'redhat'} @hosts('root@192.168.1.1:22') def task1(): filename = run('ls /root/my/') #查看遠程目錄上的文件(此例子中這個目錄下只有一個a.txt) 把這個文件名傳到task2上中去 get('/root/my/*','/root/my') #下載到本地的/root/my目錄下 local('fab task2:name=%s' % filename) #執行本地命令,並傳遞filename這個參數給task2 @hosts('root@192.168.1.2:22') def task2(name=''): #定義帶參數的函數 put('/root/my/%s' % name, '/root/my') #把本地的/root/my/a.txt上傳到192.168.1.2的/root/my目錄下 #### 運行: fab task1 單獨運行task2的命令: fab task2:name='a.txt'
最後再來一個例子:
#!/usr/bin/env python # -*- coding:utf-8 -*- from fabric.api import env,run,local,hosts,put,puts, cd import fabric.operations from fabric.colors import * import datetime # env.hosts = [] #下面定義三個主機 env.passwords = {'root@192.168.10.91:22':'password', 'root@11.44.119.2:22':'password', 'root@11.44.119.1:22':'password'} @hosts('root@192.168.10.91:22') def uploadmusic(): put('./data/*.mp3','/var/www/html/music/') #把本地/data/目錄下的mp3文件上傳到192.168.10.91 @hosts('root@11.44.119.2:22') def rsyncmusic(): with cd("/usr/local/tomcat/webapps/"): #遠程執行cd 命令,,下面是run執行的命令 run('pwd') run('ls /root/') bak_webapi = 'tar -zcf webapi_%s.tar.gz webapi' % datetime.datetime.now().strftime("%Y%m%d%H%M") run(bak_webapi) put("./data/*.txt","webapi/WEB-INF/classes/data/") run("rm -rf webapi/WEB-INF/classes/data/index") run("echo ''>/usr/local/tomcat/webapps/webapi/WEB-INF/classes/data/a.txt") #fabric.operations.open_shell("python /root/zhou.py") @hosts('root@11.44.119.1:22') def shellhost(): fabric.operations.open_shell() #遠程到119.1上,並打開shell