转载

容器的编排和调度:计算型牛群的放牧

这篇文章是的电子书 《用Docker和容器玩转自动化与编排》 的一部分,现可以网上下载。

原谅我打了一个可能不恰当的比方,但是我们正在越来越多地被劝说把我们的基础设施和应用想象成家中的牲口。我们关心牲口,但是程度可能不如宠物。我们尽量不对牛群漠不关心让它们缺乏关爱;我们想要它们呆在在最好的牧地上啃草;我们不时地疏散走拥挤在一起或者踏入危险区域的牛群;如果它们生病了,我们想要有兽医能把它们照顾好直到康复。

容器的编排和调度:计算型牛群的放牧

在云原生容器平台( cloud-native container platforms )的世界中,如果我们的应用是牧场的牲口,那编排和调度器框架扮演了所有这些照顾者的角色。一个优秀的的应用牧民会将资源利用率最大化,同时均衡系统因容错需要不断变化的需求。

在IT界的有一个完美的风暴正在形成,其包含三个重要的趋势:真正可编程的基础设施架构的崛起,这包含云,配置管理工具和容器;高适应能力应用架构的开发,包含微服务的使用,大规模分布式消息/日志处理,和事件驱动的应用;新流程和新方法论的出现,如精益和DevOps。

在所有这些革新面前,为什么我们要在乎一个容器编排和调度的主题?原因是我们应该像后农业革命中那些的成功的牧民一样关心他们如何放牧牛群。

你目前采用的是哪个类型的容器牧场?

托管和部署容器化应用目前有很多的选择,如果我们我只考虑现代的云平台,我们可以把它们分成三类:基础设施即服务(IaaS),容器即服务(CaaS),和平台即服务(PaaS)。

根据部署的应用的差别,每个类别都有自身的强项和弱点。尽管一些机构趋向于根据直觉,分析报告或者与厂商现有的关系来简单地决定使用哪一种平台,但这是一个需要进行严肃评估的根本性决定。

平台的选择对于能实现哪一种编排和调度有重大的影响。下面的比较能让你了解每一种类型提供的关键抽象,控制面和合适的应用场景 。需要值得注意的是,容器即服务仍然是一个存在热烈争议的领域 - 很多人说我们传统上被称作的容器服务也是CaaS的一种;然而,Docker建议使用 一组不同的条件 来认定一个CaaS方案,而这些条件中最重要的是云基础设施不可知性( cloud infrastructure agnostic )。我们认为广阔市场对于这个产品类别仍然有被解释的空间。

平台和服务的比较:

1. 基础设施即服务(IaaS):

  • 描述 :在应用部署之前必须组合并准备好的抽象化计算资源(CPU,内存,存储,网络等)
  • 抽象核心 :计算资源
  • 示例 :AWS,Azure,Digital Ocean,Google Cloud Platform,IBM Cloud Infrastructure, VMware
  • 应用调度
    • 手动或者通过配置管理(CM)工具
    • 资源需求通常通过基础设施选择和配置指定
    • - 容错通常由程序实现(implemented procedurally)
  • 服务发现 :
    • 手动或者通过配置管理工具,如Puppet,Chef或Ansible
    • - CM工具通常与分布式的KV存储结合,如Consul或Zookeeper,以进行服务发现
  • 资源分配(provisioning)
    • 手动或者通过配置管理工具,如Puppet,Chef或者Ansible
    • - 操作员根据资源分配和分布来进行容错和伸缩的措施
  • 数据存储/中间件 :通常是数据库即服务(DBaaS)或者自托管
  • 典型应用场景 : 进行云迁移并且需要迁移内部部署的虚拟机和同类型应用,或者需要对资源的组合和分配进行更细粒度控制的公司机构

