Fabric使用詳解,持續更新。。。


1. 安裝Fabric

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

$ python -V

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

$ python setup.py develop

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

$ pip install fabric

2. 第一個例子

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

def hello(): print "Hello Fabric!" 

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

$ fab hello

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

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

$ fab -l

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

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

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

$ fab hello:name=Year,value=2016

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

$ fab -f script.py hello

3. 執行本地命令

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

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

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

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

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

4. 執行遠程命令

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

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里,比如:

env.hosts = ['bjhee@example1.com', 'bjhee@example2.com'] 

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

$ fab -H bjhee@example3.com,bjhee@example4.com hello

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

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

from fabric.api import env, roles, run, execute, cd env.roledefs = { 'staging': ['bjhee@example1.com','bjhee@example2.com'], 'build': ['build@example3.com'] } 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) 

現在讓我們執行:

$ fab task

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

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

$ fab -R build deploy

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

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

5. SSH功能函數

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

  • sudo: 以超級用戶權限執行遠程命令
    功能類似於run()方法,區別是它相當於在Shell命令前加上了sudo,所以擁有超級用戶的權限。使用此功能前,你需要將你的用戶設為sudoer,而且無需輸密碼。具體操作可參見我的這篇文章
from fabric.api import env, sudo env.hosts = ['bjhee@example1.com', 'bjhee@example2.com'] env.password = '111111' def hello(): sudo('mkdir /var/www/myapp') 
  • get(remote, local): 從遠程機器上下載文件到本地
    它的工作原理是基於scp命令,使用的方法如下:
from fabric.api import env, get env.hosts = ['bjhee@example.com',] env.password = '111111' def hello(): get('/var/log/myapp.log', 'myapp-0301.log') 

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

  • put(local, remote): 從本地上傳文件到遠程機器上
    同get一樣,put方法也是基於scp命令,使用的方法如下:
from fabric.api import env, put env.hosts = ['bjhee@example1.com', 'bjhee@example2.com'] 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參數:

    put('/tmp/myapp-0301.tar.gz', '/var/www/myapp.tar.gz', use_sudo=True) 
  • prompt: 提示輸入
    該方法類似於Shell中的read命令,它會在終端顯示一段文字來提示用戶輸入,並將用戶的輸入保存在變量里:
from fabric.api import env, get, prompt env.hosts = ['bjhee@example.com',] env.password = '111111' def hello(): filename = prompt('Please input file name: ') get('/var/log/myapp.log', '%s.log' % filename) 

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

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

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

Please input port number: [8080] 

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

  • reboot: 重啟服務器
    看方法名就猜到了,有時候安裝好環境后,需要重啟服務器,這時就要用到reboot()方法,你可以用wait參數來控制其等待多少秒后重啟,沒有此參數則代表立即重啟:
from fabric.api import env, reboot env.hosts = ['bjhee@example.com',] env.password = '111111' def restart(): reboot(wait=60) 

上面的restart任務將在一分鍾后重啟服務器。

6. 上下文管理器

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

  • cd: 設置遠程機器的當前工作目錄
    cd()方法在之前的范例中出現過,with cd()語句塊可以用來設置遠程機的工作目錄:
from fabric.api import env, cd, put env.hosts = ['bjhee@example1.com', ] env.password = '111111' def hello(): with cd('/var/www/'): put('/tmp/myapp-0301.tar.gz', 'myapp.tar.gz') 

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

  • lcd: 設置本地工作目錄
    lcd()就是”local cd”的意思,用法同cd()一樣,區別是它設置的是本地的工作目錄:
from fabric.api import env, cd, lcd, put env.hosts = ['bjhee@example1.com', ] env.password = '111111' def hello(): with cd('/var/www/'): with lcd('/tmp/'): put('myapp-0301.tar.gz', 'myapp.tar.gz') 

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

  • path: 添加遠程機的PATH路徑
