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 官网发布的地址

Fabric1:https://pypi.org/project/Fabric/

Fabric2:https://pypi.org/project/fabric2/

Fabric3:https://pypi.org/project/Fabric3/

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. 安装fabric2

Linux

sudo pip3 install fabric

如果是windows系统, 假设你下载安装的就是python3的软件, 那么当你使用 pip install 的时候, 这个pip 就是3的版本. 所以不需要再多设置

pip install fabric  -i "https://pypi.doubanio.com/simple/"

2. fabric2基础命令

1.Connection类

 conn = fabric.Connection(host , user = 'root',port = 22, config = None, geteway = None, connect_kwargs={"password": "123456"})

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/private.key"}
    inline_ssh_env=None,
    )

Conection类方法:

cnn获取Connetction对象后,有很多属性方法可以使用,介绍下几个常用的:

run:   #执行远程命令,如:run('uname -a')

cd:    #切换远程目录,如:cd('/root');   with conn.cd('/root'):继承这个状态

put:   #上传本地文件到远程主机,如:put('/root/test.py','/root/test.py')

get:    #获取服务器上文件,如:get('/root/project/test.log')

sudo:   #sudo方式执行远程命令,如:sudo('service docker start')

对多台机器使用时,Connection

import fabric
def get_hostname():
for host in ['192.168.2.250',
'192.168.2.224',
'192.168.2.219']:
conn = fabric.Connection(host, user='root', connect_kwargs={"password": "123456"})
print("%s:" % host)
conn.run("hostname")
get_hostname()

2. Group类

连接多个服务器,组成一个group,一个group同时执行run命令时,会返回一个 GroupResult-dict,包含了每个服务器的运行结果。

from fabric2 import SerialGroup

class fra_utils:
def get_Ip_BySC(self, *host):
pool = SerialGroup(*host, connect_kwargs={'password': '123456'})
pool.run('cd /opt && touch fabric2.txt') if __name__ == '__main__':
hosts = ('root@192.168.2.250', 'root@192.168.2.224')
results=fra_utils().get_Ip_BySC(*hosts)
for connection, result in results.items():
print("{0.host}: {1.stdout}".format(connection, result))

3. 扩展,运行本地命令

import invoke

invoke.run('ls')

3. 安装fabric3

pip install fabric3

4. fabric3基本命令

fab 语法

fab 是 fabric 程序的命令行入口,在命令行使用!!!,语法:

fab [options] <command>[arg1,arg2:val2,host=foo]

fab 命令的执行,默认依赖一个 fabfile.py 的文件,可以对该文件进行编辑,也可以执行其他的文件,用 -f 参数指定文件即可

fab 参数

可以使用 fab -help 查看具体参数:

-l,     显示定义好的任务函数名
-f, 指定 fab 入口文件,默认 fabfile.py
-g, 指定网关设备,比如堡垒机环境,填写堡垒机 ip 即可
-H, 指定目标主机,多台用逗号隔开
-P 以异步并行方式运行多主机任务,默认串行运行
-R, 指定 role,以角色名区分不同业务组设备
-t 设置设备连接超时时间
-T 设置远程主机命令执行超时时间
-w 当命令失败的时候,发出警告,而不是终止任务
-p 指定密码

fabric 常用 api

fabric 执行本地命令和远程命令,必须先导入 fabric 对应的 api 接口。

api调用方法

from fabric.api import *
env.hosts = 'localhost' def hello():
local('echo hello world') def check():
local('ls /Users/') def remote():
run('ping www.baidu.com')

env 全局环境变量

导入 env 变量

from fabric.api import env
env.hosts, 定义目标主机,多个主机用列表的形式体现
env.exclude_hosts, 排除指定的主机,env.exclude_hosts=['192.168.184.2'] env.user, 定义用户名
env.port, 定义目标主机端口 env.password, 定义密码
env.passwords, 与 password 功能一样,需要指定主机。env.passwords = {'user1@host':'password','user2@host':'password'} env.gateway, 定义网关(中转、堡垒机)IP env.roledefs, 定义角色分组。env.roledefs = {'webserver':['host1','host2'], 'dbserver':['db1','db2']} env.deploy_release_dir 自定义全局变量,env.deploy_release_dir, env.age, env.sex 等等

命令行执行

fab 依赖的 fabric.py 文件中创建函数。
import fabric.api def hello():
fabric.api.local('echo hello world') def check():
fabric.api.local('ls /Users/') def remote(cmd):
fabric.api.run(cmd)

