查看原文
其他

微博基于Docker的混合云平台设计与实践

2016-01-11 王关胜 高可用架构

编者按:本文由王关胜向「高可用架构」投稿,介绍其在台湾 iThome 举办 Container summit 2015技术大会分享精华。转载请注明来自高可用架构公众号「ArchNotes」。


王关胜,微博研发中心运维架构师。2011 年初加入新浪,一直负责微博平台&大数据等业务线的运维保障工作,包括产品稳定性,运维基础设施建设,工具建设等。致力于推进 Docker 在微博的应用,参与建设微博混合云平台 DCP。擅长大规模分布式系统集群的管理与运维,疑难问题分析,故障定位与处理等。对运维工具平台建设、监控、应用性能跟踪及分析、数据化运维等方面有深入的研究。


2011 年初,新浪微博进入快速发展期,同时也开启平台化的进程,服务器设备,及人力成本大量增加,业务的快速发展,促使运维团队建立了一套完整的运维平台。虽然已稳定运行了 3 年,但随着公有云的逐渐成熟,Docker Container 技术的兴起,一时间各大型企业纷纷开始升级内部运维系统,提供自动化能力的同时,更注重弹性调度。我们也于 2014 年底构建了第一版基于 Docker 的运维平台,并在元旦,春节,红包飞等大型活动中得到了考验。但是要想更好的应对微博的这种业务场景,系统局限性还很多,比如设备申请慢,业务负载饱和度不一,扩缩容流程繁琐且时间长,基于此出发点,2015 年技术团队设计与实现了一套基于 Docker 的混合云平台 DCP。


微博的业务场景及混合云背景

微博目前有 8 亿注册用户,单日活跃用户数达 1 亿多。微博总体分为端和后端平台,端上主要是 PC 端,移动端和第三方开发者,后端平台主要是 Java 编写的各种接口层,服务层及存储层。就前端来说,每日超过 600 亿次的 API 调用,超过万亿的 RPC 调用,产生的日志就达百 T+。对于这么大体量的业务系统,对于运维的要求也很严格,就接口层来说,SLA 必须达到 4 个 9,且接口平均响应时间不能高于 50ms。因此技术团队会面临下述各种各样的挑战。


  • 产品功能迭代快,代码变更频繁

  • 业务模块多,且依赖关系复杂

  • 突发的热点事件,如典型的#周一见# #马航370# #刘翔摔倒# #明星丑闻#

  • 大型活动及春节、元旦保障,如红包飞


下面具体看下春晚时的业务模型:


每年的元旦,春晚,红包飞会带来巨大的流量挑战,这些业务场景的主要特点是: 瞬间峰值高,互动时间短。基本上一次峰值事件,互动时间都会 3 小时以内,而明星突发新闻事件,红包飞这种业务,经常会遇到高达多倍的瞬间峰值。传统的应对手段,主要是靠提前申请足够的设备,保证冗余;降级非核心及周边的业务;生扛这三种手段。这么做,除了成本高外,对系统进行水平扩容时,耗费的时间也久。


除了来自业务的挑战,在应对峰值事件时,对于运维的挑战也蛮大的。遇到难点较多的环节包括:设备申请太麻烦,时间长;扩缩容流程繁琐。


要完成一次具体的扩容,首先基础运维从采购拿到新机器,录入 CMDB,再根据业务运维提的需求,进行上架到相应的 IDC,机架,操作系统安装,网络配置,最后分给相应的业务运维,就是一台完整的可以登录的机器了。其次,业务运维拿到机器,需要对机器进行初始化配置,并继续服务部署。服务部署好后,经过 check,再挂到负载均衡上,引入流量。设备坏了自动报修,过期下架或替换。具体可看下图




这种扩容的方式,除了流程繁琐外,还经常遇到各服务器间环境差异,无法充分利用服务器硬件资源,即使有多余的服务器也无法灵活调度。若采取新申请设备,在大一点的公司申请流程通常较长。一般设备申请是业务方及业务运维发起采购提案,然后相关方进行架构评审,评审通过,则由 IT 管委会评审,再由决策及成本部门评审,评审通过,进入采购流程,再上架,还经常遇到机房机架位不足,这些都导致交付周期变得很长。


