Python模塊之Fabric


Fabric簡介

  Fabric是一個Python庫,可以通過SSH在多個host上批量執行任務。你可以編寫任務腳本,然后通過Fabric在本地就可以使用SSH在大量遠程服務器上自動運行。這些功能非常適合應用的自動化部署,或者執行系統管理任務。

官網:http://www.fabfile.org/

中文站點:http://fabric-chs.readthedocs.io/zh_CN/chs/

Fabric常用環境變量

   fabric的環境變量有很多,存放在一個字典中,fabric.state.env,而它包含在fabric.api中,為了方便,我們一般使用env來指代環境變量。env環境變量可以控制很多fabric的行為,一般通過env.xxx可以進行設置。

     fabric默認使用本地用戶通過ssh進行連接遠程機器,不過你可以通過env.user變量進行覆蓋。當你進行ssh連接時,fabric會讓你交互的讓你輸入遠程機器密碼,如果你設置了env.password變量,則就不需要交互的輸入密碼。

常用的環境變量:

>>> import fabric.api
>>> for i in fabric.api.env:
...     print(i)
... 
disable_known_hosts     # 默認是false,如果是true,則會跳過用戶知道的hosts文件
effective_roles
tasks
linewise
show
password          # 定義密碼
key_filename
abort_on_prompts
skip_unknown_tasks
reject_unknown_hosts
skip_bad_hosts                  # 默認false,為ture時,會導致fab跳過無法連接的主機
use_ssh_config 
roledefs          # 定義角色分組,例如:區分DB主機與web主機
gateway          # 定義網關(中轉,堡壘機)IP
gss_auth
keepalive
eagerly_disconnect
rcfile
path_behavior
hide
sudo_prefix
lcwd
no_agent
forward_agent
remote_interrupt
port          # 定義目標主機的端口
shell
version
use_exceptions_for
connection_attempts
hosts      # 定義目標主機
gss_deleg
cwd
abort_exception
real_fabfile
passwords      # 與password功能一致,區別在於不同主機不同密碼的應用場景
sudo_password
host_string
shell_env
always_use_pty
colorize_errors
exclude_hosts   # 排除指定主機
all_hosts
sudo_prompt
again_prompt
echo_stdin
user        # 定義ssh使用哪個用戶登錄遠程主機
gss_kex
command_timeout
path
local_user
combine_stderr
command_prefixes
dedupe_hosts
warn_only
no_keys
sudo_passwords
roles
fabfile
use_shell
host
pool_size
system_known_hosts
prompts
output_prefix
command
timeout        # 默認10 網絡連接的超時時間
default_port
ssh_config_path
parallel
sudo_user
ok_ret_codes

Fabric執行模式

執行策略:fabric默認是單一的,串行的執行函數,雖然有一個paralle模式可供你選擇。默認的行為遵循以下優先級規則:

  •  一個task列表被創建,通過命令行傳遞給fab
  •  針對每一個task,都有一個主機列表通過變量設置
  • task列表按順序執行每個task在主機列表中的主機上執行一遍
  • 如果主機列表為空,則默認在本地執行,也是執行一次

Fabric常用API