在命令行执行命令的时候,使用 fab + fun函数即可。

$ fab hello
$ fab check

此时执行remote任务时,就要传入参数值:

$ fab remote:cmd='ifconfig'

执行远程命令

from fabric.api import *

env.user = 'root'
env.hosts = ['192.168.184.2', '192.168.184.22']
env.password = 'yourpassword'
env.passwords = {
'staging': '11111',
'build': '123456'
}
env.roledefs = {
'webserver': ['bjhee@example1.com','bjhee@example2.com'],
'dbserver': ['build@example3.com']
} @roles('webserver')
def remote_task():
with cd('/data/logs'): # with 的左右是让后面的表达式,继承前面的状态
run('ls -l') # 实现 'cd /data/logs/ && ls -l' 的效果 @roles('dbserver')
def remote_build():
with cd('/tmp/citizen_wang'):
run('git pull') def remote_deploy():
run('tar zxvf /tmp/fabric.tar.gz')
run('mv /tmp/fabric/setup.py /home/www/') def task():
execute(remote_build)
execute(remote_deploy)

如果不使用execute这个函数去执行remote_build,则remote_build只能用 【 fab -f fabric.py remote_build】的方式执行。用了execute后就可以用'python3 fabric.py'的方式执行了

命令行调用:

$ fab task
$ fab remote_build

如果某一任务上没有指定某个角色,但是你又想让这个角色的服务器也能运行该任务,你可以通过”-R”来指定角色名,多个角色用逗号分隔

$  fab -R webserver remote_deploy

SSH功能函数

1. sudo: 以超级用户权限执行远程命令

功能类似于”run()”方法,区别是它相当于在Shell命令前加上了”sudo”,所以拥有超级用户的权限。使用此功能前,你需要将你的用户设为sudoer,而且无需输密码。

from fabric.api import *

env.hosts = ['192.168.201.169']
env.password = '123456'
env.user = 'root' @task
def hello():
sudo('hostname') if __name__ == '__main__':
execute(hello)
  1. get(remote, local): 从远程机器上下载文件到本地

它的工作原理是基于scp命令,使用的方法如下:

@task
def get_file():
get('/opt/sun.txt', 'sun1.txt')

3.put(local, remote): 从本地上传文件到远程机器上

同get一样,put方法也是基于scp命令,使用的方法如下:

@task
def put_file():
put('sun1.txt', '/root')
  1. prompt: 提示输入

该方法类似于Shell中的”read”命令,它会在终端显示一段文字来提示用户输入,并将用户的输入保存在变量里:

@task
def download_file():
filename = prompt('请输入文件名:')
get('/opt/sun.txt', '%s.log' % filename)

现在下载后的文件名将由用户的输入来决定。我们还可以对用户输入给出默认值及类型检查:

port = prompt('Please input port number: ', default=8080, validate=int)

执行任务后,终端会显示:

Please input port number: [8080]

如果你直接按回车,则port变量即为默认值8080;如果你输入字符串,终端会提醒你类型验证失败,让你重新输入,直到正确为止

5. reboot: 重启服务器

看方法名就猜到了,有时候安装好环境后,需要重启服务器,这时就要用到”reboot()”方法,你可以用”wait”参数来控制其等待多少秒后重启,没有此参数则代表立即重启:

@task
def reboot_server():
reboot(wait=60)

上下文管理器

Fabric的上下文管理器是一系列与Python的”with”语句配合使用的方法,它可以在”with”语句块内设置当前工作环境的上下文。让我们介绍几个常用的:

1. cd: 设置远程机器的当前工作目录

“cd()”方法在之前的范例中出现过,”with cd()”语句块可以用来设置远程机的工作目录:

from fabric.api import env, cd, put

env.hosts = ['bjhee@example1.com', ]
env.password = '111111' def hello():
with cd('/var/www/'):
put('/tmp/myapp-0301.tar.gz', 'myapp.tar.gz')

上例中的文件会上传到远程机的”/var/www/”目录下。出了”with cd()”语句块后,工作目录就回到初始的状态,也就是”bjhee”用户的根目录

2. lcd: 设置本地工作目录

“lcd()”就是”local cd”的意思,用法同”cd()”一样,区别是它设置的是本地的工作目录:

from fabric.api import env, cd, lcd, put

