Python 远程部署利器 Fabric2 模块

fabric 官网英文文档:http://www.fabfile.org/

《Python自动化运维技术与最佳实践》

如何用 Fabric 实现无密码输入提示的远程自动部署:

fabric实现远程操作和部署:

简介

Fabric 是一个 Python 的库,同时它也是一个命令行工具。它提供了丰富的同 SSH 交互的接口,可以用来在本地或远程机器上自动化、流水化地执行 Shell 命令。使用 fabric 提供的命令行工具,可以很方便地执行应用部署和系统管理等操作。因此它非常适合用来做应用的远程部署及系统维护。其上手也极其简单,你需要的只是懂得基本的 Shell 命令。

fabric 依赖于 paramiko 进行 ssh 交互,fabric 的设计思路是通过几个 API 接口来完成所有的部署,因此 fabric 对系统管理操作进行了简单的封装,比如执行命令,上传文件,并行操作和异常处理等。

paramiko 是一个用于做远程控制的模块,使用该模块可以对远程服务器进行命令或文件操作,fabric ansible 内部的远程管理就是使用的 paramiko 来现实。

fabric 简介 和 各个版本差异比较http://www.mamicode.com/info-detail-2337088.html

1、Python 官网发布的地址

2、区别

  • 1)Fabric1、Fabric和fabric2:Fabric 和 Fabric2 在 Pypi 中就是同一个东西,fabric2 只是 Fabric 的替代名称,为了便于使用备用名称进行安装。Fabric2 和之前的 Fabric1 相比,完全重写了,接口和功能都有很大改动,官网也不建议继续用 Fabric1,建议升级到 Fabric2。‘而最新版也早就支持 Python 3.4+、Python2.7 了。
  • 2)Fabric3:Fabric3 是非官网的,是之前使用 Fabric 时,没有支持 Python3 的版本,有人fork 出来,加了 Python3 的支持,但现在应该已经不维护了。

3、总结

尽量使用最新的 Fabric2。

Fabric 在升级 2.x 之后,几乎就是重写了。很多以前的用法都变了,然后在 1.x 时代,本地和远程都是用一套代码处理,但是 2.x 的时候将 local 处理部分和远程处理部分分别拆分为 fab 和 invoke了,拆分的理由可以参考 这里

忘记 1.x 的一切,然后从头开始

一、fabric2 模块使用

fabric2 是 python 的一个库,同时也是命令行工具,使用 fabric2 模块,可以方便的执行应用部署和系统管理等操作
fabric2 依赖于paramiko 进行 ssh 交互,fabric2 的设计思路是通过几个 API 接口来完成所有的部署

安装:pip install fabric2  -i "https://pypi.doubanio.com/simple/"

fabric2  的简单使用

from fabric2 import Connection


def deploy():
    # 如果服务器配置了ssh免密码登录,就不需要 connect_kwargs 来指定密码
    conn = Connection("root@192.168.44.13", connect_kwargs={"password": "123456"})
    conn.run("ls")

    with conn.cd('/home'):
        conn.run("mkdir testdir")
    with conn.cd('/home/testdir'):
        conn.run('mkdir aaa')
        conn.put('test', '/home/testdir')  # 上传文件


if __name__ == '__main__':
    deploy()

Connection 参数详解

def __init__(
        self,
        host,           # 主机 ip
        user=None,      # 用户名
        port=None,      # ssh 端口,默认 22
        config=None,    # 登录配置文件
        gateway=None,   # 连接网关
        forward_agent=None,     # 是否开启 agent forwarding
        connect_timeout=None,   # 设置超时
        connect_kwargs=None,    # 设置密码登录 connect_kwargs={"password": "123456"}
                                # 还是密钥登录 connect_kwargs={"key_filename": "/home/myuser/.ssh/id_rsa"}
        inline_ssh_env=None,
    )

conn 对象属性

run        # 执行远程命令,如:run('uname -a')
cd         # 切换远程目录,如:cd('/root'); with conn.cd('/root'),继承这个状态
put        # 上传本地文件到远程主机,如:put('/root/test.py','/root/test.py')
get        # 获取服务器上文件,如:get('/root/test.py')
sudo       # sudo方式执行远程命令,如: sudo('service docker start')
local      # 执行本地命令,如:conn.local('ls')

二、 fabric2 对多台机器使用

对多台机器使用时,Connection 

from fabric2 import Connection