除了业务扩容的繁琐,公司内设备利用率也不均衡,主要表现在三个地方:


  1. 各个业务组的服务器利用率各不相同,大家对利用率的理解不一致,导致有些设备未能得到充分利用,这也会导致更大的成本压力。

  2. 各个业务模型不同,比如有的业务高峰是在晚 22 - 23 点,有的业务则在中午。

  3. 在线业务与离线业务完全分离,导致成本也高,对于离线业务,可在低峰继续跑在线业务


正因为这些挑战,怎么能更好的解决,技术团队想到基于 Docker,及公有云来构建一套具有弹性伸缩的混合云系统。利用过去的私有云加公有云,以及公司内闲置的运算资源,混合云,兼具安全性与弹性扩展能力。其特点如下图



有了这套混合云系统后,不仅能很好的整合内部运算资源,解决内部的弹性需求外,当系统面临流量剧增的峰值事件时,也可以将过多的流量切入外部公有云,减轻内部系统的压力。


两种云内的设备如何使用呢?内部私有云设备安全性高,可控度也高,只要对硬件资源进行优化配置,用它来处理固定的工作负载。而公有云的设备则具有标准化,自动化的特性,可以快速因临时需求,在流量暴涨时,可以快速创建大量 ECS,扩容业务工作负载的能力。而对于公司,可以利用公有云这种按需付费的机制,减低硬件的运营成本。因此采用混合云架构,就可以兼具私有云及公有云的优点,可以同时拥有安全与弹性扩容能力,使业务工作负载可以在业务间进行漂移,低负载的业务就应该使用更少的设备,反之亦然。而基于 Docker 来做,对于上述情况来说,复杂度降低很多。


三大基础设施助力微博混合云

微博混合云系统不单只是一般的混合云,而是应用了 Docker,透过 Docker Container 快速部署的特性,解决海量峰值事件对微博系统带来的压力。过去公司在面对峰值事件,一般采取的作法是,首先评估需要多少额外设备,并向外部公有云申请机器分摊流量。然而,除了可能低估应付峰值事件所需的设备外,即使事先準备了足够的 VM,其部署时间成本也远高于 Docker,无法即时帮助公司分摊过多外部请求。


而微博 Docker Container 平台的混合云核心设计思想,主要是借鉴银行的运作机制:民众可以把钱存在银行,而需要使用金钱的时候,只需要提领一部分,剩余的存款银行可以拿去进行投资。而微博则借鉴银行的这一套运作模式,在内部设立一个运算资源共享池外,还导入了外部公有云。


而要微博实现高弹性调度资源的混合云架构,其中实现的关键则是 Docker。刚开始我们思考该要使用裸机还是 VM 架构,作为 Docker Container 的基础设施。后来,考量如果要采用 VM,内部机房架构要进行许多改造。所以,目前微博的内部私有云使用裸机部署,而外部公有云则采用阿里云弹性计算服务(ECS)的 VM 架构。等平台建设成熟后,还可以应用其他厂商公有云,如 AWS 等。


构建 Docker Container 平台基础架构的 3 大关键,包含 Docker 在裸机上的部署架构、改进版的 Docker Registry 以及负载均衡组件 Nginx Upsync 模块


第一是 Docker Container 的裸机部署方案,透过 IP 位址以及 Port 定义一个唯一的 Container 服务,而每台主机上则可以开启多个 Container,各个具有不同的功能。


每一个 Container 服务所产生的行为日志,会经由一个名为 Scribe 的 Container 集中收集。而集中后的数据则可进行用户行为分析。对于容器类监控数据,则是透过建立 CAdvisor Container,将 Container 运行产生的资料,传送至 ELK(Elasticsearch、Logstash 及 Kibana)开源监控软体,进行分析。对于业务数据,通过 Graphite,监控业务系统的运作状况。


第二则是 Docker Registry,我们使用 Docker 官方提供的 Docker Registry,构建了私有的 Registry Hub,并且透过这个私有调度 Docker Container 需要的镜像。



今年基于 V2 版的 Registry Hub,将存储引擎改为使用分布式开源存储平台 Ceph,并且在 Docker Registry 前端结合 Nginx,实作负载平衡功能。这个过程中,比较麻烦的是,在 Docker 版本升级过程中必须让系统能够兼容新旧版本的 Registry Hub,而前端 Nginx 可以分析系统需求,辨別要从新版本或是旧版本 Docker 仓库下载镜像。而外部公有云,则是透过镜像缓存 mirror,不必像私有云一样,部署完整的镜像仓库。


