日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
如何高效地遠(yuǎn)程部署?自動(dòng)化運(yùn)維利器Fabric教程

關(guān)于 Python 自動(dòng)化的話題,在上一篇文章中,我介紹了 Invoke 庫,它是 Fabric 的重要組件之一。Fabric 也是一個(gè)被廣泛應(yīng)用的自動(dòng)化工具庫,是不得不提的自動(dòng)化運(yùn)維利器,所以,本文將來介紹一下它。

創(chuàng)新互聯(lián)建站是專業(yè)的城中網(wǎng)站建設(shè)公司,城中接單;提供成都網(wǎng)站設(shè)計(jì)、網(wǎng)站建設(shè),網(wǎng)頁設(shè)計(jì),網(wǎng)站設(shè)計(jì),建網(wǎng)站,PHP網(wǎng)站建設(shè)等專業(yè)做網(wǎng)站服務(wù);采用PHP框架,可快速的進(jìn)行城中網(wǎng)站開發(fā)網(wǎng)頁制作和功能擴(kuò)展;專業(yè)做搜索引擎喜愛的網(wǎng)站,專業(yè)的做網(wǎng)站團(tuán)隊(duì),希望更多企業(yè)前來合作!

Fabric 主要用在應(yīng)用部署與系統(tǒng)管理等任務(wù)的自動(dòng)化,簡單輕量級(jí),提供有豐富的 SSH 擴(kuò)展接口。在 Fabric 1.x 版本中,它混雜了本地及遠(yuǎn)程兩類功能;但自 Fabric 2.x 版本起,它分離出了獨(dú)立的 Invoke 庫,來處理本地的自動(dòng)化任務(wù),而 Fabric 則聚焦于遠(yuǎn)程與網(wǎng)絡(luò)層面的任務(wù)。

為了做到這點(diǎn),F(xiàn)abric 主要依賴另一大核心組件 Paramiko,它是基于 SSH 協(xié)議的遠(yuǎn)程控制模塊,F(xiàn)abric 在其基礎(chǔ)上封裝出了更加友好的接口,可以遠(yuǎn)程執(zhí)行 Shell 命令、傳輸文件、批量操作服務(wù)器、身份認(rèn)證、多種配置與設(shè)置代理,等等。

一、Fabric 的版本區(qū)分

Python 2 版本已經(jīng)被官宣在今年元旦“退休”了,未來只會(huì)是 Python 3 的舞臺(tái)。為了適應(yīng) Python 版本的非兼容性遷移,很多項(xiàng)目也必須推出自己的新版本(兼容或只支持 Python 3),其中就包括本文的主角 Fabric。

Fabric 自身存在著 2 個(gè)大版本:Fabric 1 和 Fabric 2,而在這個(gè)庫的基礎(chǔ)上,還有兩個(gè)很容易混淆的相關(guān)庫:Fabric2 和 Fabric3(注意這里的數(shù)字是庫名的一部分)。

它們的區(qū)分如下:

  • Fabric 1.x:支持 Python 2.5-2.7,但不支持 Python 3
  • Fabric 2.x:支持 Python 2.7 與 3.4+,但不兼容 Fabric 1.x 的 fabfile
  • Fabric2:等同于 Fabric 2.x,為了使不同版本共存(裝一個(gè) 1.x 舊版本,再裝它作為新版本)
  • Fabric3:一個(gè)基于 Fabric 1.x 的 fork(非官方),兼容 Python 2&3,兼容 Fabric1.x 的 fabfile

綜上可見,我們推薦使用官方的 Fabric 2.x 系列版本,但同時(shí)要注意,某些過時(shí)的教程可能是基于早期版本的(或非官方的 Fabric3,也是基于 Fabric 1.x),需要注意識(shí)別。

例如,在 Fabric 1.x 系列中這么寫導(dǎo)入:from fabric.api import run;在新版本中將報(bào)錯(cuò):“ImportError: No module named api”(PS:可根據(jù)是否有 fabric.api 來判斷 Fabric 的版本,就像在 Python 中根據(jù) print 語句或 print 函數(shù)來判斷版本一樣)。同時(shí),由于新版本不支持老版本的 fabfile,在使用時(shí)就可能報(bào)錯(cuò):“No idea what 'xxx' is!”

