推荐 远程部署 fabric

自己写的一个例子:

from fabric.api import run, env

env.hosts = [‘nanjing‘,‘hefei‘,‘haerbin‘,‘lanzhou‘,‘taiyuan‘,‘changchun‘]
env.user = ‘lmdata‘
env.password = ‘lmdata‘

def uptime():
    #run(‘ls -l /mnt/lustre/‘)
    run(‘uptime‘)

可以监控各个集群的性能,当然他的功能远不止此,还有很多很强大的技能,原文:  Python 远程部署利器 Fabric 详解

可以去原网址看,以下内容纯属备份,以防原文被删。

Python 远程部署利器 Fabric 详解

Fabric 是一个 Python 的库,它提供了丰富的同 SSH 交互的接口,可以用来在本地或远程机器上自动化、流水化地执行 Shell 命令。因此它非常适合用来做应用的远程部署及系统维护。其上手也极其简单,你需要的只是懂得基本的 Shell 命令。本文将为大家详细介绍 Fabric 的使用。

内容索引

安装 Fabric

首先 Python 的版本必须是 2.7 以上,可以通过下面的命令查看当前 Python 的版本:

$ python -V

Fabric 的官网是 www.fabfile.org,源码托管在 Github 上。你可以 clone 源码到本地,然后通过下面的命令来安装。

$ python setup.py develop

在执行源码安装前,你必须先将 Fabric 的依赖包 Paramiko 装上。所以,个人还是推荐使用 pip 安装,只需一条命令即可:

$ pip install fabric

第一个例子

万事从 Hello World 开始,我们创建一个”fabfile.py” 文件,然后写个 hello 函数:

1

2

def hello():

print "Hello Fabric!"

现在,让我们在”fabfile.py” 的目录下执行命令:

$ fab hello

你可以在终端看到”Hello Fabric!” 字样。

简单解释下,”fabfile.py” 文件中每个函数就是一个任务,任务名即函数名,上例中是”hello”。”fab” 命令就是用来执行”fabfile.py” 中定义的任务,它必须显式地指定任务名。你可以使用参数”-l” 来列出当前”fabfile.py” 文件中定义了哪些任务:

$ fab -l

任务可以带参数,比如我们将 hello 函数改为:

1

2

def hello(name, value):

print "Hello Fabric! %s=%s" % (name,value)

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

$ fab hello:name=Year,value=2016

Fabric 的脚本建议写在”fabfile.py” 文件中,如果你想换文件名,那就要在”fab” 命令中用”-f” 指定。比如我们将脚本放在”script.py” 中,就要执行:

$ fab -f script.py hello

执行本地命令

“fabric.api” 包里的”local()” 方法可以用来执行本地 Shell 命令,比如让我们列出本地”/home/bjhee” 目录下的所有文件及目录:

1

2

3

4

from fabric.api import local

def hello():

local(‘ls -l /home/bjhee/‘)

“local()” 方法有一个”capture” 参数用来捕获标准输出,比如:

1

2

def hello():

output = local(‘echo Hello‘, capture=True)

这样,Hello 字样不会输出到屏幕上,而是保存在变量 output 里。”capture” 参数的默认值是 False。

执行远程命令

Fabric 真正强大之处不是在执行本地命令,而是可以方便的执行远程机器上的 Shell 命令。它通过 SSH 实现,你需要的是在脚本中配置远程机器地址及登录信息:

1

2

3

4

5

6

7

8

from fabric.api import run, env

env.hosts = [‘example1.com‘, ‘example2.com‘]

env.user = ‘bjhee‘

env.password = ‘111111‘

def hello():

run(‘ls -l /home/bjhee/‘)

“fabric.api” 包里的”run()” 方法可以用来执行远程 Shell 命令。上面的任务会分别到两台服务器”example1.com” 和”example2.com” 上执行”ls -l /home/bjhee/” 命令。这里假设两台服务器的用户名都是”bjhee”,密码都是 6 个 1。你也可以把用户直接写在 hosts 里,比如:

1

env.hosts = [‘[email protected]‘, ‘[email protected]‘]

如果你的”env.hosts” 里没有配置某个服务器,但是你又想在这个服务器上执行任务,你可以在命令行中通过”-H” 指定远程服务器地址,多个服务器地址用逗号分隔:

$ fab -H [email protected],[email protected] hello

另外,多台机器的任务是串行执行的,关于并行任务的执行我们在之后会介绍。

如果对于不同的服务器,我们想执行不同的任务,上面的方法似乎做不到,那怎么办?我们要对服务器定义角色:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

from fabric.api import env, roles, run, execute, cd

env.roledefs = {

‘staging‘: [‘[email protected]‘,‘[email protected]‘],

‘build‘: [‘[email protected]‘]

}

env.passwords = {

‘staging‘: ‘11111‘,

‘build‘: ‘123456‘

}

@roles(‘build‘)

def build():

with cd(‘/home/build/myapp/‘):

run(‘git pull‘)

run(‘python setup.py‘)

@roles(‘staging‘)

def deploy():

run(‘tar xfz /tmp/myapp.tar.gz‘)

run(‘cp /tmp/myapp /home/bjhee/www/‘)

def task():

execute(build)

execute(deploy)

现在让我们执行:

$ fab task

这时 Fabric 会先在一台 build 服务器上执行 build 任务,然后在两台 staging 服务器上分别执行 deploy 任务。”@roles” 装饰器指定了它所装饰的任务会被哪个角色的服务器执行。

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

$ fab -R build deploy

这样”build” 和”staging” 角色的服务器都会运行”deploy” 任务了。注:”staging” 是装饰器默认的,因此不用通过”-R” 指定。

此外,上面的例子中,服务器的登录密码都是明文写在脚本里的。这样做不安全,推荐的方式是设置 SSH 自动登录,具体方法大家可以去网上搜搜。

SSH 功能函数

到目前为止,我们介绍了”local()” 和”run()” 函数分别用来执行本地和远程 Shell 命令。Fabric 还提供了其他丰富的功能函数来辅助执行命令,这里我们介绍几个常用的:

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

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

1

2

3

4

5

6

7

from fabric.api import env, sudo

env.hosts = [‘[email protected]‘, ‘[email protected]‘]

env.password = ‘111111‘

def hello():

sudo(‘mkdir /var/www/myapp‘)

    1. get(remote, local): 从远程机器上下载文件到本地

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

1

2

3

4

5

6

7

from fabric.api import env, get

env.hosts = [‘[email protected]‘,]

env.password = ‘111111‘

def hello():

get(‘/var/log/myapp.log‘, ‘myapp-0301.log‘)

上述任务将远程机上”/var/log/myapp.log” 文件下载到本地当前目录,并命名为”myapp-0301.log”。

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

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

1

2

3

4

5

6

7

from fabric.api import env, put

env.hosts = [‘[email protected]‘, ‘[email protected]‘]

env.password = ‘111111‘

def hello():

put(‘/tmp/myapp-0301.tar.gz‘, ‘/var/www/myapp.tar.gz‘)

上述任务将本地”/tmp/myapp-0301.tar.gz” 文件分别上传到两台远程机的”/var/www/” 目录下,并命名为”myapp.tar.gz”。如果远程机上的目录需要超级用户权限才能放文件,可以在”put()” 方法里加上”use_sudo” 参数:

1

put(‘/tmp/myapp-0301.tar.gz‘, ‘/var/www/myapp.tar.gz‘, use_sudo=True)

    1. prompt: 提示输入

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

1

2

3

4

5

6

7

8

from fabric.api import env, get, prompt

env.hosts = [‘[email protected]‘,]

env.password = ‘111111‘

def hello():

filename = prompt(‘Please input file name:‘)

get(‘/var/log/myapp.log‘, ‘%s.log‘ % filename)

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

1

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

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

Please input port number: [8080] 

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

    1. reboot: 重启服务器

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

1

2

3

4

5

6

7

from fabric.api import env, reboot

env.hosts = [‘[email protected]‘,]

env.password = ‘111111‘

def restart():

reboot(wait=60)

上面的 restart 任务将在一分钟后重启服务器。

上下文管理器

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

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

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

1

2

3

4

5

6

7

8

from fabric.api import env, cd, put

env.hosts = [‘[email protected]‘, ]

env.password = ‘111111‘

def hello():

with cd(‘/var/www/‘):

put(‘/tmp/myapp-0301.tar.gz‘, ‘myapp.tar.gz‘)

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

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

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

1

2

3

4

5

6

7

8

9

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

env.hosts = [‘[email protected]‘, ]

env.password = ‘111111‘

def hello():

with cd(‘/var/www/‘):

with lcd(‘/tmp/‘):

put(‘myapp-0301.tar.gz‘, ‘myapp.tar.gz‘)

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

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

1

2

3

4

5

6

7

8

9

from fabric.api import env, run, path

env.hosts = [‘[email protected]‘, ]

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 又回到原来的值。

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

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

1

2

3

4

5

6

7

8

from fabric.api import env, run, settings

env.hosts = [‘[email protected]‘, ]

env.password = ‘111111‘

def hello():

with settings(warn_only=True):

run(‘echo $USER‘)

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

    1. shell_env: 设置 Shell 环境变量

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

1

2

3

4

5

6

7

8

9

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

env.hosts = [‘[email protected]‘, ]

env.password = ‘111111‘

def hello():

with shell_env(JAVA_HOME=‘/opt/java‘):

run(‘echo $JAVA_HOME‘)

local(‘echo $JAVA_HOME‘)

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

1

2

3

4

5

6

7

8

9

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

env.hosts = [‘[email protected]‘, ]

env.password = ‘111111‘

def hello():

with prefix(‘echo Hi‘):

run(‘pwd‘)

local(‘pwd‘)

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

1

2

run(‘echo Hi && pwd‘)

local(‘echo Hi && pwd‘)

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

错误处理

默认情况下,Fabric 在任务遇到错误时就会退出,如果我们希望捕获这个错误而不是退出任务的话,就要开启”warn_only” 参数。在上面介绍”settings()” 上下文管理器时,我们已经看到了临时开启”warn_only” 的方法了,如果要全局开启,有两个办法:

    1. 在执行”fab” 命令时加上”-w” 参数
$ fab -w hello
    1. 设置”env.warn_only” 环境参数为 True

1

2

3

from fabric.api import env

env.warn_only = True

现在遇到错误时,控制台会打出一个警告信息,然后继续执行后续任务。那我们怎么捕获错误并处理呢?像”run()”, “local()”, “sudo()”, “get()”, “put()” 等 SSH 功能函数都有返回值。当返回值的”succeeded” 属性为 True 时,说明执行成功,反之就是失败。你也可以检查返回值的”failed” 属性,为 True 时就表示执行失败,有错误发生。在开启”warn_only” 后,你可以通过”failed” 属性检查捕获错误,并执行相应的操作。

1

2

3

4

5

6

7

8

9

10

11

from fabric.api import env, cd, put

env.hosts = [‘[email protected]‘, ]

env.password = ‘111111‘

def hello():

with cd(‘/var/www/‘):

upload = put(‘/tmp/myapp-0301.tar.gz‘, ‘myapp.tar.gz‘)

if upload.failed:

sudo(‘rm myapp.tar.gz‘)

put(‘/tmp/myapp-0301.tar.gz‘, ‘myapp.tar.gz‘, use_sudo=True)

并行执行

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

    1. 在执行”fab” 命令时加上”-P” 参数
$ fab -P hello
    1. 设置”env.parallel” 环境参数为 True

1

2

3

from fabric.api import env

env.parallel = True

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

1

2

3

4

5

6

7

8

from fabric.api import parallel

@parallel

def runs_in_parallel():

pass

def runs_serially():

pass

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

1

2

3

4

5

6

7

8

from fabric.api import serial

def runs_in_parallel():

pass

@serial

def runs_serially():

pass

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

补充

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

    • 终端输出带颜色

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

1

2

3

4

5

6

from fabric.colors import *

def hello():

print green("Successful")

print yellow("Warning")

print red("Error")

    • 限制任务只能被执行一次

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

1

2

3

4

5

6

7

8

9

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 的官方文档。本篇中的示例代码可以在这里下载

转载请注明出处: 思诚之道

原文地址:https://www.cnblogs.com/dahu-daqing/p/8475532.html

时间: 2024-11-07 05:44:23

推荐 远程部署 fabric的相关文章

图文详解远程部署ASP.NET MVC 5项目

原文:图文详解远程部署ASP.NET MVC 5项目 话外篇: 由于感觉自己的机器比较慢,配置不好,所以最近想把之前的项目部署到实验室的服务器上,但是由于常不在实验室,所以在想能不能远程部署.因此今天专门研究了一下具体的过程,下面和大家分享一下.本人新手,还望大虾勿喷,有什么问题,还望高手指点. 一.本文实验环境: Windows Server 2012 R2 SQL Server 2012 Express Visual Studio 2013 项目为:ASP.NET MVC 5.0,使用的是L

他们真的来了:PXE远程部署装机,进阶版kickstart无人值守装机(实验可跟做)

各位小伙伴今天给大家带来的是:PXE远程部署装机以及kickstart无人值守装机的内容,我们将从以下几点进行解析和实验 部署PXE远程安装服务: 1.搭建PXE远程安装服务器 2.验证PXE网络安装 实现Kickstart无人值守安装: 1.准备安装应答文件 2.实现批量自动装机 服务器的批量部署: 1.规模化:同时装配多台服务器 2.自动化:安装系统.配置各种服务 3.远程实现:不需要光盘.U盘等安装介质 PXE远程装机实验: 实验环境: 1.建议在局域网环境下使用(两台centos7,一台

Rsync守护进程方式远程部署

2.Rsync守护进程方式远程部署 以守护进程(Socket)的方式传输数据 操作系统: [[email protected] ~]# cat /etc/redhat-release  CentOS Linux release 7.3.1611 (Core)  内核版本: [[email protected] ~]# uname -r 3.10.0-514.el7.x86_64 主机网络参数设置: Hostname 网卡eth0 默认网关 用途 node1 192.168.1.71 192.16

WinServer远程部署系统(RDSystem)

系统简介 RemoteDeploySystem是一套BS结构的远程部署管理系统(简称RDSystem),可以通过浏览器上传web站点和windows服务的更新包到RDSystem服务器,然后对多个服务器同时进行分发和回滚,最重要的是可以管理多个AD域里的服务器.并且还可以远程回收应用程序池.停止启动windows服务.在线浏览下载删除每个站点或服务的文件.系统角色分为超级管理员.运维管理员.开发人员三类,开发人员只能看到自己参与的项目,分发回滚的权限可以被管理员控制.通过使用本系统彻底改善运维工

【2016-07-11】Qt远程部署失败,提示"没有那个文件或目录"的解决方法

首先明确一下,这里的部署失败与网络连接.ssh/scp/sftp等无关. 一般出现在删除了远端上的可执行文件,而本地程序未做明显改动时远程部署执行的时候. Qt应用程序输出中的提示信息如下: 究其原因,是因为程序编译结果未改变,Qt部署时自动跳过了上传文件的步骤,认为不必进行部署,看程序的编译输出所提示 的信息就知道了: 而导致这一看问题的根源,在于Qt构建和运行-运行设置-部署时默认使用了增量部署,将该默认选项去掉即可: 另外,为确保上传的是最新编译的程序,可添加自定义的远程命令将远端的可执行

Eclipse打包成jar,用于远程部署

使用eclipse的Export功能打包成可运行的jar包: 步骤如下: 在要打包的项目(或package)上右击,选择Export 在弹出的窗口中,选择java->Runnable JAR File, 然后点击next按钮 在Runnable JAR File Specification窗口中,选择Launch configuration和Export destination 点击Finish按钮,打包完成 部署jar程序: 进入jar所在的目录,命令行中输入: java -jar XXXX.

Maven Cargo 远程部署到tomcat7x

pom.xml中加入cargo的Plugin声明: 1 <plugin> 2 <groupId>org.codehaus.cargo</groupId> 3 <artifactId>cargo-maven2-plugin</artifactId> 4 <version>1.4.9</version> 5 <configuration> 6 <container> 7 <containerId&

Rsync远程部署

1,使用Rsync实现远程部署 #!/bin/bash cd /var/maven/pdh5/dev/pdh5 git checkout dev git pull origin dev rsync --exclude=*\.log --exclude=\.git* --exclude="log/" -avz /var/maven/pdh5/dev/pdh5/* [email protected]:/var/www/html/h5/pdh5

tomcat远程部署应用

Tomcat安装成功后,在ip地址:8080上就可以看见熟悉的首页,在这个首页中,上方有一个manage app按钮,点击就可以进行应用管理了.这样就不需要使用ftp把war包传上去了. 要想远程部署,需要更改两个地方,第一个地方比较容易发现,只要点击按钮,就会跳到一页,这页内容知道我们更改TOMCAT_HOME/conf/tomcat-users.xml目录,照着来就可以了. 仍旧发现无法访问manage app,这是因为tomcat 8.5以后的版本,默认manage app这个应用不许远程