为什么需要容器化平台
目前唯品会做的是容器化平台,为什么需要这么做?主要跟唯品会目前面临的问题有关。
大家对唯品会的特卖模式,即早上10点和晚上20点的上新,应该并不陌生。从上面这张监控图中很容易看出,8点到12点这个时间段,客户的请求量非常大,之后请求量一直下降,一直持续到20点再次上新,流量才又开始增长。这里面出现两个问题:一个就是我们经常搞大促,这个量是平常8点到10点的几倍甚至几十倍,我们要支撑大量的资源来支持这个量。但是这个量没有了之后,剩下的资源我们该怎么办?大家可能会想,唯品会为什么不用公有云,这也是一个比较特别的原因就是数据安全,所以只能依赖于私有云。所以我们希望容器化能解决这个很容易出现的问题,即支撑高峰和善用低谷。
除此之外,唯品会目前还面临很多其他的问题:
整个运维思路比较简单,在部署方面基本上是单物理机,单进程模式——毕竟是要保持业务的稳定性,这是目前最大的约束。但是公司所有的物理机从机房上架、上电,网络开通等,整个流程消耗非常大;
资源利用率很低,整个体系的物理机CPU利用率平均还不到10%,在四个数据中心却有超过2万台物理机,这个量浪费非常大;
灵活性差,响应慢,我们要换一个硬盘很困难,效率很低、成本很高,这也是我们考虑容器化的一个原因。
所以现在我们需要打造下一代的管理平台,主要考虑以下几个因素:
能够分时段和分资源的方式使用,这样能够高效地利用资源;
唯品会现在是多数据中心,后面可能要考虑混合的数据中心,我们希望私有云或公有云的接入能做到快速部署、自动部署和严格隔离;
整个电商平台业务模式会因为支持多数据中心、混合数据中心变得非常复杂,不是纯粹的一个单体网站,后面涉及很多的流程和很多的模块,我们希望把它们有效地混合在一起。
当然大家很容易想到本文的主题,单就纯粹加一个Docker是否能完全解决这个问题?最大的问题不是Docker加进来就OK了,除了要用Docker引擎之外,还要考虑怎么做编排。我们需要做到把所有资源有机地编排在一起,做到弹性伸缩和灵活资源调度。
Docker容器、容器编排
现在的容器化平台是个很大的概念,那么我们要从概念模型上去看,我们到底选择什么样的平台,毕竟现在很多企业有很多不同的选择。
简言之,公有云可能是从虚拟机开始,私有云从物理机开始。如果你从物理机开始,一个物理主机拥有多个容器在跑,每个容器会含有单个应用(单进程),每台物理机会运行一组容器,每个容器管理一段IP。容器IP管理是个复杂的问题,后面会说到。
从选型上来看,我们的容器方案用的是Mesos+Marathon,如上图,这个选型的原因是什么?很多情况下大家可能会去选择Kubernetes,可以看下二者之间的对比。
因为我们是多数据中心,所以Kubernetes能不能支持还是一个疑问。另外,虽然Google做的东西比较好,但是有一个毛病,就是做到一定的程度就扔掉不管了。我们这么做选择,里面有很多特性的问题,但是现在包括Kubernetes自己在做很多类似的功能性拓展。Docker自己也在做,Swarm也是选择之一。至于选哪一种,就是萝卜青菜,各有所好了,大家自己要做好自己的业务分析。
把这几套体系做好选择是不是就够了?实际上你需要考虑的问题不单是这个,容器本身还要考虑的是数据中心的运营,如下图,要考虑的东西包括:
镜像管理和发布流程管理:要不要做权限控制和分组,整个发布流程怎么管,应用上线怎么发放,发布流程很重要;
弹性管理和监控体系:监控最大的问题是整个框架需要自己去搭建,这个是做容器化最大的一个能力考量,不像原来做物理机直接找个开源方案就搞定了;
网络管理和网络模型:网络模型是搭建方案时最大的一个问题,而不只是简单地搭一个容器使用默认的NAT模式,这样整个方案的效率和延迟性是没法接受的。后面我会讲一下唯品会的容器网络模型。
再强调一遍,整个容器化平台是一个体系,不要单纯地选择一个Docker引擎,希望大家做方案的时候一定要考虑清楚体系怎么搭建。
上图是我们目前整个体系的架构,里面我就不细讲了,从下面开始看,首先是整个物理机集群的调度,然后是容器的调度。除此外我们还要有相应的管理体系,包括我们自身还有运维等,每个模块都需要考虑到,可以做简单,也可以做复杂。
关键技术点
首先我们看下资源层的模型,也是从物理机器开始,把所有的物理资源后者云主机认为是一个池子,如下图:
在搭建整个物理资源时,每个物理资源每一台服务器会有一个IP段,作为容器的管理,我们要做好相应的网段管理,要把所有的网络规划做好。
对于物理资源,我们用PC的服务器方式做,从管理上讲,会有自己的CMDB的管理体系,根据不同的方式分不同的业务,业务分不同的主机,主机管不同的容器,这个模型比较简单,实际上我们也是这么做的。
对于整个网络,目前还是以最简单VLAN的方式做,当然也可以用很多开源的方式做,但是稳定性和可靠性是一个比较大的麻烦。
从管理上讲,大二层的网络方案有一定的风险,毕竟整个交换机管VLAN的总数是有限的,包括网络ARP包的量也比较大,但在没有达到大规模的时侯可以先不去考虑,所以我们基本上不需要任何管理系统,直接用交换机给每台主机分一个段,这里面有另外一个问题,就是整个IP的分配都是由Docker引擎去做。这种方式最大的问题是怎么去分配这个IP,你的IP段分给了Docker引擎之后,如果现在一台主机上有16个IP,但是只有5个容器,那有11个IP是浪费的,但好处是管理上会非常简单。
容器调动机制有利于Mesos+Marathon,用自己的发布系统来管理,会把所有容器的发布通过发布系统触发方式去做,剩下的就是利用Marathon把整个的容器集群调度起来。
容器的执行,基本上是依赖于整个Docker容器的方式去做,但这个Mesos最新版可以把Docker引擎去掉,我们目前还不想这样去做,我们还得用Docker引擎去帮助我们管理IP分配。
镜象机制大家都比较清楚了,我就不讲这个原理了。唯一做的不太一样的地方是我们倾向于单个镜象,单进程;我们不倾向于一个容器里有多进程,如果你有多进程,而你的主进程并不是在启动进程,那很可能在管理上会很复杂,因为其他进程死掉的时候,Marathon实际上根本不知道。这是我们当时遇到的一个坑,所以我们想了很多办法,应用全部拆成单进程的方式去做管理。
这是我们的一个物理主机的情况,实际上是说一个容器会做纯粹的单IP,单进程,因为IP走的是二层的网络,所以IP的互通在交换机里做好了,不需要做很多的网络转换。为了监控我们自己的应用,我们会在物理主机上部属很多辅助的容器。
容器存储,目前我们存储的方式还是选择本地存储,现在只是跑应用,还没有很好地跑数据或跑大数据的应用,目前只是用到本地存储,通过卷挂载的方式去使用物理机的本地存储。
资源的隔离,很多的业务体系希望不同的业务体系只跑那一类的业务,希望它们不要有冲突,你在网站上看到购物车是一个体系,物流是一个体系,另外我们希望可以支持多数据中心。这个都是通过Mesos的分组方式支持。
之前提到的监控实际上是很大的一块,所以整个容器要为整个公司去考虑你的监控体系,去监控容器的CPU、NET、IO。目前唯品会的整个网络层体系是这样的:应用层有自己的监控体系,我们把它叫作Mercury,这是我们自己做的业务层监控,Mercury是调用链的监控,业务层主要是Telescope。大家需要自己去考虑自己的方案。目前也有不少开源的选择。
唯品会的容器化管理,基本上涵盖几个大块,一个是刚才说的监控,另外就是整个弹性的伸缩,弹性伸缩这一块,我们目前用比较简单的做法,实际上是通过Jenkins的方式,固定时间把某些应用的容器的实例给缩下来或扩展上去。
这是我们自己整个容器化管理平台的一个系统的简单界面,我们把所有的机器融合在一起,当成一台主机的方式,第二张是监控所有主机,现在基本上是300台主机的量在做这样的实验,我们都是单独在做这样的监控。
镜象管理本身是一个存储管理,所以你要考虑分布式的存储、怎么让网络IO的量支撑你的容器分发。但是这个是很麻烦的地方,比较简单的做法是只做本地存储就好了,不需要搭一套完整的分布式系统。后面如果规模再大的话,可能要考虑其他模式,之后会提一下后面的方向。
整个的部署模型大概是这个样子的,Haproxy我们有两套,一套是管理端,一套是整个应用接入层,这样把体系搭出来,管理机器基本上是在20台到25台主机,管理体系基本上是走物理机的体系,只是应用跑在Docker里面。
除了整个技术体系还有一个是管理体系,包括整个流程的发布和打包,还有持续的集成,都会影响到整个开发流程,还有整个监控告警的处理、镜像的维护,举个例子,假如有一个应用要连数据库,那这个镜像谁可以拿,谁不可以拿,都是管理体系需要考虑的,还有就是整个物理资源的上线回收等。
唯品会之前遇到过的问题
简单讲一下我们遇到的一些问题,可能大家以后也会遇到同样的问题。
最大的坑,是默认的安装完之后,会造成机器访问时,内存访问到硬盘上,这样整个体系的系统会非常差,这是我们必调的一个,也是第一个坑。
整个Docker集群是一个Vlan的模式,所以我们会把IP段分给Docker引擎,要在启动参数时把这个做出来,要把整个网络上的IP分配规划好。另外就是如果你往容器化走,就建议大家不要走到Linux 6系列,尽可能走到7系列,7系列选择Overlay的容器存储方式,这也是整个6系列带来的一些问题,所以你可能还要去考虑整个存储引擎的日志模式,要把Docker引擎自身的日志,包括容器化日志的输出,用Linux机器本身的Journal方式去做,所以启动参数是有很大讲究的。另外我们现在的监控体系,后续的日志处理,可能会遇到整个容器的时间跟主机时间实际上在不同的地方,就需要把时区做一个调整。还有整个安装和维护,这里也有一些技巧。
我们的日志文件,是把主机的盘挂给容器,但是这样又会冲突,所以每个容器写盘的时候,会挂容器IP做子目录去写盘。
其实我们前面讲那么多,是想把目前的体系尽可能简单化地去做生产试运行,后续可能会考虑得更加复杂,主要考虑三个:
一个是网络,考虑网络整个模型的话,容器到了一定的量,你的网络模型可能就会重新搭建,目前可选择的有Contiv和Calico。
第二个方式是考虑整个存储,你要考虑存储怎么走,实际上我们目前考虑的分布式存储是Ceph的方式。
第三块是整个的Registry管理,这个我们可能会考虑VMware harbor,之前跟他们开发团队也有过沟通,而且他们现在的版本也更新比较快。
本文分享了目前Docker容器化数据中心的概念和模型,里面的每一小块都是要花很大精力去做的。大家在选择时一定要慎重,一定要根据自己的情况选择适合自己的,因为走的是各自不同的技术路线,各自的要求是不一样的。