13

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

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

  • 开发是在本地机器上完成的
  • 准备好更改后,我执行“git push origin master”以将更改推送到 BitBucket(我在其中托管所有 git 存储库)
  • 被推送到 bitbucket 后,我​​希望将新版本同时推送到所有 EC2 实例。
  • 我想这样做,而不必通过 SSH 连接到每个实例(显然)。

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

4

6 回答 6

10

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

  1. 使用来自受信任来源的基础 AMI,例如默认的“Amazon Linux”,或者您自己的。

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

  3. 至于更新现有实例的代码:有两种思想流派:

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

选项一

  1. 把它推到一台机器上。
  2. 在上面创建一个 git 钩子http://git-scm.com/book/en/Customizing-Git-Git-Hooks
  3. 使钩子运行拉到其他机器上。

唯一的问题是,您必须维护要运行更新的机器列表。

另外的选择

从您的 bitbucket 帐户中提取 cron 作业。在一个常规的基础上。

于 2012-12-13T21:43:33.143 回答
2

这项工作的工具是 Capistrano。

我使用了一个很棒的 gem,叫做capistrano-ec2group,以便将 capistrano 角色与 EC2 安全组映射。

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

这意味着您不必在应用程序中维护服务器 IP 列表。

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

cap deploy

如果您真的不想执行步骤,请创建别名:D

alias shipit=git push origin master && cap deploy
于 2013-03-05T01:01:30.583 回答
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 连接到它们的代码,但没有测试特定git pull命令。

您需要将亚马逊 cli 工具安装在您希望它运行的任何位置,以及为您尝试更新的服务器安装的 ssh 密钥。不确定 bitbucket 的功能是什么,但我猜这段代码将无法在那里运行。您要么需要按照 E_p 的建议进行操作,并将更新推送到单独的管理实例,然后将此代码包含在您的 post-commit 挂钩中,或者如果您想避免头痛,您可以像我所做的那样只安装本地计算机上的 CLI 工具,并在您想要部署更新时手动运行它。

感谢 AdamK 对另一个问题的回答,这使得从ec2din输出中提取 ip 地址并迭代结果变得很容易:如何从命令行中终止我的所有 EC2 实例?

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

于 2014-01-10T05:37:50.153 回答
1

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

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

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

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

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

于 2012-12-14T16:52:11.223 回答
0

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

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

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

基本上这个想法是创建另一个远程调用它“生产”或任何你想要的,然后将多个 url(所有服务器的 ip)添加到该远程。这可以通过编辑来完成.git/config

然后你可以运行git push production <branch>它应该推送到“生产”下列出的所有 url

这种方法的一个要求是服务器上的存储库需要是裸存储库,并且您需要有一个post-receive挂钩来更新工作树。

这是一个如何做到这一点的示例:为裸回购设置接收后挂钩

于 2018-12-13T18:51:25.133 回答