2. 容器即服务(CaaS)/容器化服务

  • 描述 :在计算资源的基础上提供了一层抽象以允许容器的部署和编排
  • 抽象核心 :容器
  • 示例 :CoreOS Tectonic,Docker Cloud,Google Container Engine(GKE),HashiCorp Nomad,IBM Container Service,Joyent Triton, Mesosphere Datacenter Operation System(DCOS)
  • 应用调度
    • 容器调度通常由平台自带,能力水平可能很原始可以很复杂
    • 资源需求以声明式的方式指定
    • - 自动处理容错
  • 服务发现 :从程序式的指定方式(如在Mesos中,Registrator和srv_router)和声明式指定方式(如Kubernete中的service和label)
  • 资源分配(provisioning)
    • 通常由平台自带,并且有如bin-packing and spread等算法来最大化资源利用率和容错
    • - 容器实例的伸缩可以通过平台实现
  • 数据存储/中间件 :通常是基于IaaS的DBaaS,也有可能供容器化的数据库
  • 典型应用场景 : 已经在开发云原生的应用,并且想从IaaS的运维复杂度中解放出来,但是不想使用那些不合胃口的PaaS的公司。

3. 平台即服务(PaaS)

  • 描述 :在计算基础设施上提供了一层抽象允许应用的部署和编排
  • 抽象核心 :应用
  • 示例 :AWS Elastic Beanstalk, Deis, Google App Engine, Heroku,IBM Bluemix, Pivotal Cloud Platform,Red Hat OpenShift
  • 应用调度
    • 平台自带
    • 资源需求以声明式的方式指定
    • - 自动处理容错
  • 服务发现 : 通常平台自带,如服务发现“作为一个服务”提供
  • 资源分配(provisioning)
    • 对用户不可见
    • - 费用开销通常基于资源的分配和消耗情况
  • 数据存储/中间件
      - 作为平台的一部分进行提供,例如,作为一个服务的代理(broker)
  • 典型应用场景 : 可以是那些想要削减维护平台基础设施的创业公司,也可以是寻求标准化流程和提升开发者效率的大规模机构

顺着我们之前放牧的比方,我们把计算资源(CPU,内存,磁盘,网络等)想象成我们的牲口吃草玩耍的牧地。编排和调度的角色就是将应用和资源匹配,就如将牲口匹配到牧地,并保证方式以最有力有效。第一眼看,将应用高效地匹配到资源可能感觉不是特别困难,但是用解决装箱问题(bin-packing)的方式来优化资源利用率在计算上一个 NP 问题。再加上下面易失和临时的云网络,我们面对的绝对是一个困难的挑战。

圈养容器化的牲畜

从一个IaaS创建一个容器化的应用好比买一款空地然后从头开始修建你的牧场 - 这十分的费劲,但是你拥有最大程度的控制。而利用CaaS就像购买一块牧场,然后雇佣专业的牧人来搭建围栏并且看管牲口。这让你有对土地的可见性,声明你的想法,并且不需要自己做即时即地的决定。在PaaS上部署应用好比实际将牲口付托给另外的牧民。可以说,这样这就有多余的精力去关注真正值得关注的事情(购买并且培育最好的牲畜,最快的把你的牛推向市场),但是你可能就不知道牧地上都发生了什么事情,而且你可能不赞成其他牧民管理牧场的方式。

在我们的OpenCredo的工作日子里,我们和多个客户一起设计,构建并且管理容器化的应用和平台。下面的部分是我们经历的两个案例的分享。这些例子用来说明在创建这些编排的技术栈的时候经历的决策过程。

在Mesos和Google Cloud Platform上运行Spring Boot Services

对于我们的第一个客户,我们实现的编排器是Apache Mesos。客户期望能混合持久运行的容器化应用服务和基于Spark的批量数据处理。Mesos自身实际上就是一个“数据中心内核”,因为它把计算资源从基础设施集群抽象了出来,并且把这些资源提供给了框架,比如让Mesosphere的Marathon运行持久运行服务,Chronos执行批量式任务,让Spark处理数据处理的工作量。部署和运行Mesos是一件运维复杂的事情;然而它已经被证明可以在大规模使用,它受到了Twitter,Airbnb和eBay的喜爱,可以混合不同类型的工作量,可以跨整个数据中心调度应用,这些对于客户来说都是非常有吸引力的提案。

Mesos通过Ansible进行部署和管理,并且通过Jenkins来构建容器化应用并且部署进Marathon框架。服务发现通过结合Consul, Registrator和srv_router来实现,而因为容错进行的服务重启或者重新分配是由Marathon提供的。QA团队可以在Google Cloud Platform中启动自己的的Mesos平台实例,这可以减少资源竞争以加快测试(这在之前是一个问题)。然而,我们吸取到了几个严重的教训,因为个人的环境资源受限和完整的平台是以不同方式调度工作量的。例如,在一个单机器组成的集群中运行多个Mesos框架通常导致其中一个框架资源耗尽。

