设为首页 收藏本站
查看: 524|回复: 0

[经验分享] 自动化部署工具Fabric简介

[复制链接]
累计签到:2 天
连续签到:1 天
发表于 2016-1-28 08:28:53 | 显示全部楼层 |阅读模式
在持续集成/灰度发布越来越流行的今天,模块在预览或生产环境的部署流程自动化显得越来越重要。本文要介绍的Fabric就是一个帮助我们在上线时减少重复/繁琐操作的自动化部署利器,对于缺乏成熟运维平台的众多小公司的运维或开发人员来说,掌握这个工具是有必要的。
1. Fabric是什么

Fabric官方文档的描述如下:
Fabric is a Python (2.5-2.7) library and command-line tool for streamlining the use of SSH for application deployment or systems administration tasks.
具体来说,Fabric是一个Python库,只要目标机器支持ssh访问,就可以借助fabric来进行远程操作(如在host1上对host2远程运行shell命令),显然,由于fabric是个Python package,故其它Python package都可以被import到fabric特有的fabfile.py脚本中,这使得fabric如虎添翼,在功能的丰富程度和运维脚本的可维护性上,远远超过用shell实现的自动化部署脚本,更不要说与纯手工敲命令的上线方式相比所体现出的巨大优势了。

在系统运维和部署自动化领域,与fabric类似的工具还有很多(如Puppet, Chef),感兴趣的话,可以参考这篇文章48 Best Cloud Tools for Infrastructure Automation的介绍。

Fabric的安装非常方便,pip install fabric就可以搞定,这里不赘述。
2. Fabric支持的操作

Fabric支持的常用命令列出如下:
1)local
Run a command on the local system.
它是对subprocess模块的封装(Shell=True),可以通过设置Capture = True/False来捕获其执行结果。
2)run
Run a shell command on a remote host.
该命令的返回值包含了远程命令是否执行成功以及远程命令的返回码等信息。通过run执行命令时,通常会要求输入目标机器密码,如果对多台机器进行部署,可以通过设置env.passwords来避免手动输入密码,具体的设置方法会在下篇笔记中介绍。
3)get
Download one or more files from a remote host.
4)put
Upload one or more files to a remote host.
5)sudo
Run a shell command on a remote host, with superuser privileges.
功能与run操作类似,它可以对当前用户临时提权来执行某些需要root权限的命令。

此外,还有些不常用的命令(如:prompt, reboot, open_shell, require)这里没有列出,感兴趣的话,可以参考Fabric Operations文档。

需要特别注意的是,fabric通过run或sudo执行远程任务时,每次都会新建ssh连接,也即任务之间是不会耦合状态的,所以在实现需要多步操作的任务时,需要把多个命令放入同一行,命令间用逗号隔开。实例说明如下:
假设要在远程机器上cd至/home/work/tmp目录后创建test目录,则下面的命令无法实现预期目的:

run('cd /home/work/tmp')
run('mkdir test')  ## 第2次run会重新创建ssh连接,且不会记忆上次cd到的目录!!



需要用下面的命令来实现:

run('cd /home/work/tmp; mkdir test')





run('cd /home/work/tmp && mkdir test')


当然,还可以借助fabric提供的context manager来实现:

with cd('/home/work/tmp'):
    run('mkdir test')


关于fabric支持的context managers,还有很多强大且好玩的功能,请参考官方文档Fabric Context Managers,不会让你失望的。

上面介绍了fabric支持的元操作,那么如何基于这些操作实现复杂功能呢?
在fabric中,一组具有逻辑关系的操作通常被封装成一个task,fabric以task为粒度来执行命令,下面开始介绍如何定义task。
3. 在fabfile中定义tasks
3.1 fabfile是什么

根据fabric的约定,当运行例如”fab deploy”这样的命令时,fab会默认搜索名为fabfile.py的python文件或名为fabfile的package,故基于fabric的部署脚本通常以fabfile.py命名且应该位于当期工作目录下以便于fab进行搜索,在该文件中实现我们想要的任务即可。当然,如果要实现的部署任务比较复杂,这些任务也可以写在多个脚本中,统一置于fabric package下。关于fabfile的细节,可以参考官方文档Fabfile construction and use,这里不赘述。
3.2 定义task

在语法约定上,fabric有两种定义task的方式:
1)经典方式(classic method)
所有定义在fabfile中的可调用对象(如函数、类)均可被当作task被fab执行,这种方式不支持嵌套,也即:若fabfile.py中import了其它模块,则即使这些模块中定义了可调用对象,这些不是直接定义在fabfile中的可调用对象也不会被当作fab task。

以classic方式定义的task示例下(摘自Fabric Overview and Tutorial):

from fabric.api import local

def prepare_deploy():
    local("./manage.py test my_app")
    local("git add -p && git commit")
    local("git push")

  

上述示例代码在fabfile.py中定义了一个普通函数prepare_deploy,不难看出,其功能是在本地执行代码测试后,将本地的最新codebase更新到版本管理系统中以便后续以该codebase进行部署。

2)基于Task类的新风格task
从fabric 1.1开始,这种new-style的task定义方式被引入。该方式约定,所有的fab任务必须定义成Task类的实例或子类,其最大的优点是支持嵌套namespaces,也即,task可以定义在其它文件,fabfile.py通过import引入该文件后,定义在该文件的task也是可以被fab识别并支持的。

在new-style方式定义task的具体实现上,由2种方法:a. 定义一个继承自Task的子类并为其实现run()方法; b. 借助@task装饰器。示例分别如下:

class MyTask(Task):
    name = "deploy"  ## 指定task name,会在fab --list输出中显示
    def run(self, environment, domain="whatever.com"):
        run("git clone foo")
        sudo("service apache2 restart")

instance = MyTask()

  

上述示例与借助@task定义task的方式等价:

@task
def deploy(environment, domain="whatever.com"):
    run("git clone foo")
    sudo("service apache2 restart")

  

被@task装饰的函数默认继承自Task类,我们可以让函数继承自定义的类,具体的用法可以参考文档Defining tasks的”Using custom subclasses with @task”部分,这里只是抛砖引玉,不再赘述。

需要特别注意的是,这两种task的定义方式是互斥的!具体而言,如果fabric在fabfile或它import的文件中发现了基于Task类的new-style定义,那么,所有以classic方式定义的task(s)均会被fabric忽略。个人认为,如果要用fabric实现复杂系统的自动化部署,最好以new-style定义任务,因为这种方式支持嵌套namespace,可以用不同的脚本文件分层组织不同的任务,更方便维护。

备注:可以运行”fab –list”来查看fabric可以识别的任务。

完成task定义后,fabric是如何执行的?尤其是远程部署多台机器时,如何更好地管理这些机器(如角色、密码等)?

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-170409-1-1.html 上篇帖子: python 自动化部署工具Fabric简介 下篇帖子: Python闭包
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表