Fabric 2 是非兼容性版本,相比于前個(gè)版本,它主要改進(jìn)的點(diǎn)有:

  • 支持 Python 2.7 與 3.4+
  • 線程安全,取消了多進(jìn)程的并發(fā)實(shí)現(xiàn)
  • API 圍繞 fabric.connection.Connection 進(jìn)行了重組
  • 全面修改了命令行解析器,允許在每個(gè)任務(wù)的基礎(chǔ)上使用規(guī)則的 GNU/POSIX 風(fēng)格的標(biāo)志和選項(xiàng)(不再需要 fab mytask:weird = custom,arg = format)
  • 可以聲明前置任務(wù)與后置任務(wù)
  • ……(官方列了10幾條[1],本文不一一羅列)

之前介紹過的 invoke,就是在開發(fā) Fabric 2 時(shí)被分離出來的,具體的原因可參見這個(gè)回答[2]。總而言之,在使用 Fabric 時(shí),應(yīng)該注意版本差異的問題。

二、Fabric 的基本用法

1、安裝

首先是安裝:pip intall fabric ,安裝后,可在命令行窗口查看版本信息:

 
 
 
 
  1. >>> fab -V 
  2. Fabric 2.5.0 
  3. Paramiko 2.7.1 
  4. Invoke 1.4.0 

執(zhí)行“fab -V”,以上結(jié)果可看出我安裝的是 Fabric 2.5.0 版本,同時(shí)可看到它的兩個(gè)核心依賴庫 Paramiko 及 Invoke 的版本信息。

2、一個(gè)簡單的例子

Fabric 主要用于遠(yuǎn)程任務(wù),即要對(duì)遠(yuǎn)程服務(wù)器進(jìn)行操作,下面是一個(gè)簡單的例子:

 
 
 
 
  1. # 可使用任意的文件名 
  2. from fabric import Connection 
  3.  
  4. host_ip = '47.xx.xx.xx'  # 服務(wù)器地址 
  5. user_name = 'root' # 服務(wù)器用戶名 
  6. password = '****'  # 服務(wù)器密碼 
  7. cmd = 'date'  # shell 命令,查詢服務(wù)器上的時(shí)間 
  8.  
  9. con = Connection(host_ip, user_name, connect_kwargs={'password': password}) 
  10. result = con.run(cmd, hide=True) 
  11.  
  12. print(result) 

以上代碼,通過賬號(hào)+密碼登錄到遠(yuǎn)程服務(wù)器,然后執(zhí)行date命令,查看服務(wù)器的時(shí)間,執(zhí)行結(jié)果:

 
 
 
 
  1. Command exited with status 0. 
  2. === stdout === 
  3. Fri Feb 14 15:33:05 CST 2020 
  4.  
  5. (no stderr) 

現(xiàn)在打印的結(jié)果中,除了服務(wù)器時(shí)間,還有一些無關(guān)的信息。這是因?yàn)樗蛴〉摹皉esult”是一個(gè)"fabric.runners.Result"類,我們可以把其中的信息解析出來:

 
 
 
 
  1. print(result.stdout)  # Fri Feb 14 15:33:05 CST 2020 
  2. print(result.exited)  # 0 
  3. print(result.ok)      # True 
  4. print(result.failed)  # False 
  5. print(result.command) # date 
  6. print(result.connection.host) # 47.xx.xx.xx 

上述代碼使用了 Connection 類及其 run() 方法,可在連接的服務(wù)器上運(yùn)行 shell 命令。如果需要用管理員權(quán)限,則需替換成 sudo() 方法。如果要在本地執(zhí)行 shell 命令,則需替換成 local() 方法。

除此之外,還有 get()、put() 等方法,詳見下文介紹。

3、命令行用法

上例代碼可寫在任意的 .py 腳本中,然后運(yùn)行該腳本,或者稍微封裝下再導(dǎo)入到其它腳本中使用。

另外,F(xiàn)abric 還是個(gè)命令行工具,可以通過fab命令來執(zhí)行任務(wù)。我們稍微改造一下上例的代碼:

 
 
 
 
  1. # 文件名:fabfile.py 
  2. from fabric import Connection 
  3. from fabric import task 
  4.  
  5. host_ip = '47.xx.xx.xx'  # 服務(wù)器地址 
  6. user_name = 'root' # 服務(wù)器用戶名 
  7. password = '****'  # 服務(wù)器密碼 
  8. cmd = 'date'  # shell 命令,查詢服務(wù)器上的時(shí)間 
  9.  
  10. @task 
  11. def test(c): 
  12.     """ 
  13.     Get date from remote host. 
  14.     """ 
  15.     con = Connection(host_ip, user_name, connect_kwargs={'password': password}) 
  16.     result = con.run(cmd, hide=True) 
  17.     print(result.stdout)  # 只打印時(shí)間 

