python fabric的用法

2022-09-23 04:32:04 字數 4650 閱讀 3227

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')12

3456

789在終端執行fab –list時,我們會看到taska和taskb兩個任務,執行之:

$ fab taska taskb

1結果示例如下:

taska executed on host1

taska executed on host2

taskb executed on host1

taskb executed on host212

34通過上面的例項,大家應該可以明白fabric預設的序列執行策略是怎麼回事。

fabric還允許我們指定以並行方式(藉助multiprocessing模組實現多個程序並行執行)在多臺機器上並行地執行任務,甚至還可在同一個fabfile檔案中指定某些task以並行方式執行,而某些task以預設的序列方式執行。具體地,可以藉助@parallel或@serial指定任務的執行模式,還可以在命令列中通過-p引數指定任務是否要並性執行。示例如下:

from fabric.api import *

@parallel

def runs_in_parallel():

pass

def runs_serially():

pass12

3456

78當執行如下命令時:

$ 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 host312

34此外,還可以通過對@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由[email protected]:port三部分構成,其中username和port部分可以預設。本篇筆記前面的第1個**例項其實已經說明了如何用env.hosts全域性地指定task的目標機器列表,這裡不再贅述。

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

from fabric.api import env

env.roledefs = ,

'db':

}@roles('web')

def mytask():

run('ls /var/www')12

3456

78910

1112

1314

上例通過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')12

3456

此時,當我們執行”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')12

345或者:

my_hosts = ('host1', 'host2')

@hosts(my_hosts)

def mytask():

# ...12

34每個任務的@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必須由[email protected]:port三部分構成,缺一不可,否則執行時還是會要求輸入密碼

env.passwords =

@hosts('10.123.11.209', '10.123.11.210')

def host_os_type():

run('uname -a')12

3456

78910

1112

1314

由於通過env.passwords配置了目標機器的登入使用者名稱/密碼,所以,當我們在終端執行fab host_os_type時,會發現不用手動輸入密碼了,大大方便了指令碼遠端自動執行。

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

Python Fabric模組詳解

python fabric模組詳解 簡單介紹一下 fabric是一個python的庫和命令列工具,用來提高基於ssh的應用部署和系統管理效率...

python三大神器之fabric

fabric是一個python的遠端執行shell的庫,同時它也是一個命令列工具。它提供了豐富的同 ssh 互動的介面,可以用來在本地或遠端...

python with as的用法

with語句是什麼? 有一些任務,可能事先需要設定,事後做清理工作。對於這種場景,python的with語句提供了一種非常方便的處理方式。一...