使用Fabric部署到多个EC2服务器

时间:2012-05-01 20:31:43

标签: python amazon-ec2 fabric

我想知道是否有人使用fabric

在ec2上部署到负载均衡器后面的多个服务器的经验

我现在已经使用了一段时间的Fabric,并且没有问题,或者部署到多个服务器,但我想在这个场景中做的是(假设我有十个实例运行)取消注册一半( 5)来自我的负载均衡器的盒子,将我的代码部署到它们并运行冒烟测试,如果一切看起来都很好,再次使用负载均衡器注册它们并取消注册剩余的5个实例并部署到它们,然后注册他们回到负载均衡器。

我完成任何单个任务(取消注册,运行测试,部署等)没有问题,我只是不知道如何以简单的方式组织我的主机,以便我可以部署上半部分,然后下半场。 Fabric似乎设置为按顺序在所有主机上运行相同的任务(主机1上的任务1,主机2上的任务1,主机1上的任务2,主机2上的任务2等)

我的第一个想法是创建一个任务来处理取消注册,部署和测试的第一部分,然后为服务器的后半部分设置env.hosts,但我觉得这似乎有点过分了。 / p>

之前有没有人使用Fabric建模类似的东西?

6 个答案:

答案 0 :(得分:5)

您可以通过定义角色(用于主机聚合)并在一个角色上执行任务,然后在第二个角色上运行测试和部署来简化此操作。

roledefs的示例:

env.roledefs = {
    'first_half': ['host1', 'host2'],
    'second_half': ['host3', 'host4'],
}

def deploy_server():
    ...
    # deploy one host from current role here

def deploy():
    # first role:
    env.roles = ['first_half']
    execute('deploy_server')
    test()  # here test deployed servers
    # second role:
    env.roles = ['second_half']
    execute('deploy_server')

更多链接:

答案 1 :(得分:3)

您想使用execute()功能。这将允许您执行以下操作:

def update():
     deallocate()
     push_code()
     smoke_test() #could fail fast
     reallocate()

def deploy():
     execute(update, hosts=first_five)
     execute(update, hosts=last_five)

您还可以在部署中对每个deallocate,push_code和smoke_test任务执行execute()调用,然后运行所有deallocates然后运行所有代码推送等。

然后进行某种检查,然后继续执行其他任务。

答案 2 :(得分:1)

我已成功将Fabric与boto结合使用。我使用boto填充主机列表。您可以使用@parallel装饰器来限制一次执行的主机数量。该命令如下所示;

fab running deploy

代码看起来像这样;

@task
@runs_once
def running():
    ec2conn = ec2.connect_to_region(region)
    reservations = ec2conn.get_all_instances(filters={'instance-state-name': 'running'})
    instances = list(chain.from_iterable(map(lambda r: r.instances, reservations)))
    env.hosts = list(chain.from_iterable(map(lambda i: i.public_dns_name, instances)))

@task
@parallel(pool_size=5)
def deploy():
    # do stuff on n<=5 hosts in parallel

如果您需要处理主机的子部分,我建议使用标签。

答案 3 :(得分:0)

Fabric未设置为在所有主机上运行相同的任务。

除了您可以明确设置特定主机的事实 使用-H命令行参数的任务,您可以使用this模式和 this更新的模式,可以完全按照您的意愿行事。

更新:Here它显示了如何使用roles

答案 4 :(得分:0)

或者你可以简单地编写一个设置一些变量的方法,例如:

def live():
    global PATH, ENV_PATH
    env.hosts = ["22.2.222.2"]
    env.user = 'test'
    PATH = '/path/to/project'
    # optional, is using virtualenv
    ENV_PATH = '/path/to/virtualenv'
    # overwri

在当前机器上需要更改的任何变量

在运行deploy命令之前,运行:

fab live deploy

详细信息:http://simionbaws.ro/programming/deploy-with-fabric-on-multiple-servers/

答案 5 :(得分:-1)

您可以将列表(或任何可迭代的)传递给主机装饰器,而不是插入env.hosts。类似的东西:

def deploy(half_my_hosts):
    @hosts(half_my_hosts)
    def mytask():
        # ...
    mytask()

然后你可以以任何你喜欢的方式拆分env.hosts并将其传递给deploy()