解釋一下,主要的改動(dòng)點(diǎn)有:

  • fabfile.py 文件名:入口代碼的腳本名必須用這個(gè)名字
  • @task 裝飾器:需要從 fabric 中引入這個(gè)裝飾器,它是對(duì) invoke 的 @task 裝飾器的封裝,實(shí)際用法跟 invoke 一樣(注意:它也需要有上下文參數(shù)“c”,但實(shí)際上它并沒有在代碼塊中使用,而是用了 Connection 類的實(shí)例)

然后,在該腳本同級(jí)目錄的命令行窗口中,可以查看和執(zhí)行相應(yīng)的任務(wù):

 
 
 
 
  1. >>> fab -l 
  2. Available tasks: 
  3.   test   Get date from remote host. 
  4.  
  5. >>> fab test 
  6. Fri Feb 14 16:10:24 CST 2020 

fab 是 Invoke 的擴(kuò)展實(shí)現(xiàn),繼承了很多原有功能,所以執(zhí)行“fab --help”,與之前介紹的“inv --help”相比,你會(huì)發(fā)現(xiàn)它們的很多參數(shù)與解釋都是一模一樣的。

fab 針對(duì)遠(yuǎn)程服務(wù)的場景,添加了幾個(gè)命令行選項(xiàng)(已標(biāo)藍(lán)),其中:

  • --prompt-for-login-password:令程序在命令行中輸入 SSH 登錄密碼(上例在代碼中指定了 connect_kwargs.password 參數(shù),若用此選項(xiàng),可要求在執(zhí)行時(shí)再手工輸入密碼)
  • --prompt-for-passphrase:令程序在命令行中輸入 SSH 私鑰加密文件的路徑
  • -H 或 --hosts:指定要連接的 host 名
  • -i 或 --identity:指定 SSH 連接所用的私鑰文件
  • -S 或 --ssh-config:指定運(yùn)行時(shí)要加載的 SSH 配置文件

關(guān)于 Fabric 的命令行接口,更多內(nèi)容可查看文檔 [3]。

4、交互式操作

遠(yuǎn)程服務(wù)器上若有交互式提示,要求輸入密碼或“yes”之類的信息,這就要求 Fabric 能夠監(jiān)聽并作出回應(yīng)。

以下是一個(gè)簡單示例。引入 invoke 的 Responder,初始化內(nèi)容是一個(gè)正則字符串和回應(yīng)信息,最后賦值給 watchers 參數(shù):

 
 
 
 
  1. from invoke import Responder 
  2. from fabric import Connection 
  3. c = Connection('host') 
  4. sudopass = Responder( 
  5.      pattern=r'\[sudo\] password:', 
  6.      response='mypassword\n') 
  7. c.run('sudo whoami', pty=True, watchers=[sudopass]) 

5、傳輸文件

本地與服務(wù)器間的文件傳輸是常見用法。Fabric 在這方面做了很好的封裝,Connection 類中有以下兩個(gè)方法可用:

  • get(*args, **kwargs):拉取遠(yuǎn)端文件到本地文件系統(tǒng)或類文件(file-like)對(duì)象
  • put(*args, **kwargs):推送本地文件或類文件對(duì)象到遠(yuǎn)端文件系統(tǒng)

在已建立連接的情況下,示例:

 
 
 
 
  1. # (略) 
  2. con.get('/opt/123.txt', '123.txt') 
  3. con.put('test.txt', '/opt/test.txt') 

第一個(gè)參數(shù)指的是要傳輸?shù)脑次募?,第二個(gè)參數(shù)是要傳輸?shù)哪康牡?,可以指定成文件名或者文件夾(為空或 None 時(shí),使用默認(rèn)路徑):

 
 
 
 
  1. # (略) 
  2. con.get('/opt/123.txt', '')  # 為空時(shí),使用默認(rèn)路徑 
  3. con.put('test.txt', '/opt/') # 指定路徑 /opt/ 

get() 方法的默認(rèn)存儲(chǔ)路徑是os.getcwd ,而 put() 方法的默認(rèn)存儲(chǔ)路徑是 home 目錄。

6、服務(wù)器批量操作

