介绍
Fabric 是一个基于 Python 的开源工具库,主要用于简化远程服务器的自动化操作(如部署、管理、批量执行命令等)。它通过封装 SSH 协议,让开发者可以用 Python 代码定义 “任务”,并批量在多台远程服务器上执行,避免了手动登录服务器逐个操作的繁琐流程。
用代码替代 “手动 SSH 登录服务器 → 输入命令 → 等待结果” 的重复工作,尤其适合需要管理多台服务器的场景(如集群部署、批量配置等)。
特点
- 基于 SSH 协议
- 任务自动化
- 支持多服务器与角色分组
- 并行执行
- Python 生态集成
应用场景
- 批量部署应用:同时向多台 Web 服务器推送代码、安装依赖、重启服务。
- 服务器监控:批量查看多台服务器的 CPU、内存、磁盘使用率。
- 配置管理:统一在多台服务器上修改配置文件、创建用户、设置权限。
- 日志收集:从多台服务器拉取日志文件到本地汇总分析。
版本说明
| 对比维度 | Fabric 1.X(官方旧版) | Fabric 2.X(官方现代版) | Fabric 3(非官方分支) |
|---|---|---|---|
| 官方定位 | 早期官方版本,已停止主动维护(仅安全补丁) | 官方推荐的当前版本(2.0+),又称 “现代版 Fabric” | 非官方分支(Fabric 1.X 的 Python 3 兼容补丁版) |
| Python 兼容性 | 仅支持 Python 2.5-2.7(不支持 Python 3) | 原生支持 Python 3.4+,兼容 Python 2.7(官方建议优先用 3.x) | 仅支持 Python 3(解决 1.X 的 Python 3 基础兼容,无高版本适配) |
| 安装方式 | pip install fabric==1.x(如 1.14.0) | pip install fabric(默认 2.x+);迁移用别名:pip install fabric2 | pip install fabric3(PyPI 第三方包,无官方源) |
| 核心架构 | 依赖全局env对象(如env.hosts)管理配置,耦合度高 | 模块化设计:拆分fabric(高层操作)、invoke(任务框架)、paramiko(SSH 底层);显式Connection对象管理连接,无全局状态 | 完全继承 1.X 架构,保留全局env,无架构重构 |
| 任务定义与执行 | 依赖@task装饰器,全局函数(如run/sudo)依赖env配置 | 支持@task装饰器,任务需传入Connection对象;支持命令行参数灵活传递 | 与 1.X 一致,无新特性,仅适配 Python 3 语法 |
| 并行任务支持 | 依赖@parallel装饰器,稳定性差,无批量控制 | 原生支持并行 / 串行(--parallel/--serial参数);SerialGroup/ParallelGroup类实现批量任务管理 | 继承 1.X 的@parallel,稳定性无改善 |
| 配置管理 | 仅通过全局env对象(如env.user/env.password) | 支持Config对象、fabric.yaml配置文件、环境变量,实现多环境隔离 | 仅支持全局env,无配置隔离能力 |
| 文件传输(上传 / 下载) | put/get功能基础,无断点续传等优化 | 增强put/get(支持断点续传、权限预设);支持远程目录递归操作 | 与 1.X 一致,无功能优化 |
| 错误处理 | 异常捕获能力弱,无明确的错误类型划分 | 细分错误类型(如CommandFailed/ConnectionError);支持上下文管理器(with Connection(...))安全处理连接 | 与 1.X 一致,无错误处理增强 |
| 维护支持 | 官方停止迭代(最后更新 2017 年),仅修复严重安全漏洞 | 官方持续维护(2024 年仍有版本更新),文档完善(官方文档) | 社区个人维护,无官方支持,2020 年后基本停更 |
| 生产环境适配性 | 不推荐(Python 2 终止支持,无安全更新保障) | 强烈推荐(稳定性高、安全更新及时、功能贴合生产需求) | 不推荐(无维护、隐性兼容性风险,仅临时过渡用) |
| 官方态度 | 已被 2.X 替代,建议迁移 | 官方唯一推荐版本,明确 “升级到 2.X 是强烈建议” | 官方明确否定:“未授权的 fork,无官方 3.x 计划” |
生产环境建议直接使用 Fabric 2.X,由于目前很多老的项目用是 Fabric 1.X 的版本,而且 Fabric 2.X 也兼容 1.X,所以下面我们先使用 Fabric 1.X 进行演示。
安装
- Fabric 1.14.0
- Paramiko 2.12.0
- Python 2.7.5
确保当前使用的版本是 python 2,然后执行下面的命令
pip install 'fabric<2.0'
常用参数
# fab --help 查看帮助
常用参数
-l 显示定义好的任务函数名
-f 指定fab入口文件,默认入口文件名为fabfile.py.. 即指定fabfile文件
-g 指定网关(中转)设备,即HOST逗号分隔要操作的主机, 比如堡垒机环境,填写堡垒机IP即可.
-H 指定目标主机,多台主机用‘,’号分隔
-p 远程账号的密码,fab执行时默认使用root账户
-P 以异步并行方式运行多主机任务,默认为串行运行
-R 指定role(角色),以角色名区分不同业务组设备
-t 设置设备连接超时时间(秒)
-T 设置远程主机命令执行超时时间(秒)
-w 当命令执行失败,发出警告,而非默认中止任务。
其他参数:
--set=KEY=VALUE,... 逗号分隔,设置环境变量
--shortlist 简短打印可用命令
-c PATH 指定本地配置文件
-D 不加载用户known_hosts文件
-i PATH 指定私钥文件
-k 不加载来自~/.ssh下的私钥文件
--port=PORT 指定SSH连接端口
-R ROLES 根据角色操作,逗号分隔
-s SHELL 指定新shell,默认是'/bin/bash -l -c'
--show=LEVELS 以逗号分隔的输出
--ssh-config-path=PATH SSH配置文件路径
-T N 设置远程命令超时时间,单位秒
-u USER 连接远程主机用户名
-x HOSTS 以逗号分隔排除主机
-z INT 并发进程数
常用方法
远程命令执行
| 方法 | 说明 |
|---|---|
run(command) | 在远程服务器上以当前用户权限执行命令(非 sudo),返回命令结果对象。 |
sudo(command) | 在远程服务器上以 sudo 权限执行命令(需输入密码,可通过 env.password 预设)。 |
local(command) | 在本地机器执行命令(非远程),常用于本地预处理(如打包代码)。 |
prompt(message) | 在本地终端提示用户输入信息(如密码、版本号),返回用户输入的字符串。 |
文件传输
| 方法 | 说明 |
|---|---|
put(local_path, remote_path) | 将本地文件 / 目录上传到远程服务器(remote_path 为目标路径)。 |
get(remote_path, local_path) | 将远程服务器文件 / 目录下载到本地(local_path 为本地保存路径)。 |
连接与环境配置
| 配置项 | 说明 |
|---|---|
env.hosts | 远程服务器列表,如 env.hosts = ['user@host1', 'user@host2:port']。 |
env.user | 登录远程服务器的用户名(默认使用本地当前用户)。 |
env.password | 远程服务器密码(或 sudo 密码),避免手动输入(明文不安全,建议用密钥)。 |
env.key_filename | SSH 私钥路径,如 env.key_filename = '~/.ssh/id_rsa'(密钥登录用)。 |
env.port | SSH 端口号(默认 22,非默认端口需指定)。 |
env.timeout | 连接超时时间(秒),如 env.timeout = 30。 |
env.parallel | 是否并行执行任务(默认 False,设为 True 可批量操作多服务器)。 |
上下文管理与装饰器
| 方法 / 装饰器 | 说明 |
|---|---|
cd(path) | 上下文管理器,临时切换远程工作目录(仅在 with 块内生效)。 |
settings(**kwargs) | 临时覆盖 env 配置,如 with settings(user='root'): run('whoami')。 |
prefix(command) | 为后续命令添加前缀(如激活虚拟环境:with prefix('source venv/bin/activate'))。 |
@task | 装饰器,标记函数为可通过 fab 命令调用的任务(如 @task def deploy(): ...)。 |
@roles(role_name) | 装饰器,指定任务仅在特定角色的服务器上执行(需先定义 env.roles)。 |
错误处理
| 方法 / 配置项 | 说明 |
|---|---|
warn_only | 设为 True 时,命令执行失败不会终止任务(默认 False,失败即终止)。 |
abort(message) | 手动终止任务并输出错误信息,如 if not result.succeeded: abort('命令失败')。 |
result.failed | 命令结果对象的属性,判断命令是否执行失败(run/sudo 返回的对象)。 |
result.succeeded | 判断命令是否执行成功。 |
快速开始
编写任务文件 fabfile.py
-f 指定fab入口文件,默认入口文件名为 fabfile.py
# 定义名为 hello 的任务
def hello():
print("Hello from Fabric!")
执行命令
fab hello
输出结果
Hello from Fabric!
带颜色的输出
fabric 为了让输出日志更具有可读性,对命令行中断的颜色输出进行了封装,使用print打印带有不同颜色的文本,这些颜色包含在fabric.colors中。
- blue(text,blod=False) 蓝色
- cyan(text,blod=False) 淡蓝色
- green(text,blod=False) 绿色
- magenta(text,blod=False) 紫色
- red(text,blod=False) 红色
- white(text,blod=False) 白色
- yellow(text,blod=False) 黄色
from fabric.api import *
from fabric.colors import *
from fabric.contrib.files import exists
def hello():
print("Hello from Fabric!")
warn(yellow('----->warn'))
print(green("green color"))
print(green("green blod color", True))
print(blue("blue color"))

