2016-11-24 来源:阿里技术 作者:林轩
林昊(毕玄),阿里巴巴研究员,平台架构部负责人,淘宝服务框架(HSF)作者,异地多活项目负责人,目前致力于资源统一管理调度系统建设。
12月6日-7日,由阿里巴巴集团、阿里巴巴技术发展部、阿里云云栖社区联合主办,以“2016双11技术创新”为主题的阿里巴巴技术论坛(Alibaba Technology Forum,ATF)将在线举办。12月7日晚20:00,毕玄将在在线论坛上发表《阿里超大规模Docker化之路》的演讲。
众所周知Docker技术这几年大热,但是过去相当长的一段时间内,阿里内部技术人员只能自己私下玩玩,没法在阿里内部生产环境使用Docker,因为Docker要求的OS版本和内核版本都比较高,阿里内部的AliOS5u7和AliKernel2.6.32内核是在CentOS-5.7和linux-2.6.32内核基础上做了很多定制而来,没法运行Docker。如果将内部OS从5u、6u升级到7u,将内核从2.6.32升级到Docker官方推荐的3.10,除了之前众多的内核、OS补丁需要和高版本做合并和功能对齐之外,还必须和上层应用经过足够多的磨合,这可不是一朝一夕就能完成的事情。阿里的应用数量庞大,种类众多,光兼容性的验证没个1、2年的时间没人敢把核心应用放上去。因此虽然Docker能给研发和运维带来的好处,作为技术人员大家都心领神会,但是面对Docker浪潮却只能是坐观弄潮者,徒有羡鱼情。
所幸的是,这个状况在去年7月份有了改变,这事要从阿里内部的容器技术产品T4说起。T4是阿里在2011年的时候基于Linux Container(LXC)开发的容器技术基础设施。从12年到15年3年时间里用的应用越来越多,实际上已经覆盖了电商领域大部分App。相比Docker的模式和理念,T4其实更适合阿里内部的运维现状。T4是从阿里内部的资源管理和日常运维中土生土长出来的产品,在诞生的第一天就针对内部基础设施、运维工具甚至是运维习惯做了很多特别的设计。T4在LXC容器的基础上,对容器资源和各种统计的可见性做了很多卓有成效的隔离,使得在容器内部看到的资源就是分配给这个容器的资源,内部看到的负载就是这个容器的负载等等。同时在LXC之外还做了容器的磁盘空间配额限制和隔离,容器内看到的那块磁盘大小就是创建容器时分配给他的磁盘配额大小。这样在CPU、网络、内存、磁盘等资源使用和统计监控上做到了容器内和物理机上基本没有区别。原来跑在物理机,或者KVM、Xen中的应用,能够平滑无感知的迁移到T4中。当年从Xen、Kvm迁移到T4的过程中,很多应用的开发者和Owner确实不知道什么时候完成迁移的,可能在某次常规的应用发布中,后台工具系统已经自动做完迁移了。甚至直到去年在和一个应用研发的沟通中,他坚信自己的应用是跑在KVM中的,我们到后台查了一下,其实已经在T4上了。
于是我们从去年6月份开始对Docker和T4都做了一些修改整合后,将两者融合为了一个产品,相当于既让T4具备了Docker的镜像能力,又让Docker具备了T4对内部运维体系的友好性,并且能够运行在内部的AliOS5u7和2.6.32内核上。这个产品在内部称为AliDocker,在去年8月份推出了第一个雏形版本。另外这个版本还解决了Docker当时很严重的一个问题,就是Daemon退出其上所有的容器都会退出,这一点在真正生产环境大规模部署时是无法接受的。Docker官方直到1.10版本才开始部分解决这个问题。我们当时的Docker版本从1.5一直跟进到后来大规模部署的1.9版本,通过Docker的Daemon管控进程和容器的解耦,Daemon重启后对之前运行容器的自动识别和重新接管,解决了这个问。这样Docker在阿里内部大规模应用就有了可能。
从这个版本发布到能够替换T4大规模部署还走了很长的路,首先T4和Docker毕竟是两个不同的产品,除了大家耳熟能详的容器机制之外,其实还有非常多的细节和特性。为了让应用在迁移中无感知,AliDocker对原先T4容器的细节功能做了全面的兼容,同时对上层的运维系统做了大量改造,使其支持Docker场景下的发布和运维模式,从Docker镜像构建到分发启停、扩容迁移都做了完备的工具和流程支持。其次在T4到AliDocker切换的过程中,我们做了2者混跑的支持,也就是说同一台物理机上可以同时跑原来的T4容器和新的AliDocker容器,互不干扰并且能统一运维。因为众多应用的实例是交错部署在众多物理机上,同一个物理机上往往有十几个不同应用的实例混跑。这种兼容机制就保证了不同应用可以按各自的节奏逐步完成Docker化,而不需要在某个时间和空间做一刀切,避免了大规模升级Docker的过程中不必要的应用腾挪和迁移。然后在我们将AliDocker和T4功能完全对齐,从实例级别到应用级别做了足够的灰度后,推送了一个开关,使得从那一刻开始创建新T4实例时会自动创建为AliDocker实例,从而完成了增量实例的切换。对于存量的T4实例,我们选择了一个完整的深圳交易单元,分批次做了批量切换,在切换期间如果发生大的问题,可以把深圳单元的流量全部切换到上海。这一保障要得益于阿里的异地多活灾备架构,对于这类底层基础设施的升级能够提供理想的兜底方案,使我们敢于放开手脚去做,而又能有效的控制风险。所幸在整个升级洗牌的过程中,没有动用到这个大杀器的功能,虽然出了一些小问题但都能及时修复,影响不大,也让我们的系统更加健壮,让各个部门的人对交易核心流量切换到AliDocker这件事情更有信心。
但是仅仅将运行容器从T4切换到Docker其实对我们带来的改变并不大。Docker真正的核心价值在于镜像机制,以及镜像机制带来的研发与运维模式的变革。应用镜像化大致来说有2种方式,一种是比较保守的方式,镜像中只包含基础环境,容器起来后,再登录到容器中部署应用包。这种方式和原先的T4类似,镜像化上不够彻底。为了彻底根治环境不一致的沉疴,从机制上杜绝非标准变更,让每个环境改变都沉淀下来,我们采取了另一种更激进的方式:镜像中除了包含基础环境外,还包含应用程序。应用新版本发布时,直接销毁原有的容器,用新版本的镜像启动新的容器提供服务。这样任何在上一个容器中做的小动作都会随着下一次发布全部清洗掉,如果想要保留下来,就必须固化到应用的Dockerfile中。一个应用镜像就代表了应用的所有依赖环境和当前版本。任何时间任何地点将应用最新镜像拉起,都能得到和线上其他实例一致的服务和行为。我们在推广AliDocker的过程中,一直和所有的应用方强调这个理念,也获得了大家的认同。
于是在今年5月底,我们成立了专门的项目组,快速推进这个事情,目标是把双十一流量覆盖的核心应用全部升级为镜像化模式的Docker应用。由于我们做到了运行态与T4保持一致,改造过程比较顺利,但实际上线中也遇到了许许多多即在意料之外又在情理之中的问题。这些问题会在毕玄的《在线ATF-阿里超大规模Docker化之路》中做详细分享,您将可以从中了解到阿里集团从AliDocker引擎到上层运维部署体系经历了怎样的大改造,如何在电商交易级别的大规模应用中来表现。