简介
fabric是一个Python的库,同时它也是一个命令行工具。使用fabric提供的命令行工具,可以很方便地执行应用部署和系统管理等操作。
fabric依赖于paramiko进行ssh交互,fabric的设计思路是通过几个API接口来完成所有的部署,因此fabric对系统管理操作进行了简单的封装,比如执行命令,上传文件,并行操作和异常处理等。

由于fabric比较特殊它还是一个命令行工具,可以通过help进行命令的了解


入门使用
fabric的典型使用方式就是,创建一个Python文件,该文件包含一到多个函数,然后使用fab命令调用这些函数。这些函数在fabric中成为task,下面是一个例子

PS:fab命令执行时,默认引用一个名为fabfile.py的文件,我们也可以通过-f来进行指定(文件名不能为abc.py,会冲突).
这里使用了三个fabric的封装:
run:用于执行远程命令的封装
sudo:以sudo权限执行远程命令
env:保存用户配置的字典(保存了相关的配置,比如登录用户名env.user,密码env.password,端口env.port等,如果没有指定用户名那么默认使用当前用户,端口使用22)

需要注意的是:
一次可以多个task,按照顺序执行: fab -f hello.py hostname ls
给task传递参数使用task:参数,多个参数按照位置进行传递(和Python相同,对于关键字的参数可以,在命令行中指定:fab ls:path=/home)
fabric的命令行参数
fab命令作为fabric程序的入口提供了,丰富的参数调用.

如下例子,不写一行代码获取所有主机的ip地址

常用的对象和方法介绍
介绍fabric中的env对象,以及其他的比如执行命令模块,上传文件等。
fabric中的env
env是一个全局唯一的字典,保存了Fabric所有的配置,在Fabric的实现中,他是一个_AttributeDict()对象,之所以封装成_AttributeDict()对象,是覆盖了__getattr__和__setattr__,使我们可以使用“对象.属性=值”的方式,操作字典。
我们可以通过源码的方式,查看env的配置参数,或者使用如下方式查看:

常用的env配置如下:
env.hosts:定义目标服务器列表
env.exclude_hosts:排除特定的服务器
env.user SSH:到远程服务器的用户名
env.port:远程服务器的端口号
env.key_filename:私钥文件的位置
env.password SSH:到远程服务器的密码
针对不同主机不同密码的情况,可以使用如下的方式:

fabric提供的命令
run():在远程服务器上执行Linux命令,还有一个重要的参数pty,如果我们执行命令以后需要有一个常驻的服务进程,那么就需要设置pty=False,避免因为Fabric退出导致进程的退出。
1run('service mysqld start',pty=False)
PS:执行完毕会返回输出的信息,我们可以定义变量接受,同时这个返回信息有一个方法return_code,当返回的是正确执行的结果时code为0,否则不为0

sudo():与run类似,使用管理员权限在远程服务器上执行shell命令,还有一个重要的参数pty,如果我们执行命令以后需要有一个常驻的服务进程,那么就需要设置pty=False,避免因为Fabric退出导致进程的退出。
local():用以执行本地命令,返回要执行的命令,local是对Python的Subprocess模块的封装,更负载的功能可以直接使用Subprocess模块,包含capture参数,默认为False,表示subprocess输出的信息进行显示,如果不想显示,那么指定capture=True即可

get():从远程服务器上获取文件,通过remote_path参数声明从何处下载,通过local_path表示下载到何处。remote_path支持通配符。
1get(remote_path='/etc/passwd',local_path='/tmp/passwd')
put():将本地的文件上传到远程服务器,参数与get相似,此外,还可以通过mode参数执行远程文件的权限配置。
1put(remote_path='/tmp/passwd1',local_path='/tmp/passwd',mode='0777')
reboot():重启远程服务器,可以通过wait参数设置等待几秒钟重启
1reboot(wait=30)
propmt():用以在Fabric执行任务的过程中与管理员进行交互,类似于python的input

fabric的上下文管理器
env中存储的是全局配置,有时候我们并不希望修改全局配置参数,只希望临时修改部分配置,例如:修改当前工作目录,修改日志输出级别等。
在fabric中我们可以通过上下文管理器临时修改参数配置,而不会影响全局配置。当程序进入上下文管理器的作用域时,临时修改就会起作用;当程序离开上下文管理器时,临时修改就会消失。
cd():切换远程目录

lcd():切换本地目录
path():配置远程服务器PATH环境变量,只对当前会话有效,不会影响远程服务器的其他操作,path的修改支持多种模式
append:默认行为,将给定的路径添加到PATH后面。
prepend:将给定的路径添加到PATH的前面。
replace:替换当前环境的PATH变量。

prefix():前缀,它接受一个命令作为参数,表示在其内部执行的代码块,都要先执行prefix的命令参数。

shell_env():设置shell脚本的环境变量

settings():通用配置,用于临时覆盖env变量

remote_tunnel():通过SSH的端口转发建立的链接