對(duì)于服務(wù)器集群的批量操作,最簡單的實(shí)現(xiàn)方法是用 for 循環(huán),然后逐一建立 connection 和執(zhí)行操作,類似這樣:

 
 
 
 
  1. for host in ('web1', 'web2', 'mac1'): 
  2.     result = Connection(host).run('uname -s') 

但有時(shí)候,這樣的方案會(huì)存在問題:

  • 如果存在多組不同的服務(wù)器集群,需要執(zhí)行不同操作,那么需要寫很多 for 循環(huán)
  • 如果想把每組操作的結(jié)果聚合起來(例如字典形式,key-主機(jī),value-結(jié)果),還得在 for 循環(huán)之外添加額外的操作
  • for 循環(huán)是順序同步執(zhí)行的,效率太低,而且缺乏異常處理機(jī)制(若中間出現(xiàn)異常,會(huì)導(dǎo)致跳出后續(xù)操作)

對(duì)于這些問題,F(xiàn)abric 提出了 Group 的概念,可將一組主機(jī)定義成一個(gè) Group,它的 API 方法跟 Connection 一樣,即一個(gè) Group 可簡化地視為一個(gè) Connection。

然后,開發(fā)者只需要簡單地操作這個(gè) Group,最后得到一個(gè)結(jié)果集即可,減少了自己在異常處理及執(zhí)行順序上的工作。

Fabric 提供了一個(gè) fabric.group.Group 基類,并由其派生出兩個(gè)子類,區(qū)別是:

  • SerialGroup(*hosts, **kwargs):按串行方式執(zhí)行操作
  • ThreadingGroup(*hosts, **kwargs):按并發(fā)方式執(zhí)行操作

Group 的類型決定了主機(jī)集群的操作方式,我們只需要做出選擇即可。然后,它們的執(zhí)行結(jié)果是一個(gè)fabric.group.GroupResult類,它是 dict 的子類,存儲(chǔ)了每個(gè)主機(jī) connection 及其執(zhí)行結(jié)果的對(duì)應(yīng)關(guān)系。

 
 
 
 
  1. >>> from fabric import SerialGroup 
  2. >>> results = SerialGroup('web1', 'web2', 'mac1').run('uname -s') 
  3. >>> print(results) 
  4.     
  5.     
  6.     
  7. }> 

另外,GroupResult 還提供了 failed 與 succeeded 兩個(gè)屬性,可以取出失敗/成功的子集。由此,也可以方便地批量進(jìn)行二次操作。

三、Fabric 的進(jìn)階用法

1、身份認(rèn)證

Fabric 使用 SSH 協(xié)議來建立遠(yuǎn)程會(huì)話,它是一種相對(duì)安全的基于應(yīng)用層的加密傳輸協(xié)議。

基本來說,它有兩種級(jí)別的安全認(rèn)證方式:

  • 基于口令的身份認(rèn)證:使用賬號(hào)與密碼來登錄遠(yuǎn)程主機(jī),安全性較低,容易受到“中間人”攻擊
  • 基于密鑰的身份認(rèn)證:使用密鑰對(duì)方式(公鑰放服務(wù)端,私鑰放客戶端),不會(huì)受到“中間人”攻擊,但登錄耗時(shí)較長

前文在舉例時(shí),我們用了第一種方式,即通過指定 connect_kwargs.password 參數(shù),使用口令來登錄。

Fabric 當(dāng)然也支持采用第二種方式,有三種方法來指定私鑰文件的路徑,優(yōu)先級(jí)如下:

  • 優(yōu)先查找 connect_kwargs.key_filename 參數(shù),找到則用作私鑰
  • 其次查找命令行用法的 --identify 選項(xiàng)
  • 最后默認(rèn)使用操作系統(tǒng)的 ssh_config 文件中的IdentityFile 的值

如果私鑰文件本身還被加密過,則需要使用 connect_kwargs.passphrase 參數(shù)。

2、配置文件

Fabric 支持把一些參數(shù)項(xiàng)與業(yè)務(wù)代碼分離,即通過配置文件來管理它們,例如前面提到的密碼和私鑰文件,可寫在配置文件中,避免與代碼耦合。

Fabric 基本沿用了 Invoke 的配置文件體系(官方文檔中列出了 9 層),同時(shí)增加了一些跟 SSH 相關(guān)的配置項(xiàng)。支持的文件格式有 .yaml、.yml、.json 與 .py(按此次序排優(yōu)先級(jí)),推薦使用 yaml 格式(后綴可簡寫成 yml)。

