探究Amazon EC2的架构及与Google容器服务间的对比
author:一佰互联 2019-04-18   click:145

一般来说,在一个集群中运行现代化分布式应用的两个关键组件是:可靠的状态管理和灵活的调度。Amazon ECS简化了构建和运行容器化应用的流程,但是如何实现才是Amazon ECS真正有意思的地方。今天,我想要探讨Amazon ECS架构并阐述这个架构能够做些什么。如下是Amazon ECS的基本组件图:


我们如何协调(Coordination)集群

让我们来谈谈Amazon ECS到底做了什么。Amazon ECS的核心是集群管理器,它是一个后台服务,能够处理集群协调和状态管理的任务。在集群管理器之上是不同的调度器。集群管理和容器调度是互相解耦的,所以Amazon支持客户使用和创建他们自己的调度器。集群其实就是应用可以使用的计算资源池。而这里的资源池就是根据容器划分的Amazon EC2实例的CPU、内存和网络资源。Amazon ECS通过运行在集群中每个EC2实例上的容器代理来协调集群。代理允许Amazon ECS与集群中的EC2实例进行通信,并根据用户或调度器的请求来启动、终止和监控容器。代理使用Go语言编写,资源占用少,目前在GitHub上基于Apache协议开源。欢迎大家贡献和反馈。


我们如何管理状态

为了协调集群,我们的集群上需要有一个SSOT[单一数据源]:集群中的EC2实例,运行在EC2实例上的任务,组成任务的容器,可用/占用资源(例如,网络端口、内存、CPU等)。在获得精确的集群状态信息之前,我们是不可能成功开启和终止容器的。为了解决这个问题,需要在某个地方存储状态,因此现代集群管理器的心脏是键值数据库。

这个键值数据库对任何集群输入的和存储于此的信息表现为SSOT。为了保证可靠性和可扩展性,这个键值数据库需要采用分布式来确保持久性和可用性,并规避网络划分和硬件故障带来的影响。也正因为键值数据库是分布式的,确保数据一致性以及正确的进行并发修改会变得更加困难,这种情况在状态持续变化的环境(比如,容器的停止和启动)中尤甚。对此,为了保证多状态修改不会出现冲突,某些形式的并发控制就需要落实到位了。打个比方,假设有2个开发者从某个EC2实例请求剩余的内存以供他们的容器使用,这个时候,只有其中一个容器能够真正得到这些资源,而另一个则会被告知请求未完成。

为了实现并发控制,我们采用了Amazon分布式系统的核心原语之一来实现Amazon ECS,这是一个基于Paxos的事务日志的数据存储系统,它保存了每一项数据变更的记录。在日志中,任何数据的写入均以事务的形式提交,并对应一个特定顺序的ID。数据当前的值就是日志中记录的那些事务的总和。对于任何数据的读取,得到的都只是日志当前时间点的一个快照。如果写操作是继上次读取操作完成以来最新提交的事务,则判定写操作成功。这种原语允许Amazon ECS以乐观锁的形式存储集群的状态信息,对于共享数据经常变动的场景(比如当需要表达诸如ECS之类的计算资源共享池的状态时)而言,这是一种理想的方式。这个架构使得Amazon ECS具有高可用性、低延迟和高吞吐量的特点,因为数据存储并未使用悲观锁(译者注:作者自己表述得很含糊,大家参见多版本并发控制MVCC)。
通过API访问

既然我们有了一个键值数据库,那么我们便能够成功协调集群,并确保所需数量的容器正在运行,因为我们有一种可靠的方法来存取集群的状态。之前提到过,我们解耦了集群管理和容器调度两个模块,因为我们希望客户能够充分利用Amazon ECS状态管理的能力。我们已经通过一系列API开放了Amazon ECS集群管理器,它允许客户以结构化的方式访问存储在键值数据库中的集群状态信息。

通过list命令,客户可以读取托管的集群,特定集群中运行的EC2实例,运行中的任务以及组成任务的容器配置(如任务定义)。通过describe命令,客户可以获取EC2实例的具体信息以及每个实例上的可用资源。最近,客户亦可以启动和停止任何集群中的任务了。近期,我们针对Amazon ECS进行了一系列的负载测试,我们希望分享一些性能要点,客户在Amazon ECS上创建应用的时候应该会关注它们的。

上图显示了一个负载测试的结果,在这次测试中,我们在Amazon ECS集群中添加和删除实例,并测量72小时的周期内,调用‘Describe Task’API时,百分比排列位于第50位和第99位的延迟。你可以看到,尽管集群数量有较大的波动,但是延迟相对而言并没有什么抖动。Amazon ECS可以如你所需地进行扩展,不管你的集群规模有多大,且根本无需操作或扩展集群管理器。

这组API是客户在Amazon ECS上搭建解决方案的基础。调度器只是提供了关于何时、何地以及如何开启和停止容器的逻辑。Amazon ECS的架构为分享集群状态而设计,它允许客户根据需要为应用运行各种调度器(如二进制打包、发布等)。这个架构允许调度器查询集群的具体状态,并从通用池中分配资源。乐观并发控制允许调度器无冲突地获取它们所请求的资源。一些客户已经在Amazon ECS上创建了各种有趣的解决方案,下面我们来分享一些具体的示例。
Hailo——弹性资源池上的定制调度

