Amazon EC2,将节点加入现有集群的最快方法

Amazon EC2,将节点加入现有集群的最快方法

我是 Amazon AWS 的新手。我经常听说有人创建实例,然后几乎立即将它们放在负载均衡器后面并放入现有集群中。

在传统的托管机器世界中,这包括配置硬件、安装操作系统、在机器上配置网络,并且一旦网络可用,使用您选择的工具(例如 CFengine、Puppet 或 Chef)根据其类别引导机器。

似乎有一些“捷径”能够在 Amazon EC2 中启动并运行特定类别的服务器。如果我的服务器上正在运行特定堆栈,例如 erlang、tomcat6 等。启动并运行这些堆栈并将其挂接到 Amazon 的负载均衡器的最快方法是什么?从网络到软件堆栈再到内核调整?它是创建 AMI 然后针对新实例运行 Puppet 之类的工具的组合吗?

任何想法

答案1

简短回答:

这取决于您的应用程序 - AMI 始终是起点,启动时您需要对实例进行多少自定义将决定您在简单的“负载均衡器后面的自动缩放实例”示例之外还需要什么。

不那么简短的回答:

EC2 上的实例与 VPS 非常相似 - 事实上,它们是虚拟机(Amazon 使用 Xen 虚拟化)。我认为 VPS 和“云”服务器之间的主要区别在于部署的简易性 - 在“云”中配置和添加十几个实例或几百 GB 的存储空间应该是一件轻而易举的事情。

由于 Amazon 使用虚拟机,因此他们拥有这些机器的“映像”。这些映像引用存储并包含对默认内核的引用(您可以更改)。此映像的内容通常用于创建附加到实例的根卷。

您基本上只能使用 Amazon 提供的(相当多的)内核 - 通常无法编译自己的内核 - 但您可以设置大多数参数并利用可用的内核模块来实现您想要的效果。一旦您创建了自己的 AMI,您从中启动的所有实例都将是相同的(除了您让 AMI 运行以自定义自身的任何脚本)。这使得这成为几乎所有情况的起点。

事物的“虚拟”性质确实有一些好处。例如,您只需停止实例、分离根卷、附加新卷并重新启动实例即可切换根卷。同样,您可以通过停止实例、修改实例属性并重新启动实例来更改实例类型。

启动实例时,您需要指定(除其他事项外)实例类型(例如 m1.large)和 AMI。这意味着您的实例将使用保存在该 AMI 上的所有内容启动 - 预配置的操作系统、您安装的任何软件等。此外,AMI(或 ec2-run-instances 命令)可以引用其他存储 - 临时存储或 EBS 支持。对于其他 EBS 存储卷,可以从现有快照创建这些卷,并在实例启动时将其附加到实例上。(有趣的是,这些快照的内容是“延迟”加载的 - 这意味着您可以在快照完全加载之前访问其中的数据,如果您正在加载大卷,这将非常有利)。

考虑最简单的场景 - 所有机器都等效的集群 - 首先,假设我们正在为一个静态站点提供服务。EC2 将允许您垂直扩展(更强大的实例)和水平扩展(更多实例)。因此,我们从最小的实例 - t1.micro 开始,我们发现它最终无法处理负载。我们现在可以在 Elastic Load Balancer (ELB) 后面添加第二个实例。因此,传入的请求将转到 ELB(其设计应该考虑到冗余和可扩展性 - 它应该自动添加更多资源以满足对它的需求) - 它会将其路由到其中一个实例,该实例将处理请求并通过负载均衡器返回它。

为了使该过程更加自动化,我们可以使用 Amazon 的自动扩展功能 - 本质上,使用触发器(Cloudwatch 指标的值),您可以动态添加和删除实例(就像手动启动实例一样,您可以指定新实例的实例类型和 AMI)。此外,这些实例可以(它们不必)与 ELB 相关联,根据某些指标的变化(例如 CPU 负载、RAM 使用率或其他自定义变量)自动增加或缩小您的集群。

现在 - 上述场景的几乎所有内容都是“不好的做法” - 您可能不应该从 t1.micro 水平扩展,因为它们是功能不足的实例 - 因此您首先需要增加实例大小;ELB 的成本远远高于(保留的)t1.micro,这使得它(在经济上)在这种情况下不切实际;如果您在 AWS 上提供静态站点,您只需使用 S3,即可完全省去实例的费用和麻烦,但这只是一个例证。

