原文作者是Amazon的CTO,Werner Vogels
原文见:http://www.allthingsdistributed.com/2015/07/under-the-hood-of-the-amazon-ec2-container-service.html
禁止任何形式的转载,不惜诉诸法律
我们是怎样协调集群的
我们来讨论一下Amazon ECS实际上是怎么运作的。Amazon ECS的核心是一个集群管理系统,以一个后端服务存在并处理状态管理和集群协调的诸多任务。在集群管理系统上面运行着很多的调度器。集群管理系统和容器调度器是两个完全解耦的模块,允许用户构建并使用自己的调度器。每个集群都是一个供用户程序使用的计算资源池。这里说的资源池就是用容器分割的Amazon EC2的CPU、内存、网络资源的实例。Amazon ECS通过运行在每个EC2实例上的Amazon ECS Container Agent来协调。我们的agent允许Amazon ECS按照用户或者调度器的请求与集群中的EC2实例进行通信去执行start、stop或者监控容器。我们的agent是Go写的,只有很小的开销,已经遵守Apache license开源在了github上。我们欢迎大家贡献代码,各种反馈也是极好的。
我们是怎么管理状态的
为了协调集群的正常运作,我们需要确保集群的信息有一个唯一的信息源,信息包括:集群中的EC2实例、EC2实例上运行的任务、承载任务的容器、可以使用的资源(例如,网络端口、内存、CPU等等)。如果不能确切的知晓集群的状态,我们是没有办法成功地启停容器。为了达到这一点,状态信息需要被存储在某个地方,所以所有现代化的集群控制系统的核心都是一个KV存储器。
我们所有的关于集群的信息(状态,以及所有状态的改变)都是存储在KV存储器中的,KV存储扮演着集群所有信息的唯一数据源的角色。为了在网络分区或者硬件故障的情况下保证健壮新和伸缩性,我们的KV存储器需要用分布式来实现持久化和高可用。但也正是因为我们的KV存储器是分布式的,也使得数据持久化和处理并发的变更更加的困难,特别是在我们这种状态变化频繁的场景下(例如:容器的启动与停止)。所以,并发控制就需要被引入到我们的系统里,去解决大量的状态变更不会冲突。例如,当两个开发者都声称要占用某一个EC2实例的所有可用内存的时候,必须只能有一个请求被满足,另一个请求被告知请求无法满足。
为了达到并发控制,我们用Amazon的核心分布式基础组件构建了Amazon ECS:一个基于事务日志的Paxos协议实现的数据存储器,负责记录每一次数据条目的变更。任何对数据的写操作都将被赋予一个特定的基于顺序的ID,被当做一次事务日志提交。数据的当前值都是在日志中记录的事务的按顺序叠加的结果。每次数据的读取都是读取的数据最新版本的快照。如果一个写请求想要成功,那么它必须是上一次读取之后最近的一次事务提交。这项特性就使得Amazon ECS可以使用乐观并发来存储集群状态信息,这种设计在共享的持续变化的数据场景下表现优异(例如,呈现像Amazon ECS一样一个共享的计算资源池的状态)。这种架构支撑着Amazon ECS保持高可用、低延迟和高吞吐,这一切都直接受益于数据存储从来不会出现悲观锁。
通过API访问
由于上述KV存储器的存在,我们可以成功的协调集群的运作也可以保证预期中数量的容器正常运行也正是因为我们可靠的存储和读取集群状态信息的机制。就像我们上面所说的,我们希望我们的用户能利用到Amazon ECS灵活的状态控制能力,所以把容器调度和集群控制进行了解耦。我们开放了一组Amazon ECS集群管理的API,用户通过它能够获取到结构化存储在KV存储器的集群状态信息。
通过一个简单的‘list’命令,我们的用户可以获取所有管理下的集群,所有运行在特定集群的EC2示例,运行中的任务以及组成任务必不可少的容器配置。通过‘describe’命令,用户可以获取特定EC2示例的详细信息以及它上面的可用资源信息。最近,我们完成了新的功能,用户可以在集群的任何机器上启停任务。我们最近在Amazon ECS上也完成了一系列的压力测试,我们可以分享一下用户在Amazon ECS上构建应用的时候可能比较关注的性能指标。
上面的图展示的是,我们在一个经常增加和移除实例的Amazon ECS集群上测试‘DescribeTask’这个API长达72小时的结果,红线和绿线分别是50%峰值和99%峰值。正如图中所示,接口的响应速度在集群规模发生巨大变化的时候几乎没有任何波动。Amazon ECS能做到无聊集群多大都可以保持伸缩性――这一切都不需要用户的操作或者增加集群控制器的规模。
我们的API动作涵盖了用户在Amazon ECS上构建应用所需的所有动作。用户自定义的调度器只用定义“how”、“when”、“where”去启动和停止容器。Amazon ECS的架构被设计成共享集群的运行状态,并且允许用户运行应用所需的多种多样的调度器(例如:二进制打包、分发、等等)。也正是先进的架构,使得调度器可以查询集群的确切状态,并且把集群作为一个通用的资源池来分配资源。乐观并发控制使得每个调度器可以在请求资源的时候避免可能的资源冲突。我们的用户已经在Amazon ECS上构建了很多有趣的解决方案,我们也希望把一些比较有代表性的分享给大家。
Hailo �C 一个构建在弹性资源池之上的调度器
Hailo是一个免费的智能手机应用, 允许用户直接呼叫注册过的出租车到他们的地点。Hailo的全球网络拥有60000个注册的司机和超过1百万的乘客。Hailo在2011年的建立之初就是构建在AWS上的。在过去的几年中,Hailo从一个单独的巨大的运行在一个AWS区域内的程序逐渐进化成微型服务构成的运行在多个AWS区域的架构。之前每个微型服务都是运行在静态划分的一个集群的某个实例上的。这个架构没有很好的伸缩性,Hailo也不希望他们的工程师为了基础设施和程序运行在哪个地方分神。
Hailo想要能够在弹性的资源池上根据服务的优先级和一些其他的度量来调度他们的容器。他们选用了Amazon ECS作为集群控制器,由于通过它提供的API接口用户可以简单的控制任务的状态也可以完整的暴露集群的状态。所有的一切就保证了Hailo可以构建自己自定义的调度器来实现符合自己程序业务逻辑的调度策略。
Remind �C PaaS
Remind是一个基于web和移动的应用可以让老师给学生发送短信,也可以和学生家长保持联系。Remind平台上拥有2400万的用户和150万的教师。每个月它会投递1.5亿条短信。Remind最初从全部的应用架构到消息投递引擎、前端API、web客户端、聊天后端都是是运行在Heroku平台上的。大多数的基础组件都是以大型的单点方式部署的。
随着用户数量的增加,Remind迫切的需求水平扩展的能力。所以在2014年底左右,工程师团队就开始探索切换到基于容器的微型服务架构上。他们的团队想要在AWS上构建一个和Heroku API兼容的PaaS平台。起初,他们的团队调研了很多开源的解决方案(例如:CoreOS、Kubernetes)去处理集群管理和容器的协调,但是由于工程师团队人力的短缺,他们没有时间去处理集群的基础设施的问题来保证集群的高可用。
在简要的评估Amazon ECS后,他们的团队就决定在ECS上构建他们的PaaS服务。Amazon ECS可以全方位的进行管控,提高了操作的效率可以让工程师的开发资源更多的去关注开发和发布自己的业务上;老板再也不用担心集群扩容和伸缩的问题了。6月份的时候,Remind将他们构建在ECS上的PaaS解决方案“Empire”开源了。Remind看到了显著的性能提升(无论是延迟减小、还是稳定性提升)当然,也有一些安全性的提升。他们接下来几个月的目标就是迁移90%的核心设施到Empire上。
Amazon ECS �C 一个全方位可管控的平台
我们已经了解到很多我们用户的应用场景。Amazon ECS架构让我们可以给大家提供一个高伸缩性、高可用、低延迟的容器管理服务。用乐观并发控制API的方式全局共享集群的状态使得我们的用户可以构建出各种各样符合他们需求的容器服务。我们专注于帮我们的用户避免重复造轮子的“脏活累活”中。在Amazon ECS中,用户只需专注于开发伟大的应用,而无需分心在集群控制器的安装和部署上。
从我们去年11月发布预览版之后我们已经上线了很多新的特性。您可以在 Jeff Barr’s blog 上了解我们从去年到现在开发的新特性。欢迎阅读我们的文档 访问我们的控制台来试用我们的产品. 我们的RoadMap上已经规划了很多,我们十分重视大家的反馈:提问请到我们的论坛 或者reddit的 /r/aws.
目前仅授权 http://51reboot.com 在其公众号、网站、51cto博客转载
>>>更多技术交流,请加群:238757010