for host in ('root@192.168.44.20','root@192.168.44.21','root@192.168.44.22'):
    result = Connection(host,connect_kwargs={'password':'123456'}).run('uname -s')
    print("{}: {}".format(host,result.stdout.strip()))

输出结果

Linux
root@192.168.44.20: Linux
Linux
root@192.168.44.21: Linux
Linux
root@192.168.44.22: Linux

对多台机器使用时,SerialGroup

from fabric2 import SerialGroup

pool = SerialGroup('root@192.168.44.20','root@192.168.44.21','root@192.168.44.22',connect_kwargs={'password':'123456'})
print(pool)
pool.run('uname -s')
for conn in pool:
    conn.run('mkdir testfiles')

扩展,运行本地命令

import invoke

invoke.run('ls')

三、使用示例:

From:https://www.walkerfree.com/article/183

import getpass
from fabric import Connection, task


@task
def pack(c):
    # 这里的c参数我理解为是Connection连接的本地 然后根据setup.py进行项目打包
    c.run('python setup.py release sdist --format=gztar')


@task
def deploy(c):
    # 输入服务器的登录用户名
    user = raw_input('Input login user name: ')
    # 输入服务器的登录地址
    host = raw_input('Input login host: ')
    # 输入服务器的项目目录地址
    root = raw_input('Input project root path:')
    # 输入服务器的登录密码
    user_pass = getpass.getpass('Input login user pass:')
    # 获取包的全名称
    result = c.run('python setup.py --fullname', hide=True)
    dist = result.stdout.strip()
    filename = '%s.tar.gz' % dist

    # 获取包的名称 - 这个名称可以根据自己的需求来自定义,这里主要是为了下面supervisor启动时使用
    result = c.run('python setup.py --name', hide=True)
    name = result.stdout.strip()

    # 远端服务器连接创建
    remote = Connection('%s@%s' % (user, host),
                        connect_kwargs={"password": user_pass})
    # 上传文件到远端服务器
    remote.put('./dist/%s' %
               filename, remote='%s' % root)

    # 在远端服务器上执行下面命令 - 这个会默认输出你在远端服务器展示的信息
    result = remote.run('cd %s &&\
     source .env/bin/activate &&\
        ls -al && type python &&\
         pip install %s &&\
         supervisorctl restart walkerfree' % (root, filename))

使用方式如下:fab pack deploy

这个命令其实也可以分布执行:
fab pack 
fab deploy

Fabric 自升级至2.x后,API大变,fab工具也逐渐边缘化,其编程方式也与普通的python脚本逐渐趋同。以下是Fabric1.x与2.x大致的差异与变化,用 python 脚本展示:

#!/bin/python
# coding:utf-8
from fabric import ThreadingGroup as Group
import ConfigParser

#fabric2.x不再支持1.x中的from fabric.colors import *方式在终端上输出有颜色的执行结果
#可以通过导入blessings包的方式来完成相关操作
from blessings import Terminal
t = Terminal()


def run_command(command_section, connection):
    for option in cf.options(command_section):
        #在shell中执行grep命令后,如果没有相关信息输出,grep的返回值为0,需要添加warn=True来
        #避免UnexpectedExit异常的触发
        result = connection.run(cf.get(command_section, option), warn=True)
        if option.find('grep', 0) != -1 and result.stdout == '':
            print(option + " exec complete!")


if __name__ == '__main__':
    #可以通过额外定义配置文件的方式,实现执行命名与脚本代码的分离
    cf = ConfigParser.ConfigParser()
    cf.read('command.conf')
    #以Group执行的方式也发生了变化,具体可参考api文档
    for aims_connection in Group('aims@10.99.1.24'):
        #通过红色加粗下划线的方式显示
        print t.red_underline_bold(str(aims_connection))
        run_command("common_command", aims_connection)
        run_command("aims_command", aims_connection)

    for ib_connection in Group('ibuser@10.99.1.27'):
        print t.red_underline_bold(str(ib_connection))
        run_command("common_command", ib_connection)
        run_command("ib_command", ib_connection)

配置文件:

[common_command]
df_command = df -h | awk 'NR > 1 && $5+0 > maxspace {maxspace = $5+0;name = $6} END { print name " has " maxspace"%"} '

[aims_command]
grep_syserror_command = grep -i error /var/log/syslog
grep_syswarn_command = grep -i warning /var/log/syslog

[ib_command]
jboss_warn = grep -i warn /opt/logs/services/jboss.log | grep -v 'null'

  • 15
    点赞
  • 63
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值