新浪公有云Docker编排实践

TammyBrando 8年前
   <p>大家好,本次分享的主题是 <strong>微博DCP系统 — 基于Docker容器混合云架构的应用实践</strong> 。</p>    <p>我这次分享的主题更偏向于实践应用,比如在大峰值流量的情况下,对于私有云解决不了的问题,我们如何利用容器技术跨云端动态调度,比如10分钟之内创建100到1000个节点解决流量峰值问题。</p>    <p>本次分享主要是分为四个部分:</p>    <ul>     <li>微博的业务与混合云</li>     <li>业界趋势与DCP技术架构</li>     <li>弹性调度</li>     <li>混合云三节实战</li>    </ul>    <p>下图展示的微博业务规模:</p>    <p><img src="https://simg.open-open.com/show/24843bdcb2e88a44703423cf6d2bef7e.jpg"></p>    <p>从图中可以看出,微博用户日活跃1亿,接口访问量百亿级,设备数量W+,所以每一次的技术升级对于我们都是很大的一个挑战。</p>    <p>目前微博的用户访问特点基本上分两种:</p>    <p>春节峰值流量会是平时的两到三倍。如果为春晚花掉上千万来采购设备,将是一笔很大的开销。</p>    <p>娱乐事件。突发事件是我们无法来预料,也是我们无法预先准备的。</p>    <p><img src="https://simg.open-open.com/show/131884d636f0fc5caa9c927e609635e5.jpg"></p>    <p>如上图右上角所示,10分钟之内数据流量呈现出3到4倍的增长,假如我们技术平台内部是2000台的服务器,对于 web 服务器来说,就需要10分钟之内扩容4倍,才能承受住流量激增的冲击。2014年微博已经做了容器化,当时只是一个私有云的建设。但是如果流量增加到3到4倍的时候,之前的技术是解决不了现在这种状况的,可无可扩。所以我们面临的一个问题就是,如何在10分钟之内完成1000个节点的扩增。</p>    <p>上图下方显示的是我们公司内部项目评审及设备申请的流程,此流程耗时可能长达两个月,无法及时应对刚才所提到的峰值问题。</p>    <p>目前主要的痛点基本上就是极端峰值、成本、扩展性以及业务加速迭代,这些给我们提出了更高的技术要求。今年开始我们参考了业界的混合云趋势,比如安全、可扩展性、成本等方面。此外,国外的 <strong>Zynga</strong> 、 <strong>Airbnb</strong> 、 <strong>Yelb</strong> 以及国内的 <strong>阿里云</strong> 、 <strong>12306</strong> 、 <strong>高德</strong> 等公司都在用容器技术来解决问题。 <strong>Docker</strong> 、 <strong>Mesos</strong> 等容器新技术使大规模调度成为可能。</p>    <p>下面简单介绍下12306的案例。基于与阿里云的深度合作,我们了解到 12306 主要查询流量余票查询业务都放在阿里云上,但是其数据是会经过大约几分钟后才会更新,所以大家在12036上看到的余票数量可能是不准确的。火车购票用户可以容忍这种情况,但是对于微博的用户,用户发一条微博出来,不可能几分钟后才让大家才能看到,所以这对实时性提出了更高的要求。</p>    <p><img src="https://simg.open-open.com/show/99dbe98abd3685e95d58aed58c613a38.jpg"></p>    <p>微博混合云涉及到公有云和私有云,2014年微博平台实现平台容器化,建立一个共享、安全,资源整合的私有云,2015年利用公有云的高效和低成本,开始混合云方案。我们之所以选用公有云,可以通过算一笔帐来探究一下,如果我们在10分钟之内需要1000台机器,阿里云支持按量来付费。假如说一台机器每小时4块钱,我们需要1000台机器,一个小时需花费4000块钱。如果我们采购1000台机器,成本可想而知。使用公有云, 在一定范围内可以认为是无限扩容的。基于网络方面,阿里云内部是VPC网络,会为每个业务方创建一个内部的私有网络,微博与阿里云之间实现两个专线的连通,实现了网络互通。整个混合云分两个部分,一个是快速弹性调度,另一个是基础设施跨云。</p>    <p><img src="https://simg.open-open.com/show/c232d851f5d17a891c5f2bc2bc8ae4fc.jpg"></p>    <p>上图是微博 <strong>DCP系统</strong> 技术架构的演进历程。第一阶段是容器化,2014年我们做了单机容器化、在线Docker集群。第二阶段是私有云,我们用的是弹性调度,然后是基于弹性调度的服务发现以及私有云的建设。第三阶段是混合云,我们把公司离线资源接入,和公司资源进行整合,多种资源管理调度框架整合,实现了跨云端的调度。</p>    <p><img src="https://simg.open-open.com/show/e244b105e1228adf17e8ff606b5409b6.jpg"></p>    <p>上图是一个基本的混合云DCP技术架构图,它来源于Docker的三架马车,分别是编排、调度以及主机。编排系统 <strong>Jpool</strong> 发起,比如上线发布、回滚等各种命令。比如现在想要获取1000个节点的容器信息,向调度层进行申请,调度层向Docker进行下发命令,然后获取容器信息。基础环境在底层Pluto系统偏主机层,它的主要作用是和阿里云主机进行打通、计算成本,最重要的是进行初始化,初始化之后首先会安装Docker环境,包括Swarm、Mesos,之后这些机器进入一个可调度的状态,底层通过一个专线,保证阿里的机房和我们的机房进行互通。当然除了Docker这三架马车体系之外,还离不开一些服务发现、镜像中心、监控中心、容量评估等。</p>    <p><img src="https://simg.open-open.com/show/84187977380e109eb1f73ed0f7698b90.jpg"></p>    <p>上图是我们的技术栈,主机或VM主要是私有云裸主机,公有云VM,在上面进行Docker的具体化;OS方面,线上90%的业务已经升级到CentOS 7.0;Docker 版本是1.6.2,之所以还在选用Host模式,微博访问流量量非常大,选用其他模式导致我们的系统性能有所下降,所以我们选择Host模式。Iptables我们也是关闭的,因为打开它之后会影响性能。Docker Registry方面,我们构建了自己的仓库,有V1、V2的版本,实现分布式跨IDC动态同步。Swarm版本是1.0.0。部分小规模的服务用Marathon是进行调度。所有的服务发现基于Consul的,Consul的版本是0.6.0。</p>    <p><img src="https://simg.open-open.com/show/3af046c000915f53f5e274a68cc3fc90.jpg"></p>    <p>上图显示的是混合云DCP功能模块,基本上分为PAAS、IAAS和基础框架。容器技术虽然解决了我们快速发布问题,但是如果要真正解决峰值流量的问题,还需要建设完整生态体系。</p>    <p><img src="https://simg.open-open.com/show/0ebb5af6c0498777a613d4dfb4cd6b09.jpg"></p>    <p>下面简单介绍一下DCP的核心思想,2014年的时候只有微博平台内部进行了Docker化,微博的业务是这样的,用户用电脑刷微博的时间集中在中午,晚上用户大都用手机刷微博,而且在凌晨的时候,我们的离线机又开始忙了。每个部门每个时段,它的机器会有空闲的状态,如何把这些空闲的机器利用起来,设计共享池机制,评估它的容量压测,比如根据一些系统指标还有一些SLA的情况判断,如果机器空闲自动进入这个共享池状态,进入共享池就代表是可供调度的状态,共享池的机器可供动态调度。DCP整体的模式是基于银行的运作机制。</p>    <p><img src="https://simg.open-open.com/show/9e55553b0c3dc79ffd5477cb31acd05c.jpg"></p>    <p>上图是容器的一个生命周期。以私有云为例,当某一部门的机器空闲的时候,它进入共享池,代表这个机器可以用,这个机器进入共享池之后进行初始化,初始化之后按照上图下方所示,Docker环境或者是机器环境启动,代表容器可以进行动态调度,直到容器上线。中午不繁忙的时候,容器进行下线再返回共享池。</p>    <p><img src="https://simg.open-open.com/show/05bc1f2fbb8bbb7b2d6888d590e59e06.jpg"></p>    <p>简单举个例子来说,比如此时需要机器,原来共享池里面ABCDE各个业务方空闲都共享给共享池,根据容量评估这时容器可以下线,然后利用资源进行动态扩容。当不需要机器的时候,归还共享池。</p>    <p><img src="https://simg.open-open.com/show/36595438dede9c67ed773af5eec2847a.jpg"></p>    <p>整个流程其实可以模拟成这样:首先是主机申请,包含内网申请和云端申请。内网申请相当与在共享池里面申请,但是内网会出现一种情况,假如平台有2000台机器,当出现5倍或者10倍流量增长的时候,扩无可扩的时候,则进行云端申请。拿到主机之后进行初始化,初始化的时候主要安装两个环境,一个是系统环境,一个是Docker环境,Docker环境大家都理解,肯定要把Docker装上,容器才能运行,成为可动态调度的模式。为什么还要装系统环境?任何一个公司的产品、任何一条业务线,业务跑到一个真正全新的主机上,肯定有自己的系统环境或者各种各样的配制、脚本等。我们系统初始化的时候,其实是按照业务方进行选择,业务方用各自的模板来初始化。基于初始化之后,可以进入动态调度的阶段,然后使用算法实现动态调度。比如申请了1000台机器,容器上线之后,再调度上面的服务发现策略(Nginx、Motan、SLB),然后进行反初始化,归还Buffer池、结算中心。刚才提到按小时算的成本,按小时每小时4块钱,还是赶快归还比较好。</p>    <p><img src="https://simg.open-open.com/show/0af67d086cf50497edd6e5c723fbb918.jpg"></p>    <p>上图为主机申请的流程。阿里云在北京有三个机房,每个机房据介绍有万+台机器,用户可以选择可用区域,然后选择交换机确定IP端,选择VPC网络,VPC网络可认为自己独立的私有网络。选择操作系统VM镜像,刚才提到初始化的时候,有Docker环境,在整个环境动态扩容的过程中,动态调度的要求几十秒内完成。比如我有2G的镜像,还有70M的JDK,千台节点拉这么大镜像镜像仓库、网络带宽都是很大调整,这时候要怎么办?所有的云产品每隔6小时,把所有的系统VM镜像进行备份,比如我所有的镜像拉下来之后,包括Docker都放在云盘上,相当于一个备份,比如说下次创建主机申请的时候,选择已经做过的镜像,在这个操作系统上的镜像创建机器,这样基础镜像就在VM镜像上面,这样大大缩短了拉镜像时间。最后选择机器配制,选了主机配制之后初始化进行动态调度。初始化是其实基于Ansible,因为阿里云提供的是SSH访问,Ansible会有性能问题,在Ansible使用过程中我们做了优化,提高其性能。下图系统环境装了dnsmasq、ntp、cron等,软件环境安装了Docker、Swarm、Consul。</p>    <p><img src="https://simg.open-open.com/show/be44e80ce44bec2f2bf2419d27b02aa8.jpg"></p>    <p><img src="https://simg.open-open.com/show/876dbbc8f82345cd90c8569cea8f22a3.jpg"></p>    <p>谈到调度都离不开Swarm、Mesos、K8S,大家讲的比较多的都是Mesos、K8S,先说一下结论,今年年初的时候我们选用了Swarm,我们认为最适合业务的才是最好的。为什么选择Swarm?,因为它是Docker体系原生的,整个体系比较简单,也能支持我们的内存隔离,支持我们的分组调度,当然它是以标签的形式实现的分组隔离。微博备战元旦峰值时,需要整合离线技术资源及公司其他业务线带来了新的挑战。离线Hadoop计算资源服务器大多操作系统为CentOS6. <em>,CentOS6.</em> 支持Docker1.6.2版本存在bug,而Swarm调度获取内存、CPU资源信息依赖Docker版本必须大于Docker1.6.2。以此为契机Roam扩展支持Mesos + Marathon、直接Docker Demon下发两种调度方式。考虑后续整合公司的离线资源,k8s现在在非容器方面还有瓶颈,所以暂没有考虑。</p>    <p><img src="https://simg.open-open.com/show/c47f1147b3bcff373c951c7915c6bf16.jpg"></p>    <p>其实我们的需求是实现内网计算资源的统一调配,公有云上获得计算资源,快速自动化部署。上图有一个接口层,我们提供了通用进行调度来满足以下的功能。任何一个调度框架都不能完全满足我们的需求,拿到的任何一个框架也不能直接用,因为可能要有一些特性化的需求,比如服务池的动态扩增容,跨服务池、跨租户来调度,以及单机业务的灰度、多实例的部署、故障自动恢复、容量评估、跨IDC的高可用,所以我们做了二次开发,对外提供统一的Rest API。</p>    <p><img src="https://simg.open-open.com/show/ec124ab123ba234a170b65b1215e280c.jpg"></p>    <p>Swarm集群规模估计是国内相对比较大规模。重点讲一下Swarm,Swarm属于轻模式。首先我们做了它的高可用,就是双主策略,多机房的调度,还有对它的调度性能、调度算法做了一个优化,包括一些分组的调度和一个调度策略的设计。Swarm在最开始版本发起调度有全局锁,这样整个过程就变为串行,影响调度性能。排查发下调度慢主要集中在拉镜像慢,改进优化为预拉镜像,提升性能。Swarm1.0版本后改为分布锁,同步也大大提升性能,内部测试单机房Swarm支持千节点是没有问题的。针对以上问题针对Swarm进行二次封装,研发出调度适配层系统Roam。Roam对外提供Rest API,通过Swarm获取Docker容器信息,外层自适配调度策略后下发Swarm集群,同时支持Docker Deamon直接下发。</p>    <p><img src="https://simg.open-open.com/show/15231f686e771f125601016d9140a1ff.jpg"></p>    <p>现在简单说一下我们怎么做的高可用,动态调度的多IDC、高可用、可扩展。Swarm集群按照机房进行拆分,高可用、动态扩展</p>    <p>1. Swarm Manage、Client节点向Consul服务发现注册,当前Manage在Consul处于加锁状态</p>    <p>2. Roam根据IDC参数从Consul获取需要调度机房 Manage信息</p>    <p>3. Roam弹性调度策略,访问当前Manage,选择资源动态扩缩容</p>    <p>4. Swarm Mange从Consul获取节点信息,30s缓存Node节点信息</p>    <p>当其中一组Master节点Down掉,Standby Master注册进入Consul成为新主</p>    <p><img src="https://simg.open-open.com/show/9b58c4306c7b14705375fc540b0e1c23.jpg"></p>    <p>简单介绍下Swarm调度算法:调度=主机 or 容器过滤 + 策略选择</p>    <p>主机/容器过滤通过过滤器(标签)实现 docker run --label idc="tc"</p>    <p>主机/容器过滤后,根据各个节点的可用的CPU, Mem及正在运行的容器的数量来计算应该运行容器的节点进行打分,剔除掉资源不足的主机。</p>    <p>调度颗粒度</p>    <p>Memory:docker run –m 1g …</p>    <p>CPU:docker run –c 1 …</p>    <p>基本所有的调度框架分组调度都是标签,Swarm基于Docker Deamon Label标签(Docker Label标签修改必须重启Docker Deamon,在最近官方Docker 1.10.0版本已支持Docker Engine配置热更新,使容器与Docker Deamon的耦合性大大降低)。在Docker Label标签基础上,对标签进行扩展进行落地存储,记录执行不同调度策略,集成Swarm调度算法,支持跨集群/服务池调度、指定IP规划、定时调度、多实例调度等</p>    <p><img src="https://simg.open-open.com/show/434f5d6980f0b88c738ac33c83d95204.jpg"></p>    <p>Swarm的调度算法并不是太神秘,最核心的调度算法,最简单来看就是使用的CPU或内存除以物理机的内存,就是物理机所用资源占比。再看一下CPU的分数,如果内存的分数同时满足的话,总分数为CPU加内存的分数,并非很复杂。如果大家需要定制自己算法策略,可以去修改源码或者使用其他算法,但是目前这种条件下满足我们的需求,比如把这些策略选择出来之后,有一个80分,有一个90分,我们肯定选择用90分的。因为我们是尽量保证主机资源均摊使用。在调度算法中大家需要注意一点,就是Swarm资源只与容器Create时配置设定资源参数有关,与运行时实际使用资源情况无关。无论容器是否由Swarm创建,无论容器处在何种状态,只要配置了资源限额,调度时均会计算在内。</p>    <p><img src="https://simg.open-open.com/show/11502a14a429eff1765e3177ebf136a1.jpg"></p>    <p>我们跨云端调度还面临其他挑战。千台节点服务同时拉取镜像,还是跨IDC情况,镜像仓库是扛不住的,很容易因为拉镜像时间过长导致调度失败。在内网的情况下我们的Docker不会遇到这个问题,因为大家机器上都用Docker,基础镜像都已在上面,阿里云端为新装机ECS,没有基础镜像。我们在内网做了自己的私有仓库,在阿里云上做了自动同步私有仓库的镜像缓存集群,后续云端扩展到了多级镜像缓存。</p>    <p><img src="https://simg.open-open.com/show/b3b45e4c5de65f0d07a48ea55adba470.jpg"></p>    <p>跨云端服务发现的时候,七层流量的频繁变更会影响业务性能。微博Nginx Plus的开源版,支持基于Consul的自动服务发现,Docker容器启动会自动向Consul服务注册中心进行注册,Nginx的模块我们开发了自己的一个Core Module,作用就是去Consul拉刚才注册的容器节点信息,然后同步更新,实现平滑流量变更。可以看下上图,这是我们使用Nginx Plus之后,服务变更耗时基本无波动。同时我们设计了动态修改线上云端节点的权重动态适配后端的处理能力,公有云同等配置存在20%的性能损耗,建议权重调低。微博内部用的是Motan RPC的服务发现,它支持跨IDC流量切换,支持按流量权重配制定向路由。DNS服务发现,我们在阿里云上构建DNSServer与内网保持同步。</p>    <p><img src="https://simg.open-open.com/show/aa1ebffa4f88cb88c43913a237c93eac.jpg"></p>    <p><img src="https://simg.open-open.com/show/2c10d1dec06c7e8b66c4afaf0fe5c233.jpg"></p>    <p>还有最重要的是监控体系,服务真正跑起来,怎么知道健康状况?我们的监控分四个级别,系统级监控、业务级监控、资源级监控和专线网络监控。业务级监控是全网监控到单机容器监控。我们的容量评估系统在线压测确定服务指标,根据单机的平均系统指标(CPU idie Mem Load)带宽、业务SLA综合指标容量评估,来决策服务的扩容或者缩容。</p>    <p><img src="https://simg.open-open.com/show/26b42764e8811a249bb02a01d0c7ffe3.jpg"></p>    <p>当上面所有的都做完之后,主机创建,初始化完,动态调度完毕之后,然后简单来看三节保障与阿里云部署。在春晚时主要扩容无状态Web服务,可以做到10分钟扩容到千节点容器规模,抵抗峰值流量。在这里大家要了解一个情况,阿里云产品会有PPS的限制,可能在内网的时候PPS达到几十万没问题,云产品上限是10万+左右, 会影响业务单机承载能力。</p>    <p><img src="https://simg.open-open.com/show/52faf3e707d15e0a4e87d08174abba5b.jpg"></p>    <p>跨IDC混合云架构离不开基础网络,微博本身在北京核心两个机房。阿里云在北京有三个可用区,最大的是A和C,它是BGP多线接入的,微博电信、联通两根专线分别于阿里云A、C机房微博私有VPC网络互通,专线保证高可用,任何一条专线断了之后,另外一条路由自动进行切换。中间还搭了一个V*N网络,这个是走公网的,有一些需要推日志或者一些业务因为数据需要交互就走公网,因为它没有实时性的要求,我们就走这条线路。</p>    <p><img src="https://simg.open-open.com/show/c2571b950855cfff03523230aa22cc8c.jpg"></p>    <p>总结一下,其实2014年我们做了容器化,混合云DCP项目是在2015年10月份上线的,所有集群按三个IDC来拆分,峰值2500+的容器,包括业界前一段也有测试,一秒钟创建3000个容器乃至1万个容器是没问题的。双十一微博内网实现单日10多次扩缩容,单次扩容小于5分钟。元旦的时候实现的跨云扩容,微博混合云架构小规模试用。春晚动态扩缩容阿里云ECS千台+规模,承载微博核心Feed流及红包飞流量。</p>    <p><img src="https://simg.open-open.com/show/49032d87d21569121b953f8aada69861.jpg"></p>    <p><img src="https://simg.open-open.com/show/df6808f0f9e8863d18d2fb0d0071bf81.jpg"></p>    <p>这次分享偏向项目应用实践,最大感触就是从业务需求出发去设计系统架构,没有最好的架构和技术,目标是业务需求完成。比如我们现在真正实现了10分钟创建1000个节点的能力,解决了这种峰值流量的问题,Swarm其实满足业务目标应用场景,所以就选择了Swarm做容器调度。在用Swarm的过程中,包括一些单机灰度、分组调度问题,我们通过二次开发来解决。Swarm使用遇到的问题在其他资源调度框架都会遇到,没有任何框架都是拿来即用,最重要就是去实践,总结共性,设计通用性架构,所以就有了Roam的适配层适配不同调度框架。混合云项目周边体系比如监控、服务发现、在线容量评估等也是非常重要,这也是任何云平台不可缺的组件。</p>    <p><img src="https://simg.open-open.com/show/35e0a96fda31c996fc7aab3ced1ca6d2.jpg"> <img src="https://simg.open-open.com/show/34fa81ec9eb2b71ee332fb89bea066d1.jpg"> <img src="https://simg.open-open.com/show/cb39216d9ec40c889429f12cbd7c6ecb.jpg"> <img src="https://simg.open-open.com/show/c6c61ed684ae152620f525188c844ee1.jpg"> <img src="https://simg.open-open.com/show/e5d8f0da299083a38c886f41994f7c35.jpg"> <img src="https://simg.open-open.com/show/b3896dadb9177f6e43829d35096f8462.jpg"> <img src="https://simg.open-open.com/show/f195f8093c039290c2b04c8edc797dac.jpg"> <img src="https://simg.open-open.com/show/a950a723b51609563fe76886a3bed59a.jpg"></p>    <p> </p>    <p>来自: <a href="/misc/goto?guid=4959674943846088193" rel="nofollow">http://dockone.io/article/1495</a></p>    <p> </p>