Hailo是一个免费的移动APP,它允许人们招呼一辆认证的出租车到其所在地。Hailo拥有一个全球网络,囊括了超过60000名司机以及一百万以上的乘客。Hailo于2011年成立,从第一天开始就使用了AWS。在过去的几年中,Hailo从AWS单一区域上运行的应用集合演化为贯穿多个区域的微服务架构。之前,每个微服务都跑在静态划分的实例集群上。Hailo遇到的问题是跨分区的资源使用率较低。这个架构并不具备很强的扩展性,并且Hailo也不希望它的工程师关心基础设施的细节或者微服务的部署问题。

为此,Hailo决定基于服务优先级以及其它的运行时指标对容器进行调度。后来他们选择了Amazon ECS来作为集群管理器,因为ECS可以轻松的管理任务状态并访问集群状态的API。同样,Hailo可以根据自己的需求来定制调度器。


Remind——平台即服务

Remind是一个web端和移动端应用,使得老师能够给学生发送信息并和家长取得联系。Remind平台上拥有24M用户和超过1.5M的老师。它每月传递150M条信息。Remind起初使用Heroku来运行整个应用设施,从消息推送引擎、前后端API、Web客户端到聊天后台。这些设施中的大部分都以庞大的应用块进行部署。

随着用户的增长,Remind希望拥有横向扩展的能力。因此大约在2014年年底,它的工程师团队开始摸索着向基于容器的微服务架构迁移。团队希望基于AWS搭建一个PaaS,确保它能够兼容Heroku的API。一开始,团队期望能有一个开源的解决方案(比如,CoreOS和Kubernetes)来负责集群的管理以及容器的协作,但是由于团队的规模较小,因此他们没有时间来管理集群的基础设施,同时保证高可用性。

在简要评估了Amazon ECS之后,团队决定在此服务的基础上搭建PaaS。Amazon ECS是全托管式的,这使得工程资源能够被集中于开发和部署应用;这里并没有集群需要管理和扩展。在6月份,Remind开源了他们基于ECS的PaaS解决方案,名为“Empire”。凭借Empire,Remind得到了可观的性能提升(例如,延迟和稳定性)以及安全优势。他们接下来几个月的计划是将90%以上的核心设施迁移到Empire。


Amazon ECS——一个全托管的平台

上述只是我们从客户处看到的其中两个用例。Amazon ECS架构允许我们提供一个具有高可扩展、高可用、低延迟的容器管理服务。通过API乐观并发(译者注:乐观锁)地访问共享集群状态的能力,使得用户得以按需创建任何定制容器解决方案。我们一直致力于为客户消除重复而繁重的任务。通过Amazone ECS,根本不需要安装或操作集群管理程序,客户理应仅仅专注于开发优秀的应用。


Amazon与Google间的容器竞争持续发酵

Google容器引擎(GKE)由pod、replication controller和节点组成。pod是一组特定的应用程序逻辑主机模型的容器逻辑分组;replication controller确保特定数量的pod副本任何时候都在运行;节点是加强了容器环境的Google计算引擎虚拟机。

GKE基于Google的Kubernetes容器编排平台。Kubernetes 1.1版本在1.0版首次亮相之后4个月的11月24号发布,是市场中第一个能够通过水平节点自动伸缩功能来实现自动伸缩节点的产品,这个功能受到用户的高度追捧,从而为许多使用GKE的案例提供了有力的支持。

“我们为很多各种类型的项目使用自动伸缩”, Descartes Labs公司的联合创始人和首席云架构师Tim Kelton如是说。这家公司位于新墨西哥洲,是机器学习方面的初创公司,能够处理PB级别的卫星数据。

自动伸缩的pod在处理大型批处理作业时能够派上大用场,Kelton解释道。有时,他的公司处理PB级的数据,这就需要扩展到3000个内核。在Kubernetes的第一个版本(随后很快被GKE合并)中,“这不是核心特性集的一部分”,他说。

虽然GKE不支持垂直容器扩展或者节点自动伸缩,但是,根据GKE高级产品经理,同时也主导Kubernetes产品管理的David Aronchick透露,这些功能很快就是实现。

Amazon EC2容器服务(ECS)由服务、任务和实例组成。服务是构成应用程序的任务组,而实例是支持容器的弹性计算云端虚拟机,与GKE中的节点很像。

Google的ECS的自动伸缩能力与GKE是相反的:使用亚马逊CloudWatch和亚马逊网络服务Lamda可以实现服务自动伸缩,实例也可以基于CloudWatch metrics进行自动伸缩,但是任务——等同于pod,属于粗糙逻辑,无法自动伸缩。

虽然所有类型的自动缩放都很重要,但是亚马逊用户希望将任务自动伸缩加入ECS中。