env.hosts = ['bjhee@example1.com', ]
env.password = '111111' def hello():
with cd('/var/www/'):
with lcd('/tmp/'):
put('myapp-0301.tar.gz', 'myapp.tar.gz')

这个例子的执行效果跟上个例子一样。

3. path: 添加远程机的PATH路径

from fabric.api import env, run, path

env.hosts = ['bjhee@example1.com', ]
env.password = '111111' def hello():
with path('/home/bjhee/tmp'):
run('echo $PATH')
run('echo $PATH')

假设我们的PATH环境变量默认是”/sbin:/bin”,在上述”with path()”语句块内PATH变量将变为”/sbin:/bin:/home/bjhee/tmp”。出了with语句块后,PATH又回到原来的值。

2. settings: 设置Fabric环境变量参数

Fabric环境变量即是我们例子中一直出现的”fabric.api.env”,它支持的参数可以从官方文档中查到。

from fabric.api import env, run, settings

env.hosts = ['bjhee@example1.com', ]
env.password = '111111' def hello():
with settings(warn_only=True):
run('echo $USER')

我们将环境参数”warn_only”暂时设为True,这样遇到错误时任务不会退出。

3. shell_env: 设置Shell环境变量

可以用来临时设置远程和本地机上Shell的环境变量。

from fabric.api import env, run, local, shell_env

env.hosts = ['bjhee@example1.com', ]
env.password = '111111' def hello():
with shell_env(JAVA_HOME='/opt/java'):
run('echo $JAVA_HOME')
local('echo $JAVA_HOME')

4. prefix: 设置命令执行前缀

from fabric.api import env, run, local, prefix

env.hosts = ['bjhee@example1.com', ]
env.password = '111111' def hello():
with prefix('echo Hi'):
run('pwd')
local('pwd')

在上述”with prefix()”语句块内,所有的”run()”或”local()”方法的执行都会加上”echo Hi && “前缀,也就是效果等同于:

run('echo Hi && pwd')
local('echo Hi && pwd')

配合后一节我们会讲到的错误处理,它可以确保在”prefix()”方法上的命令执行成功后才会执行语句块内的命令。

并行执行

我们在介绍执行远程命令时曾提到过多台机器的任务默认情况下是串行执行的。Fabric支持并行任务,当服务器的任务之间没有依赖时,并行可以有效的加快执行速度。怎么开启并行执行呢?办法也是两个:

  1. 在执行”fab”命令时加上”-P”参数
 fab -P hello

​ 2. 设置”env.parallel”环境参数为True

from fabric.api import env

env.parallel = True

如果,我们只想对某一任务做并行的话,我们可以在任务函数上加上”@parallel”装饰器:

from fabric.api import parallel

@parallel
def runs_in_parallel():
pass def runs_serially():
pass

这样即便并行未开启,”runs_in_parallel()”任务也会并行执行。反过来,我们可以在任务函数上加上”@serial”装饰器:

from fabric.api import serial

def runs_in_parallel():
pass @serial
def runs_serially():
pass

这样即便并行已经开启,”runs_serially()”任务也会串行执行。

补充

这个部分用来补充Fabric的一些特别功能:

终端输出带颜色(Python3 好像不行)

我们习惯上认为绿色表示成功,黄色表示警告,而红色表示错误,Fabric支持带这些颜色的输出来提示相应类型的信息:

from fabric.colors import *

def hello():
print green("Successful")
print yellow("Warning")
print red("Error") 

限制任务只能被执行一次

通过”execute()”方法,可以在一个”fab”命令中多次调用同一任务,如果想避免这个发生,就要在任务函数上加上”@runs_once”装饰器。

from fabric.api import execute, runs_once

@runs_once
def hello():
print "Hello Fabric!" def test():
execute(hello)
execute(hello)

现在不管我们”execute”多少次hello任务,都只会输出一次”Hello Fabric!”字样