带参数
def hello(name, value):
print("Hello Fabric! %s %s." % (name, value))
执行
fab hello:name=Year,value=2025
收集动态参数 prompt
prompt(message) 是用于在本地终端向用户获取输入的方法(类似 Python 内置的 raw_input()),常用来收集动态参数(如版本号、确认信息等)。
from fabric.api import prompt, task
def deploy():
# 提示用户输入部署版本
version = prompt("请输入部署版本号: ")
print("你输入的版本是: " + version)
# 执行部署逻辑(示例)
# run(f"deploy {version}")
def rollback():
# 提示用户输入回滚版本,默认回滚到上一版本
version = prompt("请输入回滚版本号(默认: previous): ", default="previous")
print(f"将回滚到版本: {version}")
def is_positive_number(input_str):
"""验证函数:检查输入是否为正整数"""
if input_str.isdigit() and int(input_str) > 0:
return True # 输入合法
else:
print("错误:请输入正整数!")
return False # 输入不合法,重新提示
def set_workers():
# 提示用户输入 worker 数量,必须为正整数
workers = prompt(
"请输入进程数量(正整数): ",
validate=is_positive_number # 绑定验证函数
)
print(f"已设置进程数量: {workers}")
执行本地命令之 local 方法
在当前目录下创建一个文件 fab.out,并写入字符串到文件中
from fabric.api import local
def taskA():
local('touch fab.out && echo "fabric" >> fab.out')
执行远程命令
from fabric.api import run, env
# env被称为环境字典,用来配置一些运行环境相关的信息
env.hosts = ['192.168.1.100', '192.168.1.101']
env.user = 'user'
env.password = 'passwd'
def taskA():
run('cd /usr/local/webserver/php && ls -l')
run('sudo /usr/local/webserver/nginx/sbin/nginx -t')
并行执行
Fabric 在多台机器上执行任务时默认情况下是串行的。Fabric支持在多台服务器上并行执行任务,并行可以有效的加快执行速度。开启并行执行有如下两个方法:
1. 在执行 fab 命令时加上-w参数
fab -P task
2. 设置env.parallel环境参数为True
from fabric.api import env
env.parallel = True
以上是对任务并行做一个全局控制。如果只想对某一个任务做并行的话,我们可以在任务函数上加上@parallel装饰器,这样即便全局并行未开启,被@parallel装饰的任务也会并行执行:
#-*- coding:utf-8 -*-
from fabric.api import env, run, parallel
env.hosts = ['10.216.224.65', '10.216.224.66']
env.key_filename = '~/.ssh/id_rsa'
@parallel
def taskA():
run('echo "parallel"')
def taskB():
run('echo "serial"')
假如全局并行已开启,我们想让某个任务串行执行,我们可以在任务函数上加上@serial装饰器,这样即便并行已开启,被@serial装饰的任务也会串行执行:
#-*- coding:utf-8 -*-
from fabric.api import env, run, serial
env.hosts = ['10.216.224.65', '10.216.224.66']
env.user = 'user'
env.key_filename = '~/.ssh/id_rsa_fabric'
env.parallel = True
def taskA():
run('echo "parallel"')
@serial
def taskB():
run('echo "serial"')
密码登录
env.hosts = ['10.10.10.01', '10.10.10.02']
env.user = 'user'
env.passwords = {
'root@10.10.10.01:22':'******',
'root@10.10.10.02:22':'******'
}
ssh 密钥登录
env.hosts = ['10.10.10.01', '10.10.10.02']
env.user = 'user'
env.port = 22 # 默认是 22
env.key_filename = '~/.ssh/id_rsa' # 私钥文件路径
服务器分组
env.roledefs = {
# 操作一致的放一组,一组执行同一个操作
'servers1':['10.10.10.01', '10.10.10.02'],
# 第二组
'servers2':['10.10.10.03', '10.10.10.04']
}
env.user = 'user'
env.port = 22 # 默认是 22
env.key_filename = '~/.ssh/id_rsa' # 私钥文件路径
env.parallel = True # 开启并行
def webtask():
run('/usr/local/nginx/sbin/nginx')
def dbtask():
run('uptime')
执行
fab -R servers1 webtask
部署案例
文件打包, 上传与校验
部署LNMP业务服务环境
生产环境代码包发布管理的配置
代码的自动化部署
总结
Fabric 是基于 Python 实现的 SSH 命令行工具,简化了 SSH 的应用程序部署及系统管理任务,它提供了系统基础的操作组件,可以通过 SSH 的方式与远程服务器进行自动化交互, 实现本地或远程 shell 命令,包括:命令执行、文件上传、下载及完整执行日志输出等功能。
相关链接
https://www.cnblogs.com/kevingrace/p/5570240.html