1. 程式人生 > >python fabric的用法

python fabric的用法

ESS 生成 exec only RoCE 單獨 public 配置 缺省

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 = {
[email protected]:22‘: ‘xxx‘,
[email protected]: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方式的身份認證,以便實現免密碼遠程執行任務。
---------------------
作者:slvher
來源:CSDN
原文:https://blog.csdn.net/slvher/article/details/50414675
版權聲明:本文為博主原創文章,轉載請附上博文鏈接!

python fabric的用法