对于镜像服务,总共包含 3 层架构。包含最底层操作系统、中间层的运行环境如 Java、Tomcat,及最上层的 Container。而在调度 Container 时,透过使用 dockerignore 指令,减少不必要的文件、目录,借此减低映像档的容量。除此之外,在镜像标签命名上,我们则禁止使用「Latest」做为镜像标签。这是由于不同使用者对于标签的理解不一,可能会误以为是代表映像档最新的版本。


而第三则是独立研发的 nginx upsync 模块,去年刚开始使用 container 时,将container 挂到 nginx 后,必须通过重启或 reload 指令,使流量生效。而这个过过程中,nginx 对于特別大的并发流量会发生运行不稳定的情形,因此后来开发了 nginx upsync 模块,不通过 reload 指令重启,也可以保持系统稳定运作。针对两种模块进行比较,发现流量大时,用了 nginx upsync 模块,不做 reload,单机扛量多了 10% 的请求,且性能并不会降低。


Nginx upsync 的核心功能主要是:

  1. Fix Nginx reload时带来的服务抖动

  2. Fix Web Container的服务发现


项目已开源至 github 上:https://github.com/weibocom/nginx-upsync-module

其架构如下




微博混合云 DCP 系统设计核心:自动化,弹性调度

目前开发的 Docker Container 混合云平台,包含 4 层架构:主机层、调度层及业务编排层,最上层则是各业务方系统。底层的混合云基础架构则架构了专线,打通微博内部资料中心以及阿里云。


主要思想:来源于官方三驾马车(Machine + Swarm +Compose)




DCP 混合云系统的设计理念,总共包含 4 个核心概念:弹性伸缩、自动化、业务导向等。


DCP 系统,最核心 3 层架构:主机层、调度适配层及编排层。


主机层的核心是要调度运算资源。目前设计了资源共享池、Buffer 资源池,配额管理,及多租户管理机制,借此实现弹性调度资源。


而调度层则通过 API,把调度工具用 API 进行包装,而微博 4 种常用的调度工具组合包含:Docker、Swarm、Mesos 及自主开发的 Dispatch。


而最上层的则是负责业务编排及服务发现。编排层也包括了大数据工具Hadoop,进行大数据分析的业务场景。


对于调度来说,最重要的就是资源管理,Mesos 处理这个是最合适不过了,很多公司就专用其做资源管理,比如 Netflix 写了一个 Titan 调度服务,其底层资源管理则是通过 Mesos。在调度组件中,使用最多的还是 swarm,dispatch。


可以看下面这个场景:这也是私有云内部资源流转的最佳实践


当业务 A 多余的运算资源导入混合云共享池时,此时流量暴涨的业务 C,可从共享池调度业务 A 的运算资源,而峰值事件后,便可以把多余的运算资源归还至共享池。


DCP 对于物理主机的流转,基于资源共享池、Buffer 资源池,配额管理,及多租户管理机制,其实非常复杂,详情可以去看我在台湾 iThome 举办 Container summit 2015 技术大会上分享的内容。这里可以看一下一台物理主机的生命周期(状态流转图)


引入阿里云做为第三机房,实现弹性调度架构

起初,对于是否采用混合云的架构,技术团队也是做了一番考虑的。目前微博机房的部署架构总共分为 3 层,依次是最上层域名以及负载均衡层。中间则是Web 层,包含各种前端框架,RPC 层以及中间件(Middleware)。而最下层则包含 MySQL、Redis、HBase 等资源架构。


微博核心服务主要分布在 2 个机房,两者互相做为灾难备份用途,而第 3 个机房则采用外部阿里云。混合云架构总共有 2 种部署方案。


第 1 种部署方案,将阿里云视为数据中心,底层架构与微博内部机房一样部署。内部机房采用 nginx 做为负载均衡层,但外部公有云则 SLB 引入流量。其他阿里云的中间 Web 层则与内部机房架构一致。不过,出于存储数据需要考虑的因素较多,初期把阿里云做为应付大量峰值时的方案更为简单,存储永久性数据的MySQL、HBase暂不部署于阿里云。


而第 2 种部署方案则把应付峰值事件需要的弹性计算能力迁移到阿里云。第 2 种部署方案困难之处,需要把微博的内部业务进行改造,让微博中间 Web 层,直接对阿里云机房进行 RPC 调用。此种方案部署结构相较比较简单,也让混合云架构具有实现可行性。