让我们举一个更复杂的例子 - 一个 PHP/MySQL 站点(例如 Wordpress)。首先,我们将数据库与 Web 服务器分开 - 因此让我们从每个实例开始 - 现在我们可以独立扩展每个实例。可以说,我们可以使用 Amazon 的 RDS(虽然我个人更喜欢维护自己的 MySQL 设置),而不是自己托管 MySQL,这将简化额外 MySQL 实例的部署(...当然需要付费)。我们的 Web 服务器都提供相同的内容,但现在内容可能会发生变化。存储在数据库中的更改(例如新文章、评论等)不是问题 - 所有服务器都从同一个数据库实例读取。理想情况下,您将代码存储在某个中心位置(例如 S3),每个实例在启动时都会提取它。静态资产可以从 CDN 提供,这样您就可以避免在本地处理分布式文件系统。 (ELB 可以处理粘性会话,但最好只是集中存储会话(例如 Memcached),以便所有实例都可以访问它们 - 请记住,请求最终可以到达任何实例)。

(AWS 确实有 Elastic Beanstalk - 它应该可以处理某些类别的应用程序(例如 PHP/MySQL)所需的资源配置 - 但我没有使用过它。

对于更复杂的设置,您可以将用户数据传递给实例,并且有方法可以获取正在运行的所有实例的列表(您可以标记实例以根据需要对其进行分组)。您可以在消息队列中处理任务(Amazon 版本是简单队列服务...或者如果您愿意,可以使用开源版本),以确保您的集群只处理每个请求一次。当然,您也可以使用典型的高可用性工具(例如 Heartbeat/Corosync、Pacemaker 等)控制集群 - 这将使所有节点都“知道”彼此,并让您控制每个节点上运行的资源。添加分布式文件系统(例如 Gluster),您就可以处理大多数场景。

除此之外,您仍然可以使用您提到的相同工具。上面的大多数想法都是基于多次部署相同的 AMI(您自定义 AMI,并启动它的多个副本 - 每个副本都应该能够处理自己的基本配置(例如提取最新代码等))。如果您的实例经常更改,或者您有一个更大的集群(例如,将更改推广到所有节点会有问题),或者您的节点不相似 - 那么您可以使用您选择的配置管理软件(例如 Puppet、Chef 等)部署节点。

您还可以采取另一个步骤 - 即配置您自己的“虚拟专用网络” - 本质上,允许您使用 NAT 创建一些面向私有和面向公众的实例,并控制私有 IP 地址和网络接口(例如,您可以在一个实例上拥有多个接口)。

最后,如何部署应用程序在很大程度上取决于应用程序的要求 - 每个节点需要共享哪些信息、集群中有多少个节点以及哪些节点相互依赖。最简单的情况始终是每个节点都可以独立运行,并且发送到任何节点的请求都会产生相同的结果...启动一个实例,对其进行自定义,创建您的 AMI,然后在 ELB 后面自动扩展它。所有其他场景都需要一些规划来设计可以有效扩展的东西。

鉴于上述情况,我觉得有必要指出其反面——AWS 是一项很棒的服务——因为它的入门门槛很低——你可以免费学习它(他们确实有免费套餐)——而且它可以根据你的需求进行扩展。然而,AWS 上的每一项服务都是收费的——你运行一个实例的小时数、你存储的 GB 数、你磁盘上的 I/O 量、你向 S3 发出的请求数、你使用的(传出)带宽——一切。不可预见的事情很容易在相当短的时间内产生相当多的费用。AWS 绝对不是所有问题的解决方案,它也不是没有局限性(例如,其网络上没有广播/多播数据包)。

(好吧,这最终比我原本打算写的几行要多一些……)

答案2

在完全虚拟的环境中运行(不仅仅是 EC2,尽管它配备了 API 并且任何人都可以使用它)相对于完全物理的环境而言提供了几种加速:

  • 您可以在很大程度上忽略硬件配置。
  • 安装是基于映像的,因此您可以构建一个包含大部分所需内容的黄金主映像。这样可以绕过大部分操作系统安装部分。
  • 由于部分工作已经完成,运行 puppet/cfengine/chef/whatnot 的速度更快。

所以是的,它确实提供了更好地简化流程的方法。有了正确的操作系统,更改服务器的身份就变得相当容易,因此您可以比使用纯物理系统更完整地预构建系统,从而最大限度地缩短后期映像准备时间。

相关内容