hide():用于隐藏指定类型的输出信息,hide定义的可选类型有7种
status:状态信息,如服务器断开链接,用户使用ctrl+C等,如果Fabric顺利执行,不会有状态信息
aborts:终止信息,一般将fabric当作库使用的时候需要关闭
warnings:警告信息,如grep的字符串不在文件中
running:fabric运行过程中的数据
stdout:执行shell命令的标准输出
stderr:执行shell命令的错误输出
user:用户输出,类似于Python中的print函数
为了方便使用,fabric对以上其中类型做了进一步的封装
output:包含stdout,stderr
everything:包含stdout,stderr,warnings,running,user
commands:包含stdout,running
show():与hide相反,表示显示指定类型的输出
quiet():隐藏全部输出,仅在执行错误的时候发出告警信息,功能等同于 with settings(hide('everything'),warn_only=True) .

装饰器
Fabric提供的命令一般都是执行某一个具体的操作,提供的上下文管理器一般都是用于临时修改配置参数,而fabric提供的装饰器,既不是执行具体的操作,也不是修改参数,而是控制如何执行这些操作,在那些服务器上执行这些操作,fabric的装饰器与人物执行紧密相关。下面从几个方面来进行说明
hosts:定制执行task的服务器列表
roles:定义执行task的role列表
parallel:并行执行task
serial:串行执行task
task:定义一个task
runs_once:该task只执行一次
fabric的task
task就是fabric需要在远程服务器上执行的函数,在fabric中有3中方法定义一个task
默认情况下,fabfile中每一个函数都是一个task。
继承自fabric的task类,这种方式比较难用,不推荐。
使用fabric的task装饰器,这是使用fabric最快速的方式,也是推荐的用法。

PS:默认情况下,fabfile中的所有函数对象都是一个task,但是如果我们使用了task装饰器,显示的定义了一个task,那么,其他没有通过task装饰器装饰的函数将不会被认为是一个task。
fabric的host
为了方便我们的使用,fabric提供了非常灵活的方式指定对哪些远程服务器执行操作,根据我们前面的知识,我们知道有两种方式:通过env.hosts来执行,或者在fab执行命令的时候使用-H参数,除此之外,还有以下需要注意的地方
指定host时,可以同时指定用户名和端口号: username@hostname:port
通过命令行指定要多哪些hosts执行人物:fab mytask:hosts="host1;host2"
通过hosts装饰器指定要对哪些hosts执行当前task
通过env.reject_unkown_hosts控制未知host的行为,默认True,类似于SSH的StrictHostKeyChecking的选项设置为no,不进行公钥确认。

fabric的role
role是对服务器进行分类的手段,通过role可以定义服务器的角色,以便对不同的服务器执行不同的操作,Role逻辑上将服务器进行了分类,分类以后,我们可以对某一类服务器指定一个role名即可。进行task任务时,对role进行控制。

当我们定义好role以后,我们就可以通过roles装饰器来指定在哪些role上运行task。

注意:hosts装饰器可以和roles装饰器一起使用(全集),看起来容易造成混乱,不建议混搭。
fabric的执行模型
fabric执行任务的步骤如下:
创建任务列表,这些任务就是fab命令行参数指定的任务,fab会保持这些任务的顺序
对于每个任务,构造需要执行该任务的服务器列表,服务器列表可以通过命令行参数指定,或者env.hosts指定,或者通过hosts和roles装饰器指定
遍历任务列表,对于每一台服务器分别执行任务,可以将任务列表和服务器列表看作是两个for循环,任务列表是外层循环,服务器列表是内存循环,fabric默认是串行执行的可以通过装饰器或者命令行参数确定任务执行的方式
对于没有指定服务器的任务默认为本地任务,仅执行一次
PS:关于并行模式:
通过命令行参数-P(--parallel)通知Fabric并行执行task
通过env.parallel设置设否需要并行执行
通过parallel装饰器通知Fabric并行执行task,它接受一个pool_size作为参数(默认为0),表示可以有几个任务并行执行
其他装饰器
前面介绍了task,hosts,roles和parallel装饰器,此外还有两个装饰器比较常用
runs_once:只执行一次,防止task被多次调用。例如,对目录打包进行上传,上传动作对不同的服务器可能会执行多次,但是打包的动作只需要执行一次即可。
serial:强制当前task穿行执行。使用该参数时优先级最高,即便是制定了并发执行的参数
常用的功能函数
fabric中还有其他的一些好用的函数。
封装task
fabric提供了一个execute函数,用来对task进行封装。它最大的好处就是可以将一个大的任务拆解为很多小任务,每个小任务互相独立,互不干扰。

utils函数
包含一些辅助行的功能函数,这些函数位于fabric.utils下,常用的函数如下:
abort:终止函数执行,打印错误信息到stderr,并且以退出码1退出。
warn:输出警告信息,但是不会终止函数的执行
puts:打印输出,类似于Python中的print函数

带颜色的输出
fabric为了让输出日志更具有可读性,对命令行中断的颜色输出进行了封装,使用print打印带有不同颜色的文本,这些颜色包含在fabric.colors中。像warn,puts打印输出的,也可以直接渲染颜色
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) 黄色

确认信息
有时候我们在某一步执行错误,会给用户提示,是否继续执行时,confirm就非常有用了,它包含在 fabric.contrib.console中

使用Fabric源码安装redis
下载一个redis的包和fabfile.py放在同级目录即可,不同目录需要修改包的位置,这里使用的是redis-4.0.9版本。

PS:关于set -m 的作用如下:
1"set -m" turns on job control, you can run processes in a separate process group.
理解:在一个独立的进程组里面运行我们的进程。
网友评论