其中,比較常用的配置文件有:

  • 系統(tǒng)級(jí)的配置文件:/etc/fabric.yml
  • 用戶級(jí)的配置文件:~/.fabric.yml(Windows 在 C:\Users\xxx 下)
  • 項(xiàng)目級(jí)的配置文件:/myproject/fabric.yml

以上文件的優(yōu)先級(jí)遞減,由于我本機(jī)是 Windows,為了方便,我在用戶目錄建一個(gè)".fabric.yml"文件,內(nèi)容如下:

 
 
 
 
  1. # filename:.fabric.yml 
  2.  
  3. user: root 
  4. connect_kwargs: 
  5.   password: xxxx 
  6. # 若用密鑰,則如下 
  7. #  key_filename: 
  8. #    - your_key_file 

我們把用戶名和密碼抽離出來了,所以 fabfile 中就可以刪掉這些內(nèi)容:

 
 
 
 
  1. # 文件名:fabfile.py 
  2. from fabric import Connection 
  3. from fabric import task 
  4.  
  5. host_ip = '47.xx.xx.xx'  # 服務(wù)器地址 
  6. cmd = 'date'  # shell 命令,查詢服務(wù)器上的時(shí)間 
  7.  
  8. @task 
  9. def test(c): 
  10.     """ 
  11.     Get date from remote host. 
  12.     """ 
  13.     con = Connection(host_ip) 
  14.     result = con.run(cmd, hide=True) 
  15.     print(result.stdout)  

然后,在命令行中執(zhí)行:

 
 
 
 
  1. >>> fab test 
  2. Tue Feb 18 10:33:38 CST 2020 

配置文件中還可以設(shè)置很多參數(shù),詳細(xì)可查看文檔 [4]。

3、網(wǎng)絡(luò)網(wǎng)關(guān)

如果遠(yuǎn)程服務(wù)是網(wǎng)絡(luò)隔離的,無法直接被訪問到(處在不同局域網(wǎng)),這時(shí)候需要有網(wǎng)關(guān)/代理/隧道,這個(gè)中間層的機(jī)器通常被稱為跳板機(jī)或堡壘機(jī)。

Fabric 中有兩種網(wǎng)關(guān)解決方案,對(duì)應(yīng)到 OpenSSH 客戶端的兩種選項(xiàng):

  • ProxyJump:簡單,開銷少,可嵌套
  • ProxyCommand:開銷大,不可嵌套,更靈活

在創(chuàng)建 Fabric 的 Connection 對(duì)象時(shí),可通過指定 gateway 參數(shù)來應(yīng)用這兩種方案:

ProxyJump 方式就是在一個(gè) Connection 中嵌套一個(gè) Connection 作為前者的網(wǎng)關(guān),后者使用 SSH 協(xié)議的direct-tcpip 為前者打開與實(shí)際遠(yuǎn)程主機(jī)的連接,而且后者還可以繼續(xù)嵌套使用自己的網(wǎng)關(guān)。

 
 
 
 
  1. from fabric import Connection  
  2. c = Connection('internalhost', gateway=Connection('gatewayhost')) 

ProxyCommand 方式是客戶端在本地用 ssh 命令(類似“ssh -W %h:%p gatewayhost”),創(chuàng)建一個(gè)子進(jìn)程,該子進(jìn)程與服務(wù)端進(jìn)行通信,同時(shí)它能讀取標(biāo)準(zhǔn)輸入和輸出。

這部分的實(shí)現(xiàn)細(xì)節(jié)分別在paramiko.channel.Channel 和 paramiko.proxy.ProxyCommand,除了在參數(shù)中指定,也可以在 Fabric 支持的配置文件中定義。更多細(xì)節(jié),請(qǐng)查閱文檔 [5]。

四、小結(jié)

Fabric 的非兼容版本造成了一定程度的社區(qū)分裂,這無疑跟 Python 3 的推行脫不開關(guān)系,但是我們有理由相信,新版本優(yōu)勝于老版本。

網(wǎng)上關(guān)于 Fabric 的文章,很多已過時(shí)了。本文針對(duì)最新的官方文檔,梳理出了較為全面的知識(shí)點(diǎn),可以帶大家很好地入門 Fabric。


網(wǎng)站題目:如何高效地遠(yuǎn)程部署?自動(dòng)化運(yùn)維利器Fabric教程
URL標(biāo)題:http://www.5511xx.com/article/dpppesc.html