from fabric.api import env, run, path env.hosts = ['bjhee@example1.com', ] 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又回到原來的值。

  • settings: 設置Fabric環境變量參數
    Fabric環境變量即是我們例子中一直出現的fabric.api.env,它支持的參數可以從官方文檔中查到。
from fabric.api import env, run, settings env.hosts = ['bjhee@example1.com', ] env.password = '111111' def hello(): with settings(warn_only=True): run('echo $USER') 

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

  • shell_env: 設置Shell環境變量
    可以用來臨時設置遠程和本地機上Shell的環境變量。
from fabric.api import env, run, local, shell_env env.hosts = ['bjhee@example1.com', ] env.password = '111111' def hello(): with shell_env(JAVA_HOME='/opt/java'): run('echo $JAVA_HOME') local('echo $JAVA_HOME') 
  • prefix: 設置命令執行前綴
from fabric.api import env, run, local, prefix env.hosts = ['bjhee@example1.com', ] env.password = '111111' def hello(): with prefix('echo Hi'): run('pwd') local('pwd') 

在上述with prefix()語句塊內,所有的run()local()方法的執行都會加上echo Hi &&前綴,也就是效果等同於:

        run('echo Hi && pwd') local('echo Hi && pwd') 

配合后一節我們會講到的錯誤處理,它可以確保在prefix()方法上的命令執行成功后才會執行語句塊內的命令。

7. 錯誤處理

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

  • 在執行fab命令時加上-w參數

    $ fab -w hello
    
  • 設置env.warn_only環境參數為True

from fabric.api import env env.warn_only = True 

現在遇到錯誤時,控制台會打出一個警告信息,然后繼續執行后續任務。那我們怎么捕獲錯誤並處理呢?像run()local()sudo()get()put()等SSH功能函數都有返回值。當返回值的succeeded屬性為True時,說明執行成功,反之就是失敗。你也可以檢查返回值的failed屬性,為True時就表示執行失敗,有錯誤發生。在開啟warn_only后,你可以通過failed屬性檢查捕獲錯誤,並執行相應的操作。

from fabric.api import env, cd, put env.hosts = ['bjhee@example1.com', ] env.password = '111111' def hello(): with cd('/var/www/'): upload = put('/tmp/myapp-0301.tar.gz', 'myapp.tar.gz') if upload.failed: sudo('rm myapp.tar.gz') put('/tmp/myapp-0301.tar.gz', 'myapp.tar.gz', use_sudo=True) 

8. 並行執行

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

  • 在執行fab命令時加上-P參數

    $ fab -P hello
    
  • 設置env.parallel環境參數為True

from fabric.api import env env.parallel = True 

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

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

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

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

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

9. 補充

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

  • 終端輸出帶顏色
    我們習慣上認為綠色表示成功,黃色表示警告,而紅色表示錯誤,Fabric支持帶這些顏色的輸出來提示相應類型的信息:
from fabric.colors import * def hello(): print green("Successful") print yellow("Warning") print red("Error") 
  • 限制任務只能被執行一次
    通過execute()方法,可以在一個fab命令中多次調用同一任務,如果想避免這個發生,就要在任務函數上加上@runs_once裝飾器。
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的官方文檔

1. Fabric的任務運行規則
根據Fabric Execution model的說明,fabric默認以串行方式運行tasks,具體而言:
1)在fabfile及其import文件中定義的task對象依次被創建(只是創建對象,並未真正執行),任務之間保持其定義的先后順序。
2)對於每個task,生成將要運行該task的目標機器列表。
3)fab執行tasks時,按任務被指定的順序依次執行這些任務;針對每個任務,依次在其指定的目標機器運行且只運行一次。
4)未指定目標機器的task被當作本地任務運行,且只會被運行一次。

假設在fabfile.py中定義了如下tasks:

from fabric.api import run, env

env.hosts = ['host1', 'host2']

def taskA():
    run('ls')

def taskB():
    run('whoami')
1
2
3
4
5
6
7
8
9
在終端運行fab –list時,我們會看到taskA和taskB兩個任務,運行之:

