- 本书赞誉
- 前言
- 第一部分 基础篇
- 第1章 系统基础信息模块详解
- 第2章 业务服务监控详解
- 第3章 定制业务质量报表详解
- 第4章 Python 与系统安全
- 第二部分 高级篇
- 第5章 系统批量运维管理器 pexpect 详解
- 第6章 系统批量运维管理器 paramiko 详解
- 第7章 系统批量运维管理器Fabric详解
- 第8章 从零开发一个轻量级 WebServer
- 第9章 集中化管理平台 Ansible 详解
- 第10章 集中化管理平台 Saltstack 详解
- 第11章 统一网络控制器 Func 详解
- 第12章 Python 大数据应用详解
- 第三部分 案例篇
- 第13章 从零开始打造 B/S 自动化运维平台
- 第14章 打造 Linux 系统安全审计功能
- 第15章 构建分布式质量监控平台
- 第16章 构建桌面版 C/S 自动化运维平台
7.3 fabfile 的编写
fab命令是结合我们编写的fabfile.py(其他文件名须添加-f filename引用)来搭配使用的,部分命令行参数可以通过相应的方法来代替,使之更加灵活,例如“-H 192.168.1.21,192.168.1.22”,我们可以通过定义env.hosts来实现,如“env.hosts=['192.168.1.21','192.168.1.22']”。fabfile的主体由多个自定义的任务函数组成,不同任务函数实现不同的操作逻辑,下面详细介绍。
7.3.1 全局属性设定
evn对象的作用是定义fabfile的全局设定,支持多个属性,包括目标主机、用户、密码、角色等,各属性说明如下:
env.host,定义目标主机,可以用IP或主机名表示,以Python的列表形式定义,如env.hosts=['192.168.1.21','192.168.1.22']。
env.exclude_hosts,排除指定主机,如env.exclude_hosts=['192.168.1.22']。
env.user,定义用户名,如env.user="root"。
env.port,定义目标主机端口,默认为22,如env.port="22"。
env.password,定义密码,如env.password='KSJ3548t7d'。
env.passwords,与password功能一样,区别在于不同主机不同密码的应用场景,需要注意的是,配置passwords时需配置用户、主机、端口等信息,如:
env.passwords = { 'root@192.168.1.21:22': 'SJk348ygd', 'root@192.168.1.22:22': 'KSh458j4f', 'root@192.168.1.23:22': 'KSdu43598' }
env.gateway,定义网关(中转、堡垒机)IP,如env.gateway='192.168.1.23'。
env.deploy_release_dir,自定义全局变量,格式:env.+“变量名称”,如env.deploy_release_dir、env.age、env.sex等。
env.roledefs,定义角色分组,比如web组与db组主机区分开来,定义如下:
env.roledefs = { 'webservers': ['192.168.1.21', '192.168.1.22', '192.168.1.23', '192.168.1.24'], 'dbservers': ['192.168.1.25', '192.168.1.26'] }
引用时使用Python修饰符的形式进行,角色修饰符下面的任务函数为其作用域,下面来看一个示例:
@roles('webservers') def webtask: run('/etc/init.d/nginx start') @roles('dbservers') def dbtask: run('/etc/init.d/mysql start') @roles ('webservers', 'dbservers') def pubclitask: run('uptime') def deploy: execute(webtask) execute(dbtask) execute(pubclitask)
在命令行执行#fab deploy就可以实现不同角色执行不同的任务函数了。
7.3.2 常用API
Fabric提供了一组简单但功能强大的fabric.api命令集,简单地调用这些API就能完成大部分应用场景需求。Fabric支持常用的方法及说明如下:
local,执行本地命令,如:local('uname-s');
lcd,切换本地目录,如:lcd('/home');
cd,切换远程目录,如:cd('/data/logs');
run,执行远程命令,如:run('free-m');
sudo,sudo方式执行远程命令,如:sudo('/etc/init.d/httpd start');
put,上传本地文件到远程主机,如:put('/home/user.info','/data/user.info');
get,从远程主机下载文件到本地,如:get('/data/user.info','/home/root.info');
prompt,获得用户输入信息,如:prompt('please input user password:');
confirm,获得提示信息确认,如:confirm("Tests failed.Continue[Y/N]?");
reboot,重启远程主机,如:reboot;
@task,函数修饰符,标识的函数为fab可调用的,非标记对fab不可见,纯业务逻辑;
@runs_once,函数修饰符,标识的函数只会执行一次,不受多台主机影响。
下面结合一些示例来帮助大家理解以上常用的API。
7.3.3 示例1:查看本地与远程主机信息
本示例调用local方法执行本地(主控端)命令,添加“@runs_once”修饰符保证该任务函数只执行一次。调用run方法执行远程命令。详细源码如下:
【/home/test/fabric/simple1.py】
#!/usr/bin/env python from fabric.api import * env.user='root' env.hosts=['192.168.1.21','192.168.1.22'] env.password='LKs934jh3' @runs_once #查看本地系统信息,当有多台主机时只运行一次 def local_task: #本地任务函数 local("uname -a") def remote_task: with cd("/data/logs"): #“with”的作用是让后面的表达式的语句继承当前状态,实现 run("ls -l") # “cd /data/logs && ls -l”的效果
通过fab命令分别调用local_task任务函数运行结果如图7-2所示。
图7-2 调用local_task任务函数运行结果
结果中显示了“[192.168.1.21]Executing task'local_task'”,但事实上并非在主机192.168.1.21上执行任务,而是返回Fabric主机本地“uname-a”的执行结果。
调用remote_task任务函数的执行结果如图7-3所示。
图7-3 调用remote_task任务函数运行结果
7.3.4 示例2:动态获取远程目录列表
本示例使用“@task”修饰符标志入口函数go对外部可见,配合“@runs_once”修饰符接收用户输入,最后调用worktask任务函数实现远程命令执行,详细源码如下:
【/home/test/fabric/simple2.py】
#!/usr/bin/env python from fabric.api import * env.user='root' env.hosts=['192.168.1.21','192.168.1.22'] env.password='LKs934jh3' @runs_once #主机遍历过程中,只有第一台触发此函数 def input_raw: return prompt("please input directory name:",default="/home") def worktask(dirname): run("ls -l "+dirname) @task #限定只有go函数对fab命令可见 def go: getdirname = input_raw worktask(getdirname)
该示例实现了一个动态输入远程目录名称,再获取目录列表的功能,由于我们只要求输入一次,再显示所有主机上该目录的列表信息,调用了一个子函数input_raw同时配置@runs_once修饰符来达到此目的。
执行结果如图7-4所示。
图7-4 程序运行结果
7.3.5 示例3:网关模式文件上传与执行
本示例通过Fabric的env对象定义网关模式,即俗称的中转、堡垒机环境。定义格式为“env.gateway='192.168.1.23'”,其中IP“192.168.1.23”为堡垒机IP,再结合任务函数实现目标主机文件上传与执行的操作,详细源码如下:
【/home/test/fabric/simple3.py】
#!/usr/bin/env python from fabric.api import * from fabric.context_managers import * from fabric.contrib.console import confirm env.user='root' env.gateway='192.168.1.23' #定义堡垒机IP,作为文件上传、执行的中转设备 env.hosts=['192.168.1.21','192.168.1.22'] #假如所有主机密码都不一样,可以通过env.passwords字典变量一一指定 env.passwords = { 'root@192.168.1.21:22': 'LKs934jh3', 'root@192.168.1.22:22': 'LKs934jh3', 'root@192.168.1.23:22': 'UI7384hg6' #堡垒机账号信息 } lpackpath="/home/install/lnmp0.9.tar.gz" #本地安装包路径 rpackpath="/tmp/install" #远程安装包路径 @task def put_task: run("mkdir -p /tmp/install") with settings(warn_only=True): result = put(lpackpath, rpackpath) #上传安装包 if result.failed and not confirm("put file failed, Continue[Y/N]?"): abort("Aborting file put task!") @task def run_task: #执行远程命令,安装lnmp环境 with cd("/tmp/install"): run("tar -zxvf lnmp0.9.tar.gz") with cd("lnmp0.9/"): #使用with继续继承/tmp/install目录位置状态 run("./centos.sh") @task def go: #上传、安装组合 put_task run_task
示例通过简单的配置env.gateway='192.168.1.23'就可以轻松实现堡垒机环境的文件上传及执行,相比paramiko的实现方法简洁了很多,编写的任务函数完全不用考虑堡垒机环境,配置env.gateway即可。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论