Python下Fabric的使用
来源:互联网 发布:linux挂载samba共享 编辑:程序博客网 时间:2024/05/26 05:50
文中部分内容整理自官方文档。如果文中出现错误,欢迎指出与交流。
Fabric是什么?
Fabric 是一个 Python的库和命令行工具,用来提高基于 SSH 的应用部署和系统管理效率。可以实现与远程服务器的自动化交互。Fabric底层基于paramiko模块。其特点即为简单高效,并且支持多线程。在需要运维数十台至几百台机器(视情况而定)的情况下非常好用。但如果需要运维上千台并不推荐使用Fabric,可以尝试使用saltstack。
Fabric的使用
在搞清Fabric的作用后,我们可以尝试通过一些简单的程序,来更加深入的了解Fabric。
注:文中实验环境均为Centos7.3。使用的python版本为python2.7。
安装Fabric模块
需要先安装paramiko模块(上文提到了,Fabric基于这个模块)。
#yum install gcc python-crypto python-devel python-paramiko -y
通过pip命令安装Fabric
#pip install fabric
如果没有pip命令,可以通过以下命令安装:
#yum install python-pip
至此Fabric模块就安装好了。
Hello Fabric
一个合格的教程,一定少不了hello world这个国际惯例:
#vim fabfile.py
注:fabric执行的时候会默认寻找当前路径下的fabfile.py文件。如果文件名为其它,需要在执行的时候通过
-f 文件名
的方式手动指定文件。
def hello(): print "hello world"
Fabric脚本执行并不使用python命令,而是使用fab命令(在安装模块时会一起安装)。所以这个脚本的执行方法为:
#fab hello #hello对应脚本中你想执行的函数名。Hello world!Done.
或
#fab -f 你的文件名 hello #此方法针对文件名不为fabfile时
至此我们便基于Fabric完成了一个非常简单的脚本,甚至连Fabric模块都不需要导入。但从中大家可以了解到Fabric脚本就是在文件中定义一个或多个函数,函数中是你要执行的任务。然后通过fab命令执行fabfile.py文件,执行你要执行的函数。
Fabric.api模块
Fabric.api是Fabric中最常用也是最核心的模块。可以使用此模块来实现与远程服务器的交互。简单的使用这些API就可以完成大部分应用场景的需求。
例子一:
注:Fabric基于paramiko模块,paramiko底层就是调用ssh命令来对远程主机进行管理。所以要使用Fabric来管理远程主机,要保证服务器端开启sshd服务,并且保证可以成功访问。
查看本地和远程主机的内核版本。
from fabric.api import * #导入fabric.api模块env.hosts= ['192.168.122.101','192.168.122.102','192.168.122.103'] #指定远端服务器的ip地址。如果有dns解析的也可以写主机名。env.password='indionce' #指定远端主机的密码,如果各个密码不相同可以使用一个字典指定,例如:env.password={“root@192.168.122.101”:"indionce"}def local_uname(): #定义一个本地任务的函数 local('uname -r')def remote_uname(): #定义一个远程任务的函数 run('uname -r')def uname(): #定义一个函数,将本地与远端组合起来使用 local_uname() remote_uname()
执行这个脚本会得到下面的结果(因为字数原因我只取了前两台主机的返回信息):
[root@Fabric ~]# fab uname [192.168.122.101] Executing task 'uname'[localhost] local: uname -r3.10.0-514.el7.x86_64[192.168.122.101] run: uname -r[192.168.122.101] out: 3.10.0-514.el7.x86_64[192.168.122.101] out: [192.168.122.102] Executing task 'uname'[localhost] local: uname -r3.10.0-514.el7.x86_64[192.168.122.102] run: uname -r[192.168.122.102] out: 3.10.0-514.el7.x86_64[192.168.122.102] out: .....
尽管我只保留了前两台主机的返回值,但是也可以从中发现。我有多少台主机,脚本便执行了多少次本地的uname -r
。在实际应用中,有很多类似内核信息的本地命令,我只需要执行一次。甚至多次执行会出现错误,这时我就需要使用@runs_once
来对函数进行修饰,具体使用也非常简单,如下:
@runs_once #指定下一行的函数在运行时,只运行一次。def local_uname(): local('uname -r')
新脚本执行之后就会发现本地的内核信息只输出了一次。
例子二
查看远程服务器的文件夹列表
from fabric.api import *@runs_once #一定要指定这一条,否则会让你输入多次路径def input(): return prompt("input path:") #prompt函数,让用户输入自己想要的路径,将输入的值返回到函数。def ls_path(dirname): #在定义函数的时候指定形参。 run("ls -l "+dirname)def go(): ls_path(input()) #使用input返回的值,用于ls_path()的参数
执行这个脚本
[root@name ~]# fab go [192.168.122.101] Executing task 'go'input path: /home #用户自己输入一个路径,然后到远端服务器查看这个路径下的文件[192.168.122.101] run: ls -l /home[192.168.122.101] out: total 4[192.168.122.101] out: -rw-r--r--. 1 root root 541 Jun 8 23:54 fatab[192.168.122.101] out: [192.168.122.102] Executing task 'go'[192.168.122.102] run: ls -l /home[192.168.122.102] out: total 4[192.168.122.102] out: -rw-r--r--. 1 root root 541 Jun 8 23:54 fatab[192.168.122.102] out: [192.168.122.103] Executing task 'go'[192.168.122.103] run: ls -l /home[192.168.122.103] out: total 4[192.168.122.103] out: -rw-r--r--. 1 root root 541 Jun 8 23:54 fatab[192.168.122.103] out:
故障处理
在执行任务中,难免出现命令执行失败的情况。而在日常使用中,肯定不会像我们测试时只执行一两条命令,一般都是一系列命令来共同完成一件事。如果其中一条命令执行失败,便会影响后续的命令。这个时候我们要让脚本停下来,以免出现更大的错误。
Fabric 会检查被调用程序的返回值,如果这些程序没有干净地退出,Fabric 会终止操作,下面我们就来看看如果一个测试用例遇到错误时会发生什么:
[root@Fabric ~]# fab uname [192.168.122.101] Executing task 'uname'[localhost] local: uname -rzzzuname:无效选项 -- zTry 'uname --help' for more information.Fatal error: local() encountered an error (return code 1) while executing 'uname -rzzz'Aborting.
太好了!我们什么都不用做,Fabric 检测到了错误并终止,不会继续执行接下来的任务。
如果我们想要更加灵活,给用户另一种选择,一个名为warn_only的设置就排上用场了。可以把退出换为警告,以提供更灵活的错误处理。具体如下:
from fabric.api import *from fabric.contrib.console import * #这个模块中包含confirmdef backup(): with settings(warn_only=True): #with命令表示执行这句后,执行下面的命令。使用settings命令来设置警告模式 state=local('mkdir /root/zz') #创建一个文件夹 if state.failed and not confirm("/root/zz is already exist,continue?"): #使用failed来判断state这条命令是否失败,失败了为真。confirm向用户确认是否继续,继续为真。如果命令失败了,并且用户希望停止,便通过if判断。 abort("退出任务") #abort是退出任务,有些类似python的exit。退出并且时返回给用户一串字符串 local('tar cavf /root/zz/etc.tar.gz /etc') #将etc的文件备份到/root/zz文件夹中
运行该文件得到下列结果,出现错误时向用户提示错误,用户可以视情况自行选择是否继续。
[root@Fabric ~]# fab mkdir[192.168.122.101] Executing task 'mkdir'[localhost] local: mkdir /root/zzmkdir: 无法创建目录"/root/zz": 文件已存在Warning: local() encountered an error (return code 1) while executing 'mkdir /root/zz'/root/zz is already exist,continue? [Y/n] aI didn't understand you. Please specify '(y)es' or '(n)o'./root/zz is already exist,continue? [Y/n]
跨网关的使用
实际使用中服务器的网关一帮的设有防火墙,我们无法直接ssh管理服务器。Fabric也提供给我们一种夸网关的使用方式。只需要在配置文件中定义好网关的ip地址即可,具体如下:
from fabric.api import *from fabric.contrib.console import confirmenv.user = "root"env.gateway = '10.0.0.1' #定义网关的地址env.hosts = ["10.0.0.2","10.0.0.3"]env.passwords = { 'root@10.0.0.1:22':'redhat', #需要定义网关的密码 'root@10.0.0.2:22':'redhat', 'root@10.0.0.3:22':'redhat'}
并行运行
开篇时便提到Fabric支持多线程,但之前运行结果中很明显可以看出先从101主机运行,运行结束后才在102主机上运行,以此类推。并没有并行运行
[root@name ~]# fab remote_uname[192.168.122.101] Executing task 'remote_uname'[192.168.122.101] run: uname -r[192.168.122.101] out: 3.10.0-514.el7.x86_64[192.168.122.101] out: [192.168.122.102] Executing task 'remote_uname'[192.168.122.102] run: uname -r[192.168.122.102] out: 3.10.0-514.el7.x86_64[192.168.122.102] out: [192.168.122.103] Executing task 'remote_uname'[192.168.122.103] run: uname -r[192.168.122.103] out: 3.10.0-514.el7.x86_64[192.168.122.103] out:
如何并行运行
由于并行执行影响的最小单位是任务,所以功能的启用或禁用也是以任务为单位使用 parallel 或 serial 装饰器。如下:
@parallel #将下面的函数设为并行执行。def runs_parallel(): run('uname -r')@serial #将下面的函数设为顺序执行(默认即为顺序执行 )def runs_serially(): pass
这样在执行时runs_parallel即为并行执行,serially为顺序执行。也可以在执行命令的时候指定:
#fab parallel -P #-P用来指定并行执行[192.168.122.103] run: uname -r[192.168.122.102] run: uname -r[192.168.122.101] run: uname -r[192.168.122.101] out: 3.10.0-514.el7.x86_64[192.168.122.101] out: [192.168.122.102] out: 3.10.0-514.el7.x86_64[192.168.122.102] out: [192.168.122.103] out: 3.10.0-514.el7.x86_64[192.168.122.103] out:
可以从上列返回值中很明显的看出并发执行与顺序执行的区别。
如果你的主机列表很多的时候,并行执行可能会分出几百个线程。这样对主机的压力是非常大的。这个时候需要限制线程的个数。默认是不限制的,即所有主机都会并发执行。可以使用pool_size来限制线程数。如下:
@parallel(pool_size=5) #将下面的函数设为并行执行,并且限制最多5个线程。def runs_parallel(): pass
输出管理
Fabric默认定义了几个输出层级:
在使用中,Fabric默认尽可能多的将信息显示出来。也就是上列信息都会输出到屏幕上。但有些时候我们并不需要在意这么多信息,而且过多的信息会使我们很难抓住重点。这时候我们可以通过hide和show来进行输出控制:
def my_task(): with hide('running', 'stdout', 'stderr'): #hide表示隐藏,下面的命令隐藏running,stdout,stderr输出 run('ls /var/www')
因为Fabric默认是打开所有输出的,show命令并不常用。但可以通过show命令开启debug模式:
def remote_uname(): with show("debug"): #打开debug输出,默认只有这项是关闭的 run('uname -r')
执行脚本:
[192.168.122.103] run: /bin/bash -l -c "uname -r"[192.168.122.102] run: /bin/bash -l -c "uname -r"[192.168.122.101] run: /bin/bash -l -c "uname -r"
之前的输出:
[192.168.122.103] run: uname -r[192.168.122.102] run: uname -r[192.168.122.101] run: uname -r
相比于之前的输出,可以看出命令提示更加完整。
更多关于fabric的信息与使用,可以查看官方文档http://www.fabfile.org/
- Python下Fabric的使用
- python fabric 库的学习使用
- python之使用Fabric自动化你的任务
- Fabric核心API的使用教程(配合python代码)
- 在windows下使用fabric
- 关于fabric-ca的使用
- python fabric
- 使用Fabric模块编写的批量同步文件的python脚本
- fabric使用
- fabric使用
- 使用Fabric自动化你的任务
- 使用Fabric自动化你的任务
- 使用Fabric自动化你的任务
- Fabric 1.0 Crypto Generator的使用
- Fabric 1.0 configtxgen Tool的使用
- Fabric自动化部署的简单使用
- 使用python Fabric动态修改远程机器hosts
- python使用Fabric模块实现自动化运维
- mysql存储引擎
- bzoj1030(dp+自动机)
- 深度学习之参数初始化(一)——Xavier初始化
- C++编程经验-返回局部变量的讨论
- (二)Java中Socket的用法-读书笔记
- Python下Fabric的使用
- final关键字在Java中的具体用法总结
- 机器学习中特征选择概述
- Codevs1515 跳
- MAC下想用ubuntu apt-get怎么办呢?
- tar 命令简单使用
- Tensorflow 在损失函数中加入正则项(Normalization)
- 两个有序数组的中位数
- 第3章 启程——Windows编程基础. 学习笔记