$ fab taskA taskB
1
結果示例如下:

taskA executed on host1
taskA executed on host2
taskB executed on host1
taskB executed on host2
1
2
3
4
通過上面的實例,大家應該可以明白fabric默認的串行執行策略是怎么回事。

Fabric還允許我們指定以並行方式(借助multiprocessing模塊實現多個進程並行執行)在多台機器上並行地運行任務,甚至還可在同一個fabfile文件中指定某些task以並行方式運行,而某些task以默認的串行方式運行。具體地,可以借助@parallel或@serial指定任務的運行模式,還可以在命令行中通過-P參數指定任務是否要並性執行。示例如下:

from fabric.api import *

@parallel
def runs_in_parallel():
    pass

def runs_serially():
    pass
1
2
3
4
5
6
7
8
當運行如下命令時:

$ fab -H host1,host2,host3 runs_in_parallel runs_serially
1
執行結果示例如下:

runs_in_parallel on host1, host2, and host3
runs_serially on host1
runs_serially on host2
runs_serially on host3
1
2
3
4
此外,還可以通過對@parallel傳入pool_size參數來控制並行進程數以防並行進程太多把機器拖垮。

2. 為task指定目標機器
有多種方式可以指定任務的將要運行的目標機器,下面分別進行說明。
1)通過env.hosts或env.roles進行全局指定
Fabric的env模塊中定義了一系列全局變量,可以將其理解為可以控制fabric行為的環境變量。其中env.hosts和env.roles可以用來全局指定task的目標機器列表,這兩個“環境變量”的默認值都是空列表[]。

env.hosts的元素是fabric約定的”host strings”,每個host strings由username@hostname:port三部分構成,其中username和port部分可以缺省。本篇筆記前面的第1個代碼實例其實已經說明了如何用env.hosts全局地指定task的目標機器列表,這里不再贅述。

env.roles則是在配置了env.roledefs的情況下才有用武之地。在很多時候,不同的機器有着不同的角色,如有些是接入層,有些是業務層,有些是數據存儲層。env.roledefs可以用來組織這些機器列表以體現其角色,示例如下:

from fabric.api import env

env.roledefs = {
    'web': {
        'hosts': ['www1', 'www2', 'www3'],
    },
    'db': {
        'hosts': ['db1', 'db2'],
    }
}

@roles('web')
def mytask():
    run('ls /var/www')
1
2
3
4
5
6
7
8
9
10
11
12
13
14
上例通過env.roledefs配置了兩個角色web和db,分別包含3台、2台機器,並借助@roles為mytask指定了目標機器列表。

2)通過命令行進行全局指定

$ fab -H host1,host2 mytask
1
需要注意的是,命令行通過-H參數指定的機器列表在fabfile腳本load前被解釋,故如果fabfile中重新配置了env.hosts或env.roles,則命令行指定的機器列表會被覆蓋。為了避免fabfile覆蓋命令行參數,在fabfile中應該借助list.extend()指定env.hosts或env.roles,示例如下:

from fabric.api import env, run

env.hosts.extend(['host3', 'host4'])

def mytask():
    run('ls /var/www')
1
2
3
4
5
6
此時,當我們運行”fab -H host1,host2 mytask”時,env.hosts包含來自命令行和fabfile的4台機器。

3)通過命令行為每個任務指定機器列表

$ fab mytask:hosts="host1;host2"
1
上述方式會覆蓋全局指定的機器列表,確保mytask只會在host1, host2上執行。

4)借助裝飾器@hosts為每個任務指定目標機器

from fabric.api import hosts, run

@hosts('host1', 'host2')
def mytask():
    run('ls /var/www')
1
2
3
4
5
或者:

my_hosts = ('host1', 'host2')
@hosts(my_hosts)
def mytask():
    # ...
1
2
3
4
每個任務的@hosts裝飾器指定的機器列表會覆蓋全局目標機器列表,但不會覆蓋通過命令行為該任務單獨指定的目標機器列表。

