新浪微博混合云架构实践挑战之容器编排设计与实践

阅读数:2282 2016 年 8 月 11 日 17:58

编者按:

《微博混合云架构》专栏是 InfoQ 向新浪微博技术团队的系列约稿,本专栏包含 8 篇内容,详细阐述以 DCP 设计理念为指导思想的混合云架构实践。本文是该系列的第五篇,主要介绍容器编排的设计与实现。

《微博混合云架构》专栏主要包括以下 8 篇内容:

  • 混合云架构挑战与概述
  • DCP 的不可变基础设施
  • DCP 的弹性调度揭秘
  • DCP 的镜像分发实战
  • DCP 的容器编排设计与实践
  • DCP 的服务发现
  • DCP 的容量决策评估
  • DCP 的监控体系

概述

最近由于个人原因,与 InfoQ 约稿的专栏《微博混合云架构》很久没更新了,在此深表歉意。今天的主题内容主要写容器编排设计与实践。在开篇之前,我觉得有必要回顾一下前面内容。目前已经发表了 4 篇。

  • 概述篇:主要分享了微博部署架构、业务场景、存在的挑战与痛点及微博混合云系统 DCP 的主体架构设计思想
  • 基础设施篇:主要分享了微博的不可变基础设施进化之路,环境标准化,配置管理等内容
  • 容器调度篇:主要分享了微博应用 Docker 的实践之路及容器调度演进
  • 镜像分发篇:主要分享了大规模下 Docker 镜像分发与优化实践,多版本共存等疑难问题解决方案

再看本篇前,可以回去看看 InfoQ 官网上这些篇的内容,有助于更好的理解接下来的内容。

关于编排

什么是容器编排?

编排是 Orchestration 在国内的常见译法,刚开始接触这个词时,我也很迷惑,为什么这么翻译,等理解了才明白一二,它其实是一种“设计”方法,在很多领域可见,在 Container 技术大火后,才真正进入我的视线。举个不恰当的例子:编舞师要想创作一个好的舞蹈作品,必须精心的编排,这包括灵感及创意、挑选演员,人数安排,舞美设计,人物动作表情,排练及突发情况下的应对等等,是一个复杂的过程。

对标到 Container 的场景,我们知道原生的 Docker,其实是个单机版的,所以 Docker 官方才会出了一系列的工具,比如最早的时候单机版的编排工具 Fig(团队被收购),远程下的编排工具 Swarm,甚至发布了 Docker Datacenter,其中的 UCP 就嵌入了 Swarm,以实现对 Docker 的环境管理与编排。

因此,对于容器编排,可以从以下两个方面理解:

  1. 容器编排是跨主机去管理多个集群 Container 的一种行为,随着 Docker 的发展,生态圈越来越完善,比较常见的 Kubernetes,Mesos + Mathon,甚至 DCOS 等都属于此类范畴。

  2. 容量编排是为了将资源利用率最大化,同时均衡系统因容错需要不断变化的需求。可以看下图

新浪微博混合云架构实践挑战之容器编排设计与实践

我们可以看到,早期的应用场景,经典的三层架构中,不管物理机或者 VM,一般一个机器一般只跑一个服务,而在 Container 时代,不同的服务可能跑在同一个机器节点上,这种服务的组合是不固定,动态的调配,对工程师是透明的。这种动态的调整能力可以称得上是容器的编排。

从这个图中我们可以抽象出,容器编排需要解决哪些方面

  1. 服务定义:一般以 IP + port 唯一标识一个服务,这里端口的分配与管理会成为重点。

  2. 资源管理:一个服务要运行,需要相应的资源,一般是 CPU/MEM/DISK/NET 等,怎么获取到这些资源,并合理分配是资源管理需要关注的部分,一般采用池化处理(资源池)。这也是编排的核心,Mesos 在这块做的比较好,通用且稳定。

  3. 容器调度:有了资源,怎么合理的选择资源节点,采取什么策略,怎么做容错处理等等,这些是容器调度需要关注的。

  4. 服务检测:服务在起来后,要对外提供,需要验证其正确性,这里一般会做端口及业务检测

  5. 服务发现:验证通过的服务,如果真正对外提供服务,需要引入流量,也就是自动挂到 LB 上,这也是一种 WEB 类的服务发现。

以上 5 种我觉得是容器编排里最核心的内容,实际上,生产环境的编排单元远远比这里多很多。

注: 这里插播一个,我经常看到很多同学把容器编排和容器调度等同,其实吧,无所谓对错了,这可能主要的原因是大家的理解不一样,表达的方式也就有差异,不用纠结,只要把你的业务问题很好解决了,就是棒棒哒。

分层的编排?