而这 2 种方案都会依赖 VPC 网路,如果有没有专线,想实现公有云的弹性计算能力几乎是不可能。因为公网调度资源的延迟时间太高,无法应付微博大量的业务。因此,技术团队与跟阿里云合作,在两边建立了内部专线,让阿里云机房与微博的机房互通。


大规模集群操作自动化:设备申请,初始化,服务上线

微博 Docker Container 混合云 DCP 设计思想,核心目标就是透过自动化操作大规模集群,进行弹性调度资源的任务,要完成此任务,必须经过 3 个流程:设备申请、设备初始化及服务上线。


弹性扩容任务所需要的设备来源是内部的集群以及外部的阿里云。而申请到足够设备后,也必须对设备进行初始化、部署环境及配置管理。最后一步则是将服务上线,开始执行 Container 调度以及弹性扩容的任务。


第 1 步骤则是申请设备,而设备申请借鉴于银行机制的概念。私有云的设备来源,主要来自离线集群、低负载集群以及错峰时间空出的多余设备。具体来说:离线集群并不是时时刻刻都在执行运算,即使稍微减少计算资源,也不会对业务产生重大影响;而工作负载较低的集群,如果有多余的资源也可以进行调度。此外,微博有上百个业务线,每个业务线峰值出现的时间点都不一样,而在此种状况下,各业务也可以互相支援,共享多余的计算资源。



而不同业务的集群则各自独立,并且具有独立的资源池。集群内可以自由调度资源,例如,缩小 A 服务的规模,将多余的运算资源分派给 B 服务。若集群要调度外部资源,也有设计配额制度,控制每个集群分配到的资源。在集群外,必须看 Buffer 池是否有足够的资源,如果足够的话,可以直接将 Buffer 池内的设备初始化,进行使用。


反之,如果 Buffer 池内的资源不足,也必须查看是否有足够的配额,可以直接申请机器。当设备申请完成,直接分配给 Buffer 池后,随即被纳入 DCP 使用,所有可调度的主机只能通过集群自己的 Buffer 池。


第 2 步骤则是设备初始化;通过自己开发的工具系统,可以达到操作系统升级自动化、系统操作 API 化。而服务器所依赖的基础环境、需要的软体等环境配置,透过配置管理工具 Puppet,将需要的配置写成模块,并使用 RPM 机制打包,进行安装。


在初始化流程中,必须要支持软件反安装模式,例如,当A业务要调度设备时,其他业务在交付设备前,必须要先透过反安装程序,将要设备恢复为最原始的状态。


而目前业界中的一些做法也可以免去初始化的流程。例如导入为 Container 而生的容器操作系统,像 CoreOS、RancherOS 或 Red Hat Atomic。不过,虽然这样可以,但是此种做法的可维护度高,但是缺点在于迁移设备的成本较高。


第 3 步骤则是利用完成初始化的设备,开始进行服务上线。目前一线的运维人员,只要在系统页面上输入服务池名称、服务类型、Container 类型、需要 Container 数量以及镜像地址等参数,即可在 5 分钟内完成扩容,扩容完成后,系统也会产出完整的报告,列出扩容程序中,执行的步骤,以及每件任务的成功、失败状况。


总体来说:一键扩容流程如下




应用微博Docker混合云,不怕峰值事件

在用微博混合云 DCP 时,优先调度内部的共享池资源的运算资源。但是在红包飞、春晚时,则必须调度外部的运算资源。平日的正常状况下,阿里云只需提供几百个运算节点,并且在 5 到 10 分钟内完成部署任务。但是,面对春晚、红包飞的峰值流量,则要提供数千个节点。这对阿里云的机房也是有较高要求的。


目前 Docker 混合云 DCP 平台,去年 10 月完成第一版,Container 数量千级。截止发稿,基本上手机微博,微博平台,红包飞,在今年的春晚,都会基于此系统进行峰值应对。上线以来,达成了微博所设定每次水平扩容时间低于 5 分钟的目标。「有这样的弹性调度能力时,系统面对大型活动的峰值压力就小很多。」


本文由王关胜投稿,想更多交流上述话题,可以回复 join 申请进群。转载本文请注明来自高可用架构 「ArchNotes」微信公众号并包含以下二维码。



您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存