上述4種為task指定目標機器列表的方式之間的優先級規則總結如下:
1) Per-task, command-line host lists (fab mytask:host=host1) override absolutely everything else.
2) Per-task, decorator-specified host lists (@hosts(‘host1’)) override the env variables.
3) Globally specified host lists set in the fabfile (env.hosts = [‘host1’]) can override such lists set on the command-line, but only if you’re not careful (or want them to.)
4) Globally specified host lists set on the command-line (–hosts=host1) will initialize the env variables, but that’s it.

截止目前,我們可以看到,fabric允許我們混合使用上面列出的幾種目標機器指定方式,但是我們要明白混合的結果是否符合預期。

此外,fabric默認會對通過不同來源出現多次的同一個目標機器做去重,當然,可以通過設置env.dedupe_hosts為False來關閉默認的去重策略。甚至還可以指定任務需要跳過的機器列表。具體細節可以參考Fabric Execution model的說明,這里不贅述。

3. 任務執行時,目標機器的密碼管理
如果你親自運行上面的示例代碼,就會發現,每次在目標機器遠程執行task時,fabric均會要求輸入目標機器的登錄名及密碼。如果要在多台機器上執行task,那這些密碼輸入的過程可以自動化嗎?

答案是肯定的。實現方式有兩種,下面分別進行說明。

1)通過env.password或env.passwords配置目標機器的登錄信息
下面的示例說明了如何通過env.passwords配置多台機器的登錄信息:

#!/bin/env python
#-*- encoding: utf-8 -*-

from fabric.api import run, env, hosts

## 需要注意的是,這里的host strings必須由username@host:port三部分構成,缺一不可,否則運行時還是會要求輸入密碼
env.passwords = {
    'slvher@10.123.11.209:22': 'xxx',
    'work@10.123.11.210:23': 'yyy',
}

@hosts('10.123.11.209', '10.123.11.210')
def host_os_type():
    run('uname -a')
1
2
3
4
5
6
7
8
9
10
11
12
13
14
由於通過env.passwords配置了目標機器的登錄用戶名/密碼,所以,當我們在終端運行fab host_os_type時,會發現不用手動輸入密碼了,大大方便了腳本遠程自動執行。

但是,這種明文指定登錄名/密碼的方式存在安全性問題,所以,fabric還支持以ssh key認證的方式免密在遠程機器執行任務。

在具體實現上,需要事先在目標機器上生成ssh public key並配置在~/.ssh/config文件中,然后在定義任務的fabfile中將env.use_ssh_config設置為True來啟用基於ssh public key方式的身份認證,以便實現免密碼遠程執行任務。

具體細節可以參考Fabric Leveraging native SSH config files文檔的說明,或者參考StackOverflow的這篇帖子Connecting to a host listed in ~/.ssh/config when using Fabric,限於篇幅,這里不再贅述。

最后,推薦DigitalOcean上一篇Fabric教程How To Use Fabric To Automate Administration Tasks And Deployments,淺顯易懂,值得一讀。Enjoy it.

參考資料
[1] Fabric Doc: Execution model
[2] Fabric Doc: Parallel execution
[3] Fabric Doc: The environment dictionary, env
[4] Fabric Doc: Password management
[5] Fabric Doc: Leveraging native SSH config files
[6] StackOverflow: Connecting to a host listed in ~/.ssh/config when using Fabric
[7] DigitalOcean: How To Use Fabric To Automate Administration Tasks And Deployments

=================== EOF ==================

 

使用Fabric遠程部署Flask應用
同樣,你需要先了解如何使用Fabric來遠程部署Python應用。然后,我們來編寫”fabfile.py”文件:

from fabric.api import *

env.hosts = ['example1.com', 'example2.com']
env.user = 'bjhee'

def package():
    local('python setup.py sdist --formats=gztar', capture=False)