随着行业的发展,我们看到互联网技术领域的一些趋势:

  1. 可编程的基础架构的崛起,比如云计算,配置管理,Contianer 技术
  2. 应用架构的变迁,单体应用 ->SOA-> 微服务
  3. 新流程及新方法论的出现:如精益,敏捷和 DevOps

在这样的趋势下,互联网公司多多少少都会根据自己的业务场景做出一些改变,比如升级应用架构,业务上云等等,这其实对运维来说,复杂性在过渡阶段是增加的。就拿我们的业务来说,建设私有云的同时,也推业务上云,我们的基础架构很难用标准化的方式去满足需求,这也推动我们去重新建设运维平台,也就有了混合云系统 DCP 的诞生。我们在设计之初的时候,遇到了一个很明显的问题,我们很难用单一的 IaaS,PaaS 或 CaaS 去定义我们的场景,于是我们选择了混合云的模式,系统采用分层设计的方法去适应业务场景。

在这个过程中,我对编排的理解又有了一些变化。我觉得不同的层是存在不同的编排方法的。简单来说,IaaS 的编排核心重点在计算资源,PaaS 的编排核心在于应用,CaaS 的编排核心在于容器即服务。而对于我们的混合云 DCP,我把他分为两大方面:

  • 服务的编排:重在弹性,比如扩容,缩容,容器迁移,容错处理,服务发现等
  • 资源的编排:重在资源,对于私有云主要是物理机的管理与分配;对于公有云主要是标准化的 VM,我们用到了阿里云的 ECS

对于资源的编排,混合云模式下,专线的落地是最重要的,决定着整个设计及业务上云的规模,如下图,我们与阿里云之间就通过 VPC 技术拉通了常备的专线,打通内网。

新浪微博混合云架构实践挑战之容器编排设计与实践

在分层设计之上,我们在工具选型上就明朗多了,主要选用了自研的 Dispatch 和 Swarm。

微博混合云 DCP 架构设计

微博目前开发的 DCP,主要包含 3 层,资源管理层,容器调度层及业务编排层。底层的资源管理分为两个部分:内网主机和阿里云 ECS,我们的目标是对上层业务提供统一、不可变的基础环境 ; 中间的容器调度层,主要是根据资源去调度容器,并启动容器,提供各种原子型的操作,比如基于任务模式的容器起、停、删、重启、服务注册、服务反注册、服务检测等等;最上层的业务编排层,则是基于调度层的 API,去串起整个业务的常见操作,比如服务部署、扩容、缩容、容器迁移等等。根据上面对于编排的理解,我觉得把资源层算作资源编排,而调度层与业务编排层,统一称服务编排。我们看下图:

新浪微博混合云架构实践挑战之容器编排设计与实践

这里需要说明的是,分层设计的指导思想的核心:

  • API 化:层与层之间皆是 REST 型的 API 相互通讯,底层对上层提供 API。
  • 操作幂等:核心的操作是可重复的且可逆的。
  • 容错处理:对异常及失败情况下的容错处理。

细化出来,DCP 的功能模块是很多的,可见下图:

新浪微博混合云架构实践挑战之容器编排设计与实践

其中,资源管理层的模块主要是调度运算资源。目前设计了共享池、Buffer 资源池,配额管理,及多租户管理机制,借此实现弹性调度资源,这也是 DCP 的核心之一,可以看做是一个定制的 IaaS 吧。调度层后面会细说,基于任务机制的容器调度。

这里重点说下业务编排层:最上层的是对业务场景的抽象,根据目前的梳理,微博的业务,前后端各种语言都有,加上大数据体系的服务,在这种情况下,我们很难抽象出用一种非常通用的模式,直接支持各种语言的服务,这也受限于不同服务的 Docker 化程序。于是我们做了如下设计:

  • 服务设计:我们设计了集群,服务池,容器节点这样的三级维度去描述服务

  • 业务级隔离:产品线对应集群,集群与集群之间在业务层上是产品线之间的隔离,各家自己的服务互不影响。

  • 开放业务编排层:微博后端几乎是 Java 类的服务,前端是 PHP 类,同时大数据体系又有离线计算和实时计算的,还有一些小语言的,每一类的服务,我们做成是通用的模式,比如 Java 类的就独立设计其编排模式,并且把这个设计开放到公司的范畴,别的部门也可以来一起参与设计并实现。在开放的过程中,我们的原则:底层的资源,调度,服务服务一定是全公司内统一的。

从这些架构设计角度,可以看出,我们的 DCP 的核心设计理念包括 4 个:弹性,自动化,业务定制及 all in one。相对 XaaS 类的服务,我们更注重业务需求的落地,解决实际问题。