fabric基本使用的更多相关文章

  1. Azure Service Fabric 开发环境搭建

    微服务体系结构是一种将服务器应用程序构建为一组小型服务的方法,每个服务都按自己的进程运行,并通过 HTTP 和 WebSocket 等协议相互通信.每个微服务都在特定的界定上下文(每服务)中实现特定的 ...

  2. python10作业思路及源码:类Fabric主机管理程序开发(仅供参考)

    类Fabric主机管理程序开发 一,作业要求 1, 运行程序列出主机组或者主机列表(已完成) 2,选择指定主机或主机组(已完成) 3,选择主机或主机组传送文件(上传/下载)(已完成) 4,充分使用多线 ...

  3. MySQL: Fabric 搭建 HA

    搭建好Fabric之后,就可以在它的基础上创建HA Group. Shard Group.HA+Shard Group等.这里来说明一下如何快速的搭建HA环境. Fabric 192.168.2.23 ...

  4. MySQL:Fabric 安装

    MySQL Fabric安装 MySQL Fabric是Oracle提供的用于辅助进行ha\sharding的工具,它的基本架构: 从上面看出,借助于Fabric, 可以搭建 HA 集群.Sharin ...

  5. Fabric远程自动化使用说明

    背景: 关于Fabric的介绍,可以看官网说明.简单来说主要功能就是一个基于Python的服务器批量管理库/工具,Fabric 使用 ssh(通过 paramiko 库)在多个服务器上批量执行任务.上 ...

  6. MySQL Fabric和MyBatis的整合过程中遇到的问题

    这是我昨天在整合MySQL Fabric和MyBatis时遇到的问题,花了大半天才解决的问题,解决的过程中在网上查找了很久,都没有找到解决的方案.现在记下来,希望能够帮助有同样问题的朋友.如果各位朋友 ...

  7. FABRIC单机开发者模式启动

    在开始之前需要导出一个自定义变量,方便后续操作: export FABRIC=/opt/gopath/src/github.com/hyperledger/fabric/devenv 1.在真机上执行 ...

  8. fabric devenv Vagrantfile配置

    Vagrantfile文件只会在第一次执行vagrant up时调用执行,其后如果不明确使用vagrant reload,则不会被强制重新加载. # This is the mount point f ...

  9. python fabric install

    1,install setuptools 2,install pip 3,install pycrpto 4,install paramiko 5,install fabric

  10. [Python Fabric] [SSH] Mac OS X 10.9 + Vagrant虚拟环境使用Python Fabric进行SSH远程登录的简单实验

    1. ssh客户端生成key $ Generating public/private rsa key pair. Enter file in which to save the key (/Users ...

随机推荐

  1. 2023 PTA天梯赛补题(L1 & L2)

    2023 天梯赛 L1 & L2 补题 L1 L1-089 最好的文档 输入输出题 #include<bits/stdc++.h> using namespace std; int ...

  2. c++学习笔记(二):引用

    c++中的引用 引用变量是一个别名,也就是说,它是某个已存在变量的另一个名字.一旦把引用初始化为某个变量,就可以使用该引用名称或变量名称来指向变量. C++ 引用 vs 指针 引用很容易与指针混淆,它 ...

  3. git merge 详细操作,看完就懂

    [root@hostname git_test]# git init hint: Using 'master' as the name for the initial branch. This def ...

  4. Spark Dataframe 转 Json

    import org.apache.spark.sql.DataFrame import org.apache.spark.sql.functions._ import org.apache.spar ...

  5. ES6之常用开发知识点:let 和 const 命令详解(二)

    let命令 基本用法 { let a = 10; var b = 1; } a // ReferenceError: a is not defined. b // 1 根据上面结果显示,let声明的变 ...

  6. Redis入门 - C#|.NET Core封装Nuget包

    经过前面章节的学习,可以说大家已经算Redis开发入门了.已经可以去到项目上磨砺了. 但是今天我还想和大家分享一章:封装自己的Redis C#库,然后打包成Nuget包. 首先要说明的是:不是要自己开 ...

  7. QT6框架WebEngine模块之WebEngine总体介绍以及WebEngine能做什么?

    QT6框架WebEngine模块之WebEngine总体介绍以及WebEngine能做什么? 简介 本文简略介绍QT6框架WebEngine模块之WebEngine总体介绍以及WebEngine能做什 ...

  8. Flutter 3.3 正式发布

    Flutter 3 是我们正式为全平台提供支持的一个重量级里程碑,距离它的发布仅过去了三个月,今天让我们有请 Flutter 3.3 正式版!近三个月我们并没有放慢更新迭代的速度--自 Flutter ...

  9. 系统编程-进程-当fork遇到管道,可能碰撞出什么?

    第一部分 1. 直接上代码 #include <stdio.h> #include <unistd.h> #include <stdlib.h> int globv ...

  10. for循环遍历的盗版笔记

    遍历一个List有如下几种方法   5 6 是 java8 增强for循环底层由Iterator实现 增强for的出现时替代迭代器的,所以在遍历集合或者遍历数组就可以使用增强for去完成 增强for循 ...