在负载均衡器上推送多个EC2实例

时间:2012-12-13 21:40:17

标签: php git nginx amazon-ec2 load-balancing

我正在尝试找出一种方法,将新提交推送到ELB(负载均衡器)后面的一组EC2服务器实例。每个实例都运行Nginx和PHP-FPM

我想执行以下工作流程,但我不确定将新版本推送到负载均衡器后面的所有实例的好方法。

  • Dev在本地计算机上完成
  • 一旦准备就绪,我会执行“git push origin master”来推送 对BitBucket的更改(我托管我所有的git repos)
  • 被推到bitbucket之后,我想拥有新版本 同时推送到所有EC2实例。
  • 我想这样做,而不必SSH到每个实例 (显然)。

有没有办法配置远程服务器以接受远程推送?有更好的方法吗?

6 个答案:

答案 0 :(得分:10)

是的,我一直这样做(实际上使用相同的应用程序堆栈)。

  1. 使用来自受信任来源的基本AMI,例如默认的“亚马逊Linux”,或自行推送。

  2. 作为启动配置的一部分,使用“用户数据”字段在引导时引导配置过程。这可以像运行yum install nginx php-fpm -y的shell脚本一样简单,并从S3存储桶中复制文件或从您的存储库中执行拉取。如果您需要更多灵活性,亚马逊创作的AMI还包括对cloud-init脚本的支持。如果您需要更强大的功能,可以使用变更管理和协调工具,例如PuppetChefSalt(我个人最喜欢的)。

  3. 就更新现有实例的代码而言:有两种思想流派:

    • 充分利用云,然后启动一个全新的实例队列,在启动时获取新代码。然后你翻转负载平衡器指向新的车队。它是即时的,如果出现问题,它可以让你快速恢复旧机队。几小时(或几天)之后,您可以关闭旧实例。
    • 您可以使用FabricCapistrano等工具同时对所有实例进行并行“推送”部署。这通常只是重新执行服务器在引导时运行的相同脚本。 Salt和Puppet的MCollective还提供类似的功能,与其基本的“拉”配置相结合。

答案 1 :(得分:2)

选项一

  1. 将它推到一台机器上。
  2. 在其上创建了一个git hook http://git-scm.com/book/en/Customizing-Git-Git-Hooks
  3. 在其他机器上进行钩子拉动。
  4. 唯一的问题是,您必须维护要运行更新的计算机列表。

    另一个选项

    从您的bitbucket帐户中获取cron作业。在常规基地。

答案 2 :(得分:2)

这项工作的工具是Capistrano。

我使用一个名为capistrano-ec2group的精彩宝石,以便将capistrano角色映射到EC2安全组。

这意味着您只需要将EC2安全组(例如app-web或app-db)应用于您的实例,以便capistrano知道要向他们部署什么。

这意味着您无需在应用中维护服务器IP列表。

对工作流程的更改是,不是专注于在推送到bitbucket时自动部署,而是推送然后执行

cap deploy

如果您真的不想做步骤,请创建一个别名:D

alias shipit=git push origin master && cap deploy

答案 3 :(得分:2)

此解决方案基于E_p的想法。 E_p说问题是您需要在某处维护服务器列表,以便告诉每个服务器提取新更新。如果是我,我只是使用ec2中的标签来帮助识别一组服务器(例如“Role = WebServer”)。这样你就可以使用ec2命令行界面列出实例并在每个实例上运行pull命令。

for i in \
    `ec2din --filter "tag-value=WebServer" --region us-east-1 \
    | grep "running" \
    | cut -f17`\
; do ssh $i "cd /var/www/html && git pull origin"; done

注意 :我已经测试了获取所有已标记实例的IP地址并通过ssh连接到它们的代码,但不是特定的{{ 1}}命令。

您需要在任何需要运行的地方安装amazon cli工具,以及为您尝试更新的服务器安装的ssh密钥。不确定bitbucket的功能是什么,但我猜这个代码将无法在那里运行。您可能需要按照E_p的建议进行操作,并将更新推送到单独的管理实例,并将此代码包含在您的提交后挂钩中, OR 如果您想节省您可以做的头痛我已经完成了,只需在本地计算机上安装CLI工具,并在要部署更新时手动运行它。

感谢AdamK对另一个问题的回答,这个问题可以很容易地从git pull输出中提取ip地址并迭代结果:How can I kill all my EC2 instances from the command line?

EC2 CLI工具参考:http://docs.aws.amazon.com/AWSEC2/latest/CommandLineReference/Welcome.html

答案 4 :(得分:1)

您最好的选择可能是实际使用AMI进行部署。

就个人而言,我通常有一个暂存实例,我可以将任何repo更改为。一旦我确认它以我想要的方式运行,我就从该实例创建一个AMI。

对于部署,我在负载均衡器后面使用自动缩放组(不需要动态扩展或任何东西)。在一个简单的设置中,您可以在自动缩放组中拥有固定数量的服务器(例如10个实例)。我会将与自动缩放组关联的AMI更改为新的AMI,然后在自动缩放组中一次开始终止几个实例。所以,假设我有10个实例,我终止了两个实例,将其归结为8个实例。自动缩放组配置为至少有10个实例,因此它将使用新的AMI自动启动两个新实例。然后,您可以按照您的负载水平以任何合理的速率移除实例,以免影响您的机队的性能。

显然,即使没有自动缩放组,您也可以通过直接在ELB中添加/删除实例来手动执行此操作。

如果您希望完全自动化(即持续部署),那么您可能希望使用构建系统(如Jenkins),这将允许提交启动构建然后运行必要的AWS制作AMI并部署它们的命令。

答案 5 :(得分:0)

我正在寻找解决同一问题的方法。我偶然发现了这篇文章,并认为这是一种有趣的方法

https://gist.github.com/Nilpo/8ed5e44be00d6cf21f22#pc

转到“将更改推送到多个服务器”

基本上,这个想法是创建另一个称为“生产”或任何您想要的远程,然后向该远程添加多个URL(所有服务器的ip)。可以通过编辑.git/config

来完成

然后您可以运行git push production <branch>,它应该将其推送到“生产”下列出的所有网址

此方法的一个要求是服务器上的存储库必须是裸存储库,并且您需要具有post-receive钩子才能更新工作树。

以下是如何执行此操作的示例:Setting up post-receive hook for bare repo