在AWS Kubenernetes上部署基于Go的微服务

在这个项目中,Kubenernetes通过Terraform和Ansible被部署到了AWS上,主要的目的是为开发者提供IaaS之上一层的抽象,让他们无需在PaaS花大工夫。 Google Container Engine因为客户端/厂商的限制无法使用。很容易说大多数的机构会最终构建某一种形式的PaaS,因为很多PaaS的特性对于一个典型的开发团队是必要的,如测试,部署,服务发现,存储,数据库集成和开发者社区引导。相应的,这个案例确实也实现了很多这种特性。

Kubenenetes提供了命名空间的隔离,这对于在同一个集群上运行多个测试和staging的部署有用。分隔的集群被用来做真正的隔离。部署是通过集成Kubenernetes API的或者kubectl CLI工具来管理的。持续集成使用的是Jenkins框架,它也负责构建和测试我们应用服务。服务发现由Kubernetes自带,开箱即用。因为具备Node健康检查和应用/容器级别的活动性探针健康检查,其也提供了良好的容错。其底层的IaaS层也提供了存储和数据库集成,并且结合版本控制系统和一个内维护良好的wiki,开发模式得到很好的共享和重用。

在我们牧场上得到的教训

这篇文章的目的是基于你自己的需求,和相应的编排和调度机制,提供一些容器平台选择的参考。然而,这主要基于两个客户示例案例研究。有很多其他的产品组合及由其催生的技术栈,包括 全部混杂使用Docker Swarm和Mesos ,包括 IBM的基于PaaS的云编排 。

这里是一些我们在OpenCredo目前为止学习到的主要的学习经验:

工具链

  • 尽可能的自动自动化,这可以节省时间,可以大规模的重用,可以减少基础设施和配置的差异。
  • 不鼓励但是允许人工的干预,特别是当把尚处于新兴阶段的容器技术引入到公司的时候。我们都知道不应该直接SSH到生产环境的主机上,但是保留这个入口作为一种救命稻草,可能会在关键时候挽拯救你的商业。

性能错误

  • 语法错误,又被称作“对业务造成影响(business impact)”错误,在云和容器的世界里尤其重要,甚至比底层的基础设施错误更加的重要。即使你一半的生产环境都挂掉了也没关系,只要你的系统仍然能优雅的降级并让客户正常获取价值。我们经常看到运维团队被基础设施错误警报淹没,但是他们不知道实际的对用户造成的影响。
  • 了解Brendan Gregg的 USE(Utilization, Saturation and Error,即利用率,饱和量和错误数)方法论 和Tom Wilie的 RED(Rate, Error and Duration,即请求频率,错误频次,和时长分布) 方法论。我们发现这些方法对于解决性能的问题特别的有用。

监控和资源竞争

  • 在所有的层次都需要具备可见性。容器监控和管理是任何在生产环境中使用容器方案的公司应主要担心的问题。
  • 正确地编写程序,只对于必要的信息记录日志。
  • 提供业务层(语义)的指标。这有助于促进关键的相关利益者的采纳度,也会有助于解决故障。
  • 网络:确保正确地规划计算实例的大小。例如,你的应用只需要一个小型实例提供的CPU和内存就够了,但是你配置了相应的网络带宽了吗?
  • 一定要对于磁盘和CPU层进行全面的监控。对于CPU,如果你部署的是一个公有云,那请留意 被偷窃时间 。
  • 熵的缺少( lack of entropy )是很难调试的问题,在容器化的环境中经常出奇的看到多个容器在争夺主机的 /dev/random 。容器化的应用通常会不明所以就挂起(hang住),而在调试的时候回发现是一个安全方面的操作(如:会话或者加密的令牌生成操作)阻塞了它。

原文链接: Containaer Orchestration and Scheduling: Herding Computational Cattle (翻译:钟最龙)

原文  http://dockone.io/article/1280
正文到此结束
Loading...