def deploy():
    dist = local('python setup.py --fullname', capture=True).strip()
    put('dist/%s.tar.gz' % dist, '/tmp/myapp.tar.gz')
    run('mkdir /tmp/myapp')

    with cd('/tmp/myapp'):
        run('tar xzf /tmp/myapp.tar.gz')
        run('/home/bjhee/virtualenv/bin/python setup.py install')

    run('rm -rf /tmp/myapp /tmp/myapp.tar.gz')
    run('touch /var/www/myapp.wsgi')
上例中,”package”任務是用來將應用程序打包,而”deploy”任務是用來將Python包安裝到遠程服務器的虛擬環境中,這里假設虛擬環境在”/home/bjhee/virtualenv”下。安裝完后,我們將”/var/www/myapp.wsgi”文件的修改時間更新,以通知WSGI服務器(如Apache)重新加載它。對於非WSGI服務器,比如uWSGI,這條語句可以省去。

編寫完后,運行部署腳本測試下:

$ fab package deploy

 使用中報錯解決

錯誤:No module named 'fabric.api'

主要是版本太新,選擇fabric2以下版本

錯誤:No module named 'fabric.api',原因---fabric(2.0新特性)
fabric經常出現在自動化運維領域,批量處理一些運維工作。fabric是在paramiko之上又封裝了一層,操作起來更加簡單易用。

 

  本來只是想寫個博客記錄一下,然后發現之前寫的代碼不能運行了,報以下錯誤:No module named 'fabric.api'

Traceback (most recent call last):
  File "D:/PycharmProjects/TestTool/Publish/fabric_sample.py", line 3, in <module>
    from fabric.api import *
ModuleNotFoundError: No module named 'fabric.api'
  然后百度了下,說是2.0以上的fabric版本已經移除了fabric.api,解決方法是指定安裝2.0以下的版本,比如pip install fabric==1.14.0  ~_~ ,但都並沒有介紹新的特性。然后去官網看了下文檔,使用方法如下:

 

1.連接服務器
  通過fabric.Connection方法連接服務器:

  conn = fabric.Connection(host , user = 'root',port = 22, config = None, geteway = None, connect_kwargs={"password": "123456"})

  Connection參數的含義:

復制代碼
復制代碼
  def __init__(
    self,
    host,                       #主機ip
    user=None,                  #用戶名
    port=None,                  #ssh端口,默認是22
    config=None,                #登錄配置文件
    gateway=None,               #連接網關
    forward_agent=None,         #是否開啟agent forwarding
    connect_timeout=None,       #設置超時
    connect_kwargs=None,        #設置 密碼登錄connect_kwargs={"password": "123456"}) 還是 密鑰登錄connect_kwargs={"key_filename": "/home/myuser/.ssh/private.key"}
    inline_ssh_env=None,      
    )
復制代碼
復制代碼
 

2.通過fabric安裝軟件
  下面通過一段代碼實現在Ubuntu上批量安裝docker,順序取走列表中的ip。

復制代碼
復制代碼
import fabric

def docker_install():
    for host in ['10.1.4.24',
                 '10.1.15.154',
                 '10.1.14.106']:
        conn = fabric.Connection(host , user = 'root', connect_kwargs={"password": "123456"})
        print("%s:" % host)
        conn.run("echo Y|apt-get remove docker.io")
docker_install()
復制代碼
復制代碼
  是不是很簡單,幾行代碼就解決了~

 

  cnn獲取Connetction對象后,有很多屬性方法可以使用,介紹下幾個常用的:

復制代碼
復制代碼
run:                #執行遠程命令,如:run('uname -a')

cd:                 #切換遠程目錄,如:cd('/root');   with conn.cd('/root'):繼承這個狀態

put:                #上傳本地文件到遠程主機,如:put('/root/test.py','/root/test.py')

get:                 #獲取服務器上文件,如:get('/root/project/test.log')

sudo:               #sudo方式執行遠程命令,如:sudo('service docker start')
復制代碼
復制代碼
   全部屬性:


 

  調用本地命令:

import invoke

invoke.run('uname -a')
錯誤:No module named 'fabric.api',原因---fabric(2.0新特性)

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM