阿里云-云小站(无限量代金券发放中)
【腾讯云】云服务器、云数据库、COS、CDN、短信等热卖云产品特惠抢购

自动化运维工具Fabric – 角色管理以及并行执行

225次阅读
没有评论

共计 3332 个字符,预计需要花费 9 分钟才能阅读完成。

注:该文编写是结合了 Fabric 官方文档中的 defing-host-lists 以及 parallel execution 这两个章节来写的

当我们需要批量管理不同功能的服务器的时候,为了让不同功能的服务器执行不同的命令,这时候就需要用到 Fabric 的 Roles 的 env.roledefs 这个功能,

角色管理

主机字符串匹配单个主机,但是有时候根据主机分组是非常有用的。或许你有一组在负载均衡下的 Web 服务器,并且你想对它们做全部更新操作,或者是在所有的客户端服务器上运行一个任务。Roles 提供了一种正确给主机字符串分组的字符串定义方式,能通过该字符串代替整个主机组。

这个映射被定义成字典的方式。env.roledefs 为了被使用,必须在 fabfile 中被定义。下面是一个简单的例子:

from fabric.api import env

env.roledefs['webservers'] = ['www1', 'www2', 'www3']

因为 env.roledefs 默认是是空值。或许你需要选择重新分配值而不用为丢失任何信息而担心(当你在修改它的时候得保证你没有加载其他任何的 fabflies)。

from fabric.api import env

env.roledefs = {'web': ['www1', 'www2', 'www3'],
    'dns': ['ns1', 'ns2']
}

除了列表目标主机的类型之外,env.roledefs 的值是立即生效的。当在查找以及代替模块加载时间在运行的时候就被调用了(and will thus be called when looked up when tasks are run instead of at module load time)【注:求高手正确翻译】。(例如,你可以连接远程服务器取得角色定义,并且在被调用的时候不用担心在 fabfile 文件加载的时候引起延迟。比如:fab --list)。
使用 roles 没有任何其他要求 — 它仅仅是在你有服务器分组需求的情况下能提供一种便利的方式。

个人实践并且在生产应用了的代码,修改后删减如下:

#!/usr/bin/Python env
from fabric.api import env
from fabric.api import run
from fabric.api import roles
from fabric.api import execute
#from fabric.context_managers import execute




#env.user = 'username'
env.password = 'password'
env.roledefs = {'test1': ['host1', 'host2'],
    'test2': ['host3', 'host4']
}

@roles('test1') 
def get_version():
    run('cat /etc/issue')

@roles('test2')
def get_host_name():
    run('hostname')

def execute_all():
   execute(get_version)
   execute(get_host_name)

当你想在 web1 组里面只执行一台服务器的时候,你可以使用 env.exclude_hosts 或者是 -x 这个命令行参数来排除

env.exclude_hosts=['host1']

fab -R web1 -x host1,host5 get_version

这样执行的时候就会把 host1 这台服务器给排除在外了。

并行执行

Fabric 默认是串行执行的 (更多细节请参考 Execution strategy)。这个部分描述了在多个主机上并行执行任务的选择。可以通过每个任务的装饰器或者是命令行的全局开关来处理。

注:该功能只在 1.3 以及以后版本有。

因为 Fabric 1.x 默认不是线程安全的(并且因为在一般情况下,任务功能之间不会相互影响)这个功能是通过 Python 的 multiprocessing 模块实现的。它为每一个任务以及主机组合创建了一个新的线程。随意的使用了滑动窗口来避免在同一时间运行太多线程。

例如,设想一个你想更新许多 Web 服务器应用程序代码的场景。一旦代码分发出去,立即重载 web 服务(当更新失败的时候,允许很容易的回滚),如下的 fabfile 能实现如上需求:

from fabric.api import *

def update():
    with cd("/srv/django/myapp"):
        run("git pull")

def reload():
    sudo("service apache2 reload")

然后在 3 台 web 服务器上串行的执行,如下:

$ fab -H web1,web2,web3 update reload

正常的情况下,没有使用并行执行,Fabric 会按照如下顺序执行:

  1. update on web1
  2. update on web2
  3. update on web3
  4. reload on web1
  5. reload on web2
  6. reload on web3

当使用并行执行的时候(通过查看 P 获取更多细节),变成了这样:

  1. update on web1, web2, and web3
  2. reload on web1, web2, and web3

这个是收益非常明显的 – 如果花费了 5s 运行 以及 2s 重载。串行执行会花费(5+2)*3=21s 的时间,而并行执行仅仅只需要花费其三分之一的时间,平均(5+2)=7s 左右。

怎么使用并行

因为并行执行影响一个任务是最小的单元。这个功能可以通过使用 parallel 和 serial 装饰符来控制开关。例如,fabfile 如下:

from fabric.api import *

# 并行执行任务 
@parallel
def runs_in_parallel():
    pass

# 串行执行任务 
def runs_serially():
    pass

当按照下面这种方式运行的时候:

$ fab -H host1,host2,host3 runs_in_parallel runs_serially

连续执行的结果如下:

  1. runs_in_parallel on host1, host2, and host3
  2. runs_serially on host1
  3. runs_serially on host2
  4. runs_serially on host3

命令行标记

你可以通过使用命令行标记 -P 或者是环境变量 env.parallel 强制所有的任务并行执行,尽管如此,任何使用 serial 特别标记了的任务,都将忽略并行标记,继续串行执行。

例如:

from fabric.api import *

def runs_in_parallel():
    pass

@serial
def runs_serially():
    pass

当这样调用的时候:

$ fab -H host1,host2,host3 -P runs_in_parallel runs_serially

如以前,runs_in_parallel 并行执行,runs_serially 串行执行。

Bubble size(队列池样的概念?)

在大批量主机的情况下,用户的 Fabric 本地主机因为运行了太多的 Fabric 进程可能会不堪重负,导致 Fabric 主机负载太高。因为这个,你可能需要选择一个 moving bubble 的方法来限制 Fabric 活跃并行进程的指定数量。

默认的情况下,Fabric 是没有 bubble 被使用的,所有的主机运行在一个并行池里��。你可以通过为没一个任务给 parallel 来指定 pool_size 关键字来重写它。或者是通过全局的 -z 来设置。

例如,在某一时间运行 5 台主机:

from fabric.api import *

@parallel(pool_size=5)
def heavy_task():
    # lots of heavy local lifting or lots of IO here
    #

或者是跳过 pool_size 参数,用如下代替:

$ fab -P -z 5 heavy_task

使用 Vagrant 和 Fabric 用于集成测试 http://www.linuxidc.com/Linux/2014-07/104113.htm

Fabric:Python 远程部署工具 http://www.linuxidc.com/Linux/2014-05/101616.htm

正文完
星哥玩云-微信公众号
post-qrcode
 0
星锅
版权声明:本站原创文章,由 星锅 于2022-01-20发表,共计3332字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
【腾讯云】推广者专属福利,新客户无门槛领取总价值高达2860元代金券,每种代金券限量500张,先到先得。
阿里云-最新活动爆款每日限量供应
评论(没有评论)
验证码
【腾讯云】云服务器、云数据库、COS、CDN、短信等云产品特惠热卖中