[root@bogon fabric]# python
Python 2.6.6 (r266:84292, Jul 23 2015, 14:41:34) 
[GCC 4.4.7 20120313 (Red Hat 4.4.7-11)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import tab
>>> import fabric.api
>>> for i in dir(fabric.api):
...     print(i)
... 
__builtins__
__doc__
__file__
__name__
__package__
abort
cd                 # 切換遠程目錄
env
execute
fastprint
get              # 從遠程主機下載文件到本地
hide 
hosts
lcd              # 切換本地目錄
local           # 執行本地命令     
open_shell
output
parallel
path
prefix
prompt          # 獲取用戶輸入信息
put               # 上傳本地文件到遠程主機
puts
quiet
reboot
remote_tunnel
require
roles
run                    # 執行遠程命令
runs_once          # 函數修飾符 標識的函數只會執行一次,不收多台主機影響
serial
settings
shell_env
show
sudo              # sudo方式執行遠程命令
task              # 函數修飾符,標識的函數為fab可以調用
warn
warn_only
with_settings             

API應用場景案例

案例1:同時查看本地及遠程主機信息

案例2:動態獲取遠程目錄列表

案例3:網關模式文件的上傳與下載

 

Fabric安裝及使用

Fabric安裝

pip install fabric
easy_install fabric
or
源碼安裝

fab命令默認被安裝到Python的目錄下,需要創建軟鏈接

[root@saltstack ~]# find / -type f -name "fab" 
/usr/local/python2.7.10/bin/fab
[root@saltstack ~]# ln -s /usr/local/python2.7.10/bin/fab /usr/bin/fab
[root@saltstack fabric]# fab -h
Usage: fab [options] <command>[:arg1,arg2=val2,host=foo,hosts='h1;h2',...] ...

Options:
  -h, --help            show this help message and exit
  -d NAME, --display=NAME print detailed info about command NAME
  -F FORMAT, --list-format=FORMAT formats --list, choices: short, normal, nested
  -I, --initial-password-prompt  Force password prompt up-front
  --initial-sudo-password-prompt  Force sudo password prompt up-front
  -l, --list            print list of possible commands and exit                   # 顯示一個腳本中可用的task(命令)
  --set=KEY=VALUE,...   comma separated KEY=VALUE pairs to set Fab env vars
  --shortlist           alias for -F short --list
  -V, --version         show program's version number and exit
  -a, --no_agent        don't use the running SSH agent
  -A, --forward-agent   forward local agent to remote end
  --abort-on-prompts    abort instead of prompting (for password, host, etc)
  -c PATH, --config=PATH specify location of config file to use
  --colorize-errors     Color error output
  -D, --disable-known-hosts  do not load user known_hosts file
  -e, --eagerly-disconnect disconnect from hosts as soon as possible
  -f PATH, --fabfile=PATH  python module file to import, e.g. '../other.py'   # 指定入口文件,fab默認入口文件是:fabfile/fabfile.py
  -g HOST, --gateway=HOST  gateway host to connect through      # 指定網關(中轉)設備,比如堡壘機環境,填寫堡壘機IP即可
  --gss-auth            Use GSS-API authentication
  --gss-deleg           Delegate GSS-API client credentials or not
  --gss-kex             Perform GSS-API Key Exchange and user authentication
  --hide=LEVELS         comma-separated list of output levels to hide
  -H HOSTS, --hosts=HOSTS   comma-separated list of hosts to operate on      # 指定host,支持多host逗號分開
  -i PATH               path to SSH private key file. May be repeated.
  -k, --no-keys         don't load private key files from ~/.ssh/
  --keepalive=N         enables a keepalive every N seconds
  --linewise            print line-by-line instead of byte-by-byte
  -n M, --connection-attempts=M make M attempts to connect before giving up
  --no-pty              do not use pseudo-terminal in run/sudo
  -p PASSWORD, --password=PASSWORD  password for use with authentication and/or sudo
  -P, --parallel        default to parallel execution method    # 以異步並行方式運行多主機任務,默認是串行
  --port=PORT           SSH connection port
  -r, --reject-unknown-hosts   reject unknown hosts
  --sudo-password=SUDO_PASSWORD  password for use with sudo only
  --system-known-hosts=SYSTEM_KNOWN_HOSTS  load system known_hosts file before reading user known_hosts
  -R ROLES, --roles=ROLES comma-separated list of roles to operate on    # 指定role,支持多個,即以角色名區分不同業務組設備
  -s SHELL, --shell=SHELL  specify a new shell, defaults to '/bin/bash -l -c'
  --show=LEVELS         comma-separated list of output levels to show
  --skip-bad-hosts      skip over hosts that can't be reached
  --skip-unknown-tasks  skip over unknown tasks
  --ssh-config-path=PATH   Path to SSH config file
  -t N, --timeout=N     set connection timeout to N seconds    # 設置設備連接超時時間(秒)
  -T N, --command-timeout=N  set remote command timeout to N seconds   # 設置遠程主機命令執行超時時間(秒)
  -u USER, --user=USER  username to use when connecting to remote hosts  
  -w, --warn-only       warn, instead of abort, when commands fail     # warn_only,默認是碰到異常直接abort退出,該設置為發出告警,但不退出
  -x HOSTS, --exclude-hosts=HOSTS  comma-separated list of hosts to exclude
  -z INT, --pool-size=INT  number of concurrent processes to use in parallel mode

 

Fabric應用案例

案例1:本地執行一組操作

# 直接用命令行的形式執行遠程命令
[root@bogon fabric]# fab -p 'strong' -H 192.168.80.128 -- 'uname -m'
[192.168.80.128] Executing task '<remainder>'
[192.168.80.128] run: uname -m
[192.168.80.128] out: i686
[192.168.80.128] out:


Done.
Disconnecting from 192.168.80.128... done.

[root@saltstack fabric]# cat fabric_8.py #!/usr/bin/env python # coding:utf-8 from fabric.api import local def prepare_deploy(): local("./manage.py test my_app") local("git add -p && git commit") local("git push") [root@saltstack fabric]# fab -f fabric_8.py prepare_deploy # 報錯是因為測試環境不足所致 [localhost] local: ./manage.py test my_app /bin/sh: ./manage.py: 沒有那個文件或目錄 Fatal error: local() encountered an error (return code 127) while executing './manage.py test my_app' Aborting.

 

案例2:遠程查看服務器類型

[root@saltstack fabric]# cat fabric_1.py  
#!/usr/bin/env python
# coding:utf-8

from fabric.api import run

def host_type():
    run('uname -s')

# 注:fabfile.py為fab默認識別的文件名,如果不是該文件名需要使用-f參數說明要執行的文件名
[root@saltstack fabric]# fab -H localhost -f fabric_1.py host_type              
[localhost] Executing task 'host_type'
[localhost] run: uname -s
[localhost] out: Linux
[localhost] out: 


Done.
Disconnecting from localhost... done.

案例3:遠程傳遞參數(本地執行原理一致)

[root@saltstack fabric]# cat fabric_2.py
#!/usr/bin/env python
# coding:utf-8

from fabric.api import run

def host_type(name):
    run('uname -s')
    print("Hello %s !!!" % name)

[root@saltstack fabric]# fab -H localhost -f fabric_2.py host_type:name=mads
[localhost] Executing task 'host_type'
[localhost] run: uname -s
[localhost] out: Linux
[localhost] out: 

Hello mads !!!

Done.
Disconnecting from localhost... done.

案例4:多台服務器批量執行相同的操作

[root@saltstack fabric]# cat fabric_3.py
#!/usr/bin/env python
# coding:utf-8

from fabric.api import run,cd,env,hosts
env.hosts=['192.168.20.140:22','172.16.1.150:22']   # env.hosts=['user@ip:port',] ssh要用到的參數格式
env.password='strong'

def host_type():
    with cd('/tmp/'):
        run('du -ksh *')

[root@saltstack fabric]# fab -f fabric_3.py host_type
[192.168.20.140:22] Executing task 'host_type'
[192.168.20.140:22] run: du -ksh *
[192.168.20.140:22] out: 36K    hsperfdata_rundeck
[192.168.20.140:22] out: 8.0K   pip-3wB4vO-unpack
[192.168.20.140:22] out: 4.0K   rundeck
[192.168.20.140:22] out: 4.0K   yum_save_tx-2016-07-30-20-49HgACou.yumtx
[192.168.20.140:22] out: 

[172.16.1.150:22] Executing task 'host_type'
[172.16.1.150:22] run: du -ksh *
[172.16.1.150:22] out: 4.0K     uname.txt
[172.16.1.150:22] out: 


Done.
Disconnecting from 172.16.1.150... done.
Disconnecting from 192.168.20.140... done.

案例5:多台服務器混合,需要在不同服務器進行不同操作時

[root@saltstack fabric]# cat fabric_4.py
#!/usr/bin/env python
# coding:utf-8

from fabric.api import env,roles,run,execute
 
env.roledefs = {
'server1': ['root@172.16.1.140:22',],
'server2': ['root@172.16.1.150:22', ]
}
 
env.password = 'strong'
@roles('server1')
def task1():
    run('ls /home/ -l | wc -l')
 
@roles('server2')
def task2():
    run('du -sh /home')
 
def test():               # 調節主機組和主機組執行操作的順序
    execute(task2)
    execute(task1)

[root@saltstack fabric]# fab -f fabric_4.py test
[root@172.16.1.150:22] Executing task 'task2'
[root@172.16.1.150:22] run: du -sh /home
[root@172.16.1.150:22] out: 4.0K        /home
[root@172.16.1.150:22] out: 

[root@172.16.1.140:22] Executing task 'task1'
[root@172.16.1.140:22] run: ls /home/ -l | wc -l
[root@172.16.1.140:22] out: 3
[root@172.16.1.140:22] out: 


Done.
Disconnecting from 172.16.1.150... done.
Disconnecting from 172.16.1.140... done.

 

擴展

擴展1:打印顏色

[root@saltstack fabric]# cat fabric_5.py
#!/usr/bin/env python
# coding:utf-8

from fabric.colors import *

def show():
    print green('success')
    print red('fail')
    print yellow('yellow')

[root@saltstack fabric]# fab -f fabric_5.py show
success
fail
yellow

Done.

效果圖:

擴展2:錯誤及異常

默認,一組命令,上一個命令執行失敗后,不會接着往下執行,失敗后也可以進行不一樣的處理,詳解文檔

# 默認情況
[root@saltstack fabric]# cat fabric_6.py
#!/usr/bin/env python
# coding:utf-8

#from fabric.api import run
from fabric.api import local

def host_type():
    local('uname -s')
    local('tt')
    local('hostname')
[root@saltstack fabric]
# fab -H localhost -f fabric_6.py host_type [localhost] Executing task 'host_type' [localhost] local: uname -s Linux [localhost] local: tt /bin/sh: tt: command not found Fatal error: local() encountered an error (return code 127) while executing 'tt' Aborting. # 注:由於tt執行報錯,后面的hostname命令沒有被執行 [root@saltstack fabric]# cat fabric_7.py #!/usr/bin/env python # coding:utf-8 from __future__ import with_statement from fabric.api import local, settings, abort from fabric.colors import * from fabric.contrib.console import confirm def host_type(): local('uname -s') with settings(warn_only=True): result = local('tt', capture=True) if result.failed and not confirm(red("tt cmd failed. Continue anyway?")): abort("Aborting at user request.") local('hostname') [root@saltstack fabric]# fab -H localhost -f fabric_7.py host_type [localhost] Executing task 'host_type' [localhost] local: uname -s Linux [localhost] local: tt Warning: local() encountered an error (return code 127) while executing 'tt' tt cmd failed. Continue anyway? [Y/n] y # 判斷上一步執行有無異常,異常給予提示,確認是否繼續 [localhost] local: hostname saltstack Done.

擴展3:密碼管理

1)Fabric既支持ssh公鑰認證也支持管理密碼的機制

2)Fabric的密碼管理機制提供了兩層密碼。如果你的server有相同的密碼,可以在env.password中設置默認的密碼;如果server密碼不同,還可以在env.passwords中設置(host,password)對,為每個server設置單獨的ssh密碼。

小結

  使用Fabric,你可以管理一系列host的SSH連接(包括主機名,用戶,密碼),定義一系列的任務函數,然后靈活的指定在哪些host上執行哪些任務。這非常使用於需要管理大量host的場景,比如運維,私有雲管理,應用自動化部署等。
  本文只是一篇入門文檔,遠沒有體現出Fabric的強大。實際上,Fabric還包括大量的功能,比如Role的定義,遠程交互及異常處理,並發執行,文件操作等,並且不僅僅局限於命令行方式,可以在你的應用中調用Fabric。
  希望本文能夠引起你對Fabric的興趣,並在你的實際應用中解決問題。

 


免責聲明!

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



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