“运行一个新的实例意味着你要有额外的容量来运行额外的任务,但这并不意味着任何新的任务都将被启动”,ACI信息科技集团副总裁Chris Moyer如是说。ACI,位于纽约,是一家基于Web的内容聚合技术的公司,也是TechTarget的贡献者。“如果你只是自动伸缩实例,并不能真正帮助你解决额外的负载——你必须真正运行额外的任务来实现扩展。”

跨区域冗余

在ECS发展过程中,亚马逊优先发展在同一个集群中,针对基于用户需求的任务自动伸缩冗余性,本地跨越可用区域(AZs)的能力,当ECS服务调度启动新的任务时,它也会尝试通过集群中的AZs自动平衡这些任务。

“这很重要,因为单个AZ允许失败,所以如果两个任务都允许在同一个AZ中,很容易拖垮你的服务”,Moyer说。

据Aronchick介绍,Google可以在GKE中通过命令行接口(CLI)跨多个区域。

"实现跨区域非常容易,两三条命令就能搞定",Aronchick如是说。

然而,这就要谈到GKE用户最大的心愿:将跨区域功能改进到Web界面上,包括跨域集群扩展功能。

“实现用户界面需要大量工作”,Vendasta科技首席架构师Dale Hopkins说,Vendasta为媒体公司设计销售和营销软件。用户界面目前支持集群创建以及其他少数功能。Hopkins说:“扩展集群是不直观的。”
互操作性

ECS作为一个可扩展平台,旨在融入客户现有的工作流,主要处理代表用户的集群状态。将ECS集成到现有工作流中来兼容客户在用的工具,比如用以高级调度的Apache Mesos。亚马逊还自豪的声称拥有广泛的容器伙伴网络来为亚马逊ECS贡献新特性,比如监视、持续集成和安全。

同时,Google已经与一批云端容器合作伙伴合作,这些合作商允许Kubernetes可以通过多个云端供应商被部署——这也是CLI现在的一个功能,Aronchick如是说。去年夏天Kubernetes 1.0版本发布时, Google引导了Cloud Native 计算基金会的成立,基金会成员包括云服务公司,比如IBM和Red Hat,以及终端用户如eBay和Twitter。

“[附] Kubernetes,其实我可以在亚马逊部署,在Azure上部署,在IBM上部署,也可以部署在我自己的物理硬件上,”Descartes的Kelton 说。 “这是非常有吸引力的,因为我们有选择。”

Google也有一个开源项目,拥有数百提交者和每月数以千计的代码提交,使得 Kubernetes可以快速的添加新功能,比如水平pod自动扩展。

Google是Kubernetes的创始者,而且Google做了很多杰出的工作壮大了社区,451 Research的研究员Jay Lyman如是说。

富者愈富

尽管如此,使用老牌和熟悉的次级亚马逊服务来实现集成使得亚马逊ECS特别吸引新的客户。

一家总部位于纽约的公司,与一些大的企业就IT项目上进行咨询,计划在两个新项目上使用ECS, 据其创始人John D"Esposito介绍。驱使我们使用ECS的主要优点是使用现有的、成熟的基础设施服务比如弹性负载平衡、虚拟私有云、身份和访问管理,以及弹性块存储可以实现无缝集成。

GKE和Compute Engine的定价还是对客户非常有吸引力的。除了在以10分钟为单位收费的VM资源的底层,GKE包括免费的Kubernetes主节点——这是特别吸引Vendasta的Hopkins的地方。

“直到我可以获得大量机器,我才会给 Kubernetes支付额外的费用。对于第一套机器,GKE为我免费提供Kubernetes节点”,Hopkins说。

在Kubernetes和容器引擎被引入之前,Hopkins和Kelton都已经在用Google云服务,包括Google App引擎。这样,数据重力就会在他们所选择部署的云端容器上起作用。

“我们的大多数数据集是PB级规模的,所以你不能只是移动或复制它们,你必须真正去计算数据”,Kelton说。大多数数据目前存放在Google云平台,虽然Descartes不与AWS的合作伙伴合作。
微软Azure Container服务整装待发

虽然Google和亚马逊在云端容器竞争中到目前为止仍处于前沿,但亚马逊最大的竞争对手仍然是微软的Azure,它在有限预览阶段拥有自己基于Linux的云端容器的服务,以及Windows Server的新版本,今年之后,将支持基于Windows的容器。

“我们的大多数客户都是......无论是在Azure或亚马逊,” 位于Rochester的HKM咨询公司的合伙创始人Chris Riley如是说,“微软已经拿到了一些他们正在开发的有趣工具。如果我们看到一个次要的,它很可能Google之前的Azure“。

简单性和易用性是很多微软的产品的设计重点,Lumagate的CTO Kristian Nese介绍,Lumagate是挪威的一家微软Azure系统集成商。

“我们现在部署Azure的容器服务,仅仅需要100行代码,”Nese说。 “一旦你部署了Azure的容器服务,你实际上部署了23个资源......如果你想手动做到这一点,可能需要数千行代码。”

Azure容器服务在预览阶段也支持自动扩展,是一个独立服务形式,被称作VM量表集。

Azure还将提供成熟和熟悉的工具来管理容器,如Azure的资源管理器,Nese补充说。