ps:综合来看,我觉得有一个很重要的点,虽然 Docker 很火,但好多公司都很难将自己的业务 Docker 化的比较彻底,这其实也在影响着你的架构设计。比如与物理机还有一些依赖的东西,比如程序部署的逻辑关系,比如日志及围绕日志的周边工具,但是业界的一些开源编排方案,schedule/scale/rolling update 等这些操作,其实对业务的标准化要求很高,包括试用的一些云服务,要想把业务以最小成本的迁移部署,有一定难度的,所以有些公司内搞 Docker,定制化的需要还是很多的。所以如果你想大规模用,其实可以考虑牺牲一些通用性的原则的,我觉得微服务看来是一个解决方案,由于历史原因,我们很早就是服务化了的,要改造成微服务化,成本蛮高,因此从 14 年业务上云之后,虽然相对来说,走在了前面,但是一直还在路上摸索着。

服务设计

这一节,我们再来看看 DCP 对服务的设计,我们的核心需求是弹性,设计了集群,服务池,节点这三个维度,而弹性是建立在服务池这个维度的,以 IP + port 唯一标示一个服务。如下图:

新浪微博混合云架构实践挑战之容器编排设计与实践

众筹池与 Buffer 池

这里有个两个易混淆的概念,众筹池是所有集群的冗余设备;Buffer 池是集群内的冗余设备。这么设计的主要考虑是,某个业务在集群内的服务之间,是很容易自己去弹性调整的,集群内容量不足了,则会去私有云内调度,私有云内也没有的,会去公有云调度。保证服务可用性,同时为了保证每个集群(产品线)不乱用,给集群设置了配额的管理。从业务运维的角度可以看到如下的流程:

新浪微博混合云架构实践挑战之容器编排设计与实践

除此之外,值得一提的就是 DCP 的用户视角,我们设计了三类角色:

  1. 超级管理员:负责管控私有云及公有云的资源
  2. 集群管理员:负责管控自己产品线内的资源
  3. 服务池管理员:基本上业务运维,他们负责线上各种具体的操作

新浪微博混合云架构实践挑战之容器编排设计与实践

业务编排

有了服务设计以及原子型的调度 API,去实现业务编排就简单很多了,大体可以分为 2 个部分:首先,根据某类业务场景,设计较为通用的 Docker 化方案;其次是服务部署及弹性扩缩容。

弹性扩缩容

在概述篇中,我们已经讲到,服务的弹性扩缩容其实是一些很重的操作,在 DCP 中,做了 3 个流程的设计,来串起这些复杂的操作,这 3 个流程是:资源申请、设备初始化及服务上线。弹性扩容任务所需要的设备来源是内部的集群以及外部的阿里云。而申请到足够设备后,也必须对设备进行初始化、部署环境及配置管理。最后一步则是将服务上线,开始执行 Container 调度以及弹性扩容的任务。

第一步,则是资源申请,这在服务的设计已经详细说了,私有云的设备来源,主要来自离线集群、低负载集群以及错峰时间空出的多余设备。具体来说:离线集群并不是时时刻刻都在执行运算,即使稍微减少计算资源,也不会对业务产生重大影响;而工作负载较低的集群,如果有多余的资源也可以进行调度。此外,微博有上百个业务线,每个业务线峰值出现的时间点都不一样,而在此种状况下,各业务也可以互相支援,共享多余的计算资源。私有云的设备不足,会去公有云上自动创建,整个操作流是自动化的。

第二步,则是设备初始化,我们已开发了工具系统:可以达到操作系统升级自动化、系统操作 API 化,而服务器所依赖的基础环境、需要的软体等环境配置等需要标准化。如下图

新浪微博混合云架构实践挑战之容器编排设计与实践

私有云内通过配置管理工具 Puppet,将需要的配置写成模块,并使用 RPM 机制打包,进行安装。而公有云则是通过 Ansible 来做此类工作。这块业界中的一些做法也可以免去初始化的流程。例如导入为 Container 而生的容器操作系统,像 CoreOS、RancherOS 或 Red Hat Atomic。不过,虽然这样可以,但是此种做法的可维护度高,但是缺点在于迁移设备的成本较高。

当然这个操作也是耗时操作,主要的时间取决于申请资源的时间,实际初始化也就只需要 1 分钟而已。

(点击放大图像)

新浪微博混合云架构实践挑战之容器编排设计与实践

第三步,则是最为复杂的弹性扩容操作,前一线的运维人员,只要在系统页面上输入服务池名称、服务类型、Container 类型、需要 Container 数量以及镜像地址等参数,即可在 5 分钟内完成扩容,扩容完成后,系统也会产出完整的报告,列出扩容程序中,执行的步骤,以及每件任务的成功、失败状况。我们先来看下扩容流程:

新浪微博混合云架构实践挑战之容器编排设计与实践

我们再来看看耗时分析:可以看到大部分的弹性扩容任务都是分钟级的,总体上,基本能完成 10 分钟扩容上千 Container 的能力。

(点击放大图像)

新浪微博混合云架构实践挑战之容器编排设计与实践

任务系统设计

由上面可以看到,这些每一个流程能够很好的串起来,以及容错机制,这背后是有一套任务引擎在工作的,这个就是任务系统。其主要的思路是改造原有自研的 jpool 系统为任务引擎,来串起这些操作。

  • 任务定义:详细的任务参数设计,模板引擎,回滚等
  • 任务控制:并发执行,并发数控制,比例及步长控制,超时控制等
  • 容错处理:异常及失败处理,容器迁移等

详细信息,可以看我在 Qcon 2015 上有个 Jpool 的分享,这个就不细说了。

无人值守的弹性扩缩容

再次回到概述篇,我们建立这一套系统,核心要实现的是服务具有弹性,能根据容量情况进行自动的弹性伸缩,以此来解决明显的早晚高峰及热点事件的峰值问题。截止到上面讲的,我们的系统已经完备了,但是操作的触发是需要人的参与,而且也会有几个操作步骤,人本身是懒惰的且是易犯错的,且还会存在人力成本,这还没达到我们的目标,离无人值守还差一段距离,于是,我们又开发了两个工具:

  • 容量决策系统:可以每周在线压测服务,评估出每个服务的容量数据,以供决策;
  • 调度框架:在任务之上,采用基于时间段的调度策略,在业务访问低峰时执行缩容策略, 高峰来临前执行扩容策略。

经过分析,我们的调度框架需要有以下几个特性

  1. 支持各种调度策略,初期可考虑实现基于时间的调度方式,类似 crontab 触发机制,Chronos、 Quartz 提供可借鉴的任务调度实现机制。

  2. 支持主备模式,如 Mesos 和 Swarm 多提供了多主的实现,其中 Swarm 采用 consul、etcd、 zk 等协调服务,各 master 间通过竞争一个分布式锁的方式来获取 leader 权限,获得 leader 权限的进程对外提供服务,未获得 leader 权限的进程处在等待状态,可参考 Swarm 的多主实现方式。

  3. 提供 Http API 运维配置,Consul 提供了非常优秀的 RestFul 协议和 UI,可参考。

  4. 支持服务的依赖,A 服务依赖 B,B 在自动弹性扩容时,需扩容好服务 B。

  5. 所有参数,可配置化。

最后形成的架构如下,并用 Go 做了实现:

新浪微博混合云架构实践挑战之容器编排设计与实践

可以看到,在更高层面的调度框架具有以下特点:

  • 定时触发:以天为周期,自动执行扩缩容任务,任务结束后发送邮件提醒;
  • 依赖控制:如 V4-Feed 依赖 RPC-User,严格控制上下线顺序与数量比;
  • 并行化:即使有依赖也只在关键流程做同步控制,不同业务完全并行;
  • 容错机制:重试、超时、回滚 (如扩容中失败的机器立即释放) 等;
  • 可重入与幂等性:进程重启后从退出点继续运行,同一个时间任务执行多次均不受影响;
  • 多 master 机制:确保 Scheduler 本身的 HA。

这个调度框架组件目前已经很稳定,每天都会定时的在晚高峰进行自动弹性扩缩容。有了它,我们私有云的核心服务的冗余,从之前的冗余 150% 减少冗余 120%,这样就可以下线调一大批机器,以节省成本,真正实现基于公有云的弹性。

除此之外,基于这个框架 API,做了个可配置的简单页面,定义服务以来及弹性扩容参数,非常的方便,见下图:

(点击放大图像)

新浪微博混合云架构实践挑战之容器编排设计与实践

ps: 此任务非上面任务系统中的任务。

总结

基于容器的业务编排在整个混合云的设计当中,是非常核心的内容,为新浪微博元旦,春晚及日常晚高峰的弹性扩容提供了强有力的支持。我们当前还在不断的完善系统的建设,同时,也正在纳入更多的业务场景,还是那句话,基于 Docker 的云应用,我们一直在路上。希望我们的方案对大家有一定的参考意义。


感谢魏星对本文的策划和审校。

给 InfoQ 中文站投稿或者参与内容翻译工作,请邮件至 editors@cn.infoq.com 。也欢迎大家通过新浪微博( @InfoQ @丁晓昀),微信(微信号: InfoQChina )关注我们。

评论

发布