中文站

落地中台,如何实现快速迭代、简化运维?

近期,网易云有多场关注数字化转型创新又落地业务的直播,如果你刚好工作忙错过了,或者听完不过瘾,还需要直播笔记,那一定不能错过这个系列——我们将复盘直播内容,划好重点,干货十足!


以下是正文:

大家好,我是网易杭州研究院解决方案架构师张亮。感谢大家工作之余来收听我们的在线讲座,今天分享的主题是「使用容器来简化运维」。

一、企业IT面临的运营问题

首先,以网易为例,讲一下我们内部一些业务碰到的运维挑战。


如图是我们杭州研究院运维内部的一些统计数据。用过网易云音乐或者网易严选的朋友可能会有了解,云音乐和严选这两个业务这几年发展很快,包括之前考拉电商业务发展也是非常快的,所以他们的服务器规模每年都会增长很多,图上可以看到它的物理机从15年到16年基本是翻倍的,后面也都保持了三位数的增长,虚拟机数涨的更多。这些业务都会有很多运维去帮他们做一些底层的日常运维,包括应用的运维操作、系统运维,硬件网络的运维等。总结来说伴随业务的持续翻倍增长,运维人员不会同比例增加,所以运维团队面临的压力逐渐增加

具体来说,工单数增加了很多,那么运维的工作量也随之翻番。首先要新部署很多服务器,部署完了以后要做配置,配置完上线后日常会有很多问题出现,包括应用出问题、网络出问题、存储出问题、硬件出问题等。除了部署以外,运维大量的时间要去做一些常规的配置操作和排错。这是运维面临的挑战。

同时业务也面临很多问题,不仅网易内部业务,包括我们的客户也会存在这些问题,历史原因导致业务的很多系统是独立建设的,可能系统是外包公司做的,后面自己的开发又做了另外一个系统,每个系统之间没有太多关联性。等业务出现一些新需求时就会出现各种问题,比如做零售餐饮的业务想做外卖,需要对接微信小程序,对接支付或者银行的APP,这时就会发现,要支持这些新的需求,要做很多改造,可能需要做很长时间,要重新去开发,要花半年甚至更长的时间才能把新的应用开发出来,去支持业务的需求。这是业务面临的问题。

另外不同业务系统用的技术栈可能也不一样,因为对有些甲方来说,如果不是IT公司,不是以技术为核心的公司,没有很大的技术自研团队,很多业务系统会交给外包公司去做,但外包公司比如说给甲方公司做一个ERP系统,做一个前端的营销系统,使用的技术栈可能也不一样,交付物可能也不一样。对运维来说,很多东西不是标准化的,这个系统是一种运维方式,另外一个系统又是另外一种方式,对运维团队来说也增加了复杂度。

二、 解决这些运营问题的方法

面临这些问题,我们应该怎么去解决?其实运维自动化或者减轻运维工作量去做一些大批量的配置管理,一直都是有一些解决方案的,比如大家比较熟悉的puppet、ansible或者chef类似这种配置管理工具。在此前的物理机时代或虚拟机时代,他们其实是能解决的。

我们之前碰到了很多问题的,比如要更新一个软件可以去配置,那么只要在一个 maste节点上定一个规则,然后把定义分发下去,master所管理的那些你想要更新的节点正常情况下就会拿到新的软件,自己进行安装。这在很大程度上减轻了运维的工作,但依旧存在一些问题。

不管你想要做什么,首先必须定义好规则。比如说用puppet,必须到master节点去定义,想要这些节点是什么状态,你的规则得写好才能去做。再比如说我想更新一个软件,但是我又不想让服务中断怎么办?因为这个软件是用户一直在访问的。如果先把旧的卸载掉再去安装新的,中间就会对用户造成服务的中断。还有可能有时候我需要更新一个操作系统内核,不是只是更新一个应用,这时可能整个操作系统要重启,如果这时候有业务在这台重启机器上,一旦重启业务就会出现中断。

总结来说,这些配置管理工具可以做到在正常情况下将环境配置到一个我们期望达到的状态,但是不够那么友好和平滑。同时它还需要保持master节点和工作节点的网络连通,一旦网络出现故障,是拿不到规则的。这些软件确实帮运维做了一些事情,但还是有一些问题没有得到解决。

在运维和业务面临这么多问题的情况下,我们想提一个概念——不可变基础架构,这个概念其实早几年就有人提过了,简单来说就是我要对这个系统做更改的时候,是重新创建节点,并不对现有节点做更改,不会把1.0版本卸掉再装一个1.1版本,或者从1.0升级到1.1,然后再做一个重启。还是在原来的机器上(可能是个物理机,也可能是虚拟机)去做应用的升级,这是一个之前很常见的操作。不可变基础架构的模型是怎么样的呢?就是说旧的机器我是不动的,原来跑的是1.0版本让他继续跑着,然后我会先起一个虚拟机或者物理机(当然现在用虚拟机的很多了,包括容器也很多了),它里面跑的是1.1版本,这时我需要做的就只是把流量重新切到新的 instance b就可以了,不需要对instance a也就是原来的节点做任何的更改,可以选择让它保持一段时间,如果没有问题就把instance a销毁掉, instance b继续运行,这就是不可变基础架构。它的理念是去发现新的节点,现有节点在上线那一刻是什么样就会一直什么样,不会再对

它做一些我们以往会去做的很多运维操作。当然这并不是说整个系统就永远不变了,实际上也可以去做一些改变,比如说拷一些东西到上面,或者给它再装一些软件,这些也是可以的,只是说不可变基础架构本身的理念是这样。而且它并不是要求所有应用一定全部是无状态的应用,可以有一些有状态的应用,和不可变基础架构并不矛盾。

关于有状态应用使用不可变基础架构的情况,我们在后面也会提到。所以不可变基础架构相比传统模式发生了什么变化呢?

我们平常从写代码到测试、集成测试,最后到部署上线的一个过程中所涉及到的常用工具和工具链,整个流程走下来,需要大量的工具去串起来的。那么相比传统模式的变化是什么呢?就是说计算节点是一个可替换可丢弃的资源,而不是说一定要像以前一样去维护,去打补丁、去更新、去改端口、改防火墙策略,以前传统运维经常是这样,但是现在我们会有一些更好的方式。原来把业务或者系统代码开发好了以后,扔给你一个程序包交给运维,运维到虚拟机上去部署上线,有更新了以后按照文档去更新,以前是这样的。

现在这些工作,其实是放到了构建阶段,也就是说代码出来以后在构建为程序包或者打成一个容器镜像时,把原来那些部署、配置端口、配置权限、配置防火墙策略的事情都做掉了,是在构建阶段就做出来了,做好了镜像是什么样上线的时候就是什么样的,后面的运维不会再去做这些配置或者更新操作了。这是一个和传统运维方式不太一样的地方,还有就是做变更,以前比如说做更新其实是靠文档去做的。我们经常会发现,如果系统运维的久了,如果没有很好的做文档记录的话,你会不知道以前对这一台机器做了什么,因为做了太多的操作,可能运维也换过好几拨人,你也不知道为什么之前会有这个应用在里面,它的权限端口是这样配置的、这样开的,其实你不知道。从我们今天来说,文档永远是跟不上变化的,很可能做了一个变化,但是忘了更新文档,所以慢慢的文档和真实环境产生了一些差异。如果用不可变基础架构的方式去做的话,你的变更是可以做版本控制的。为什么呢,比如说代码仓库,你用git代码仓库,你每次发布一个新的更新就是一个新的版本,那么你的配置也可以放到git里面,这样你的代码和配置都是有版本可以去做的,到了线上可以很容易知道是哪个版本,如果要做回滚的话,应该回滚到哪一个是可用的版本,因为这些不是在文档上,而是直接在版本控制系统里面集成了功能。比如说做一些灰度发布,或者蓝绿部署、金丝雀发布,对我们来说都有方便应用的意义。

再举个例子,我们配置管理工具去做一个运维操作,几年前我们比如说当时 openSSL发现了一个漏洞,对吧?比如说业务系统有很多线上系统要打补丁,如果用的是配置管理工具,你肯定先会写一个规则,首先要去看是不是这个机器安装了openSSL,如果装了的话,看是哪个版本?如果是有问题的版本,要让他去回滚,不要用新版本。如果是它的状态已经是装过的,你也装不了新的,你就必须去指定版本,然后会发现必须是这个版本,现在去拉这个版本,那么可能你们公司的report里面是没有装这个版本的包的,可能你的report里面没有存旧版本的包,怎么办呢?因为之前升级的时候你把相关的依赖已经升级过了,所以你要回到这个版本,就需要再把原来的操作再反着做一遍。

这就是一个很实际的问题。我们刚才说了,这些配置管理工具它能解决问题,但是像这么个场景,现在要打一个补丁,对我们来说它并不是那么简单,而是比较麻烦的。这个例子是一个外国人在一个大会上讲的,当时的主题就是用docker和容器来做不可变基础架构。我觉得这个例子反映了我们配置管理工具在处理这些场景时的一些问题。

如果我们再换一种思路,用不可变基础设施这种方式的话,你会发现,可以做到原来的旧版本。比如说0.98这个版本我是保留下来的,因为刚才说了我们不会去把它升级到新版本,而且我们是有一个新的实例,它是新版本。那么如果发现新版本有漏洞的话,我们把流量切到原来的旧节点就可以了,新的版本可以销毁,或者说新版本留着线下再去修漏洞,修好了以后把它再切回来,对于我们来说非常灵活,我们不会面临刚才的问题。

总结来说,线上跑的业务系统,如果继续跑就一直存在安全风险,但是如果你把它下线去修的话就有服务中断,但如果我们用不可变基础架构这种方式的话,相对来说是比较平滑的。我们切流量它可能会有一个非常短暂的切换时的中断,可能就是秒级的,我们旧的节点就可以继续提供服务了。这个方式对一些对终端用户可见的服务来说,它的灵活性就非常高了


为什么要采用不可变基础架构?它有几个好处,一是说这个镜像基本上从开发的代码到构建,加上日常的配置,安全的配置,应用的安装也好,它都是干净的状态,不会有遗留的问题。它不会像以前的物理机或者虚拟机那样,可能这个系统已经跑了5年甚至更久,可能有好多人运维过它,这个人上来装一些东西,那个人上来装一些东西,这个人改了个权限,那个人加了个端口、加了个防火墙策略。你会发现总是从一个干净状态开始,你不会有这些问题。所以说对它做的改动越少,出错就越少,而且还有一个很重要的特点就是开发和生产环境的配置是一致的。开发出来是这样子,生产环境中上线的配置也是这样子,如果镜像把配置打进去了以后,就会是这样。

以前我们经常会有开发自己在测试环境去测的时候是好的,一到生产环境就不行的情况。经常会出现本来在开发测试环境中可能端口就开了,没有防火墙策略,到了生产环境有防火墙策略,就是不行,或者说一些安全权限的问题。因为开发拿自己的开发环境去测,生产环境比如说操作系统可能会有一些区别,安全配置、安全策略可能会有区别,这些都不一样,而且有时候开发可能直接拿root上去做一些操作,发现是好的,但是到了生产环境可能并不会给给他root的权限去跑,有些东西就有问题。如果你用不可变基础架构的话,就保证了开发和生产环境一致,就不会出现这种问题。

另外一个好处是有了版本以后,很容易的可以去回滚。只要保持了这个版本的镜像,可以回滚到之前任何一个版本,这是非常方便的。你想想,如果人工去在机器上操作,删除、卸载、加端口、给文件夹加权限,怎么回滚呢?可能今天在10台机器上做了,过个三个月,再去回想之前做了哪些操作,可能都记不起来了。所以版本的管理也是一个很重要的优点。

另外一个好处是,有了以上这些特性以后,问题可以在很早的阶段被解决。如果开发测试中出现这个问题,就能在开发测试中把它发现处理掉,而不会让配置的问题或者代码的问题到线上。应该说如果代码我已经经过了测试的话,那么代码是没问题的。其实很多时候是环境不一致或者配置导致的问题,可能运维没有按照操作手册去做,某个步骤漏掉了,这是很常见的,因为人总是有可能出错的。把发现问题的机会提前了,不会说上线了以后才有这个问题。

再有一个,因为可以使用版本管理的软件去做这些事情,所以就不用再去靠人工文档或者大脑去记录都做过什么操作。这些东西都是有版本的,你去看版本管理软件里面的那些记录,就知道这个版本对应的配置是什么样?

还有一个好处是减少了排错时间,理想状态是不需要排错了。如果一个业务正常运行的情况下,理论上在上线以后应该也是正常的,当然可能它会出现一些类似高并发的时候可能有一些性能问题或者其他问题,但这是比较少的情况,而且当你碰到这种情况,你要做的就是重庆就好,不需要再去排错。因为排错都在开发测试的阶段做掉了,这是一个非常大的不同,因为不需要再去对部署后的系统花很多的时间排错。如果它坏掉,就把它换了,比如说内存不够了,CPU不够了或者怎么样,我只是把它干掉,再去兴起一个示例就可以了。而且这时候因为采用了不可变基础架构,部署、更新可以被自动化了,不需要再靠人工去做。刚才我们说工具链就是从代码到到测试到部署上线,整个工具链都可以自动化。

代码提交新版本,如果所有测试全部通过的话,就可以发布到预发布环境,或者说可以先上线一部分到一个真的线上环境,但是只是切部分的流量比如切1%或者5%的流量过来,如果观察几天没有问题,就把所有的流量都切过来,这些工作可以靠一些自动化的脚本,或者配置软件比如外呼客去做自动化,人工就不用再去做这种例行的工作。用虚拟机或者物理机原来的可不可以做?其实也可以做。你用不可变基础架构理念那套运维方式去做的话,其实也可以做,但是容器它有一些天然的好处,相比虚拟机或者物理机来说,容器本身它具有不可变的特性。什么意思呢?就是说你一重启,你做过的所有操作都没有了,它就回到原来的样子,原来镜像是什么样就是什么样,当然这个是对无状态的容器来说的。对于有状态的容器来说,他们是可以保持状态的,但是因为容器从一开始到现在用的最多的仍然是它的无状态的,对无状态应用来说特别友好。

对于那些无状态应用来说,它本身就是具有不可变特性的,本身就是可以支持版本管理的。如果大家用过容器的话,都知道容器你拉镜像的时候,它后面有个tag标签,其实你可以通过标签版本来识别。比如说这个词是哪一个版本?应用是哪个版本,通过 tag就可以去做版本管理。比如它的打镜像的docker file,它是可以放到类似git这种版本管理软件里面进行管理的。所有的东西都可以通过版本管理,通过代码仓库去实现它的更新、配置、发布,通过结合一些其他工具链,可以做这些事情。

再一个它本身“快”,首先快速操作系统,当然主要是指Linux操作系统。那个是大的创新,比如说你在centos或者说在Ubuntu这些,基本上你在centos能跑的Ubuntu基本上也能跑。它是跨os的,跨平台,因为现在很多公有云已经是非常流行了,你某个应用比如说原来在亚马逊跑,现在要换到微软、阿里、腾讯,或者换到其他厂商。如果以前是跑在虚拟机里的,可能用了亚马逊的AWS,现在要换成阿里的或者微软的,就会有点问题,虽然通过一些工具可以去做转化,但会存在一些成本。而如果你用容器的话,是直接可以去换厂商的,对你来说基本上还是这么一个镜像,去换一个厂商、换一个平台是很容易的。

再就是它允许通过环境变量去注入很多配置项。当然也有一些其他的方法,比如像现在主流的Kubernetes中的configmap,或者可以通过分布式的配置中心模块如spring cloud config这种工具去做配置管理,就可以减少对配置管理工具的依赖,你会发现代码都是一份,但是配置是不一样的,开发测试环境的配置和生产环境配置那就是不一样的。这个也很正常,因为毕竟开发测试环境很多权限相对来说没那么严格,包括一些防火墙的策略,但是到生产环境肯定是很严格的。那么没关系,你可以把代码和配置分开,它支持让代码和配置解耦,但是仍然可以通过其他方式管理这些配置,而且在部署的时候,可以选择进入什么环境的配置,这样不需要再去用以前的方式去管理应用,不需要去做一个删除旧版本安装新版本的操作,或者去开一个防火墙,你不需要去这样做了,因为在打镜像的时候就做好了。即使打镜像时没有把这部分做进去,它仍然可以通过动态配置中心或者不同的环境变量去做,也就是说在系统上线的一瞬间启动的过程中,在部署过程中,它就拿到了应该拿到的配置,在配置正常情况下就不需要改了。如果你要改的话,就去创建新的示例再去修改配置项,最后重新把它们部署上去。

另外一个特点就是它比较轻量,比较快速。启动快,关掉也块。轻量是说容器对资源的需求是很低的,小的话可能几十兆也可以跑起来,不像一般操作系统基本上都是1G起。对于有些业务来说,可能不需要这么大的资源,它可能是需要很多个,但是每一个资源不需要那么大。所以容器有这种特性,它可以很好的支持不可变基础架构。

容器本身它也是一个工具,如果在大规模场景下,仍然要做编排。规模大了以后,肯定会碰到这种问题,选择哪个节点去部署,哪个节点状态是不是好的,在哪个节点应该起哪个容器,上面说的做流量切换,新版本升级了,谁去把流量从旧版本切到新版本?其实也有很多编排工具,现在在容器这块主流的基本上就Kubernetes了。我们可以看一下,比如说一个场景,我们的一个前端服务要去做更新,它从版本1更新到版本2,要怎么做?

我们想象一下,以前传统方式我们把版本1先卸载掉,然后升级到版本2,去装一个新的版本2,或者说升级,如果这个软件允许升级的话。但不管怎么样,中间可能会有一些中断,当然你可以说我有多个副本,可以一个升级,然后我到前面的负载均衡去先把几个屏蔽掉,然后去升级那几个。当正常升级了以后,再把它加回到负载均衡里面去升级剩下的。执行层面来说是这么一个工作,你会发现这个工作非常非常繁琐。那么如果你用了比如K8s的话,只需要一行命令,就可以把这个软件做升级了,就是底下这么一行命令,其实就是一个js文件,然后你只需要告诉它,这个版本你其他什么都不用变,只需要把镜像的版本从1改到2就可以了,它自己就会帮你把一个新版本的镜像提起来,一个容器提起来,然后把流量切到新的版本上,再把旧的版本干掉。你可以控制整个过程中可用的副本数,最大不可用的副本数是多少?以及可行度。比如说只有等版本2正常了以后再把流量切到版本2,再开始去删除版本1,类似这种策略是可以去控制的。所以你会发现编排工具帮你做了很多原来需要手工去做的事情。你会发现工作量比之前少了很多,就是这么一个更新应用的场景。


而像自我修复、弹性伸缩的场景,如果你的基础设施使用容器以后,遇到像电商促销、秒杀的场景,需要去扩节点,那么容器就可以去配置弹性这种策略,比如说当 CPU到了多少,内存到了多少,占用率到多少,或者说新建连接数到了多少以后就自动去扩,比如说扩10个节点或者扩20个节点,就不需要人工盯着监控平台去看数据再去决定了。它就是自动化的,节点负载高了以后自动去扩出来一部分;如果节点继续高,负载继续高,继续再扩节点。

还有比如自修复,原本有三个节点,不同节点是不同的服务,突然中间的物理机出问题了,平常的情况下,b和c这两个服务就不可用了。但是如果自修复的话,编排工具比如说像Kubernetes,它就知道 b和c两个服务的容器挂掉了,要在其他可用的节点去把这两个服务提起来,你会发现很快。这个节点一旦到了,它很快就在第1和第3个节点把这两个服务提起来了,那么这个服务又能正常了,它有自修复的能力。比如凌晨2:30有一台服务器宕了,如果没有24小时值班的话,运维根本不知道发生这个事情,他可能第2天收到一个短信或者邮件的告警说凌晨2:30有个机器宕了,但是他上去看,会发现业务它是好的,它自己就修复了,它可能短暂的在服务器中的那么几秒钟时间内,它会有一些短暂的中断,但是非常短。因为容器它比较轻量的,启动是秒级的,非常快。所以容器会有这些特性,很大程度上减轻了运维的压力。

三、 容器带来了哪些问题

但是你如果说容器这么好,它是不是全都是优点,没有缺点,其实也不是。因为我们说在IT界没有任何一个工具,可以解决所有的技术问题不带来任何的副作用或者没有任何缺点,这是没有的,不存在的。只能说对于当下的问题它解决了,到了什么程度,解决得多好。我们举一些使用容器带来的问题,或者说可能它在一些地方不如原来使用传统配置管理工具的情况,比如说做一些小的修改,比如说有个外围应用,你需要修改一行它的css内容,可能就是线上一个网页改一段文字,以前就是直接上去把页面那一行改掉,然后验证一下,没啥问题直接就发布,可能一两分钟这个操作就完成了。但是如果要用容器的话,首先要去修改验证,之后要重新打这个镜像,因为它是线上的节点,不可变基础架构,所以要新创建一个节点,把镜像打包,然后把节点建出来,接着你可以通过编排工具帮你自动去切,为了保险起见也可以去切,总之这个过程一般来说比上面说的传统方式要耗时。可能时间上是个10分钟这个级别,然后过一段时间再把旧的节点销毁,你会发现设计流程确实比传统的方式要多,而且要麻烦。涉及到一些小的修改,只要已经发布了,哪怕改个字母、改个字,流程也要重新走一遍。从这个角度来说,它是比较麻烦的。


还有之前说到的容器天生对无状态的应用特别友好,但是对有状态的应用,它其实一开始支持不是那么好的,他有支持。我们知道容器它是statefulset,是支持有状态的容器的。以前想把有状态应用容器化,我们怎么办?比如说有一些本来是web的应用,我要保存session对吧?是放到web系统上,或者在负载均衡上去配置一些session粘连,让它保证同一个用户,每次访问在一个session阶段内都能访问到同一个容器上,可以使用这种办法。当然还有一些问题,比如说要改配置文件,去改的话,一重启又不见了,类似这种。还有日志,如果有时候想去抓一些日志,当然现在这些都有办法。随着容器用的比较多,比如说日志可以通过很多工具像 logstash、fluentd等去把它拉出来,然后传往比如说后台可以有一个elastic search,你就可以用到elastic search里面去,然后你可以前端特别去做一个日志中心,配置文件可以用spring cloud config server或者说阿波罗这种动态配置的工具去做管理。

那么对于数据库,应用里面有像mysql或者mango、ddb这些有状态的数据库,也想容器怎么办?一个是可以直接用,如果你是公有云的话,可以直接用云厂商提供的一些服务。另外因为容器是支持持久化存储的,可以外接一些存储,比如说快存储或者文件存储系统,可以把这些有状态的文件放到外部存储厂,当然现在原生的或者说相对来说更方便的一种方式Kubernetes operator,会比前面几种办法要新一些。有了Kubernetes operator来说以后,你去管理Mexico、mango、ddb这些有状态的应用的话,会发现跟无状态应用非常像,因为困难的那部分由 operator做掉了。对运维来说,你不需要是一个dba,你不需要非常懂Mexico,你才能去布一个容器化的Mexico,有了operator你就不需要了,因为这部分的复杂度交给operator去做了。所以大家如果想去把一些有状态的业务容器化的话,可以多关注一下 operator这个能力。它是一个概念,它不是一个具体的,就是你 mysql有mysql的operato, mongodb的operator,不同的有状态的业务有它自己的operator,他们的逻辑是不一样的。它做切换比如说一个节点挂了,它去跟谁同步、选主的过程,这些都不一样,所以说要去找对应的operator。

还有容器用的多了以后,它仍然会碰到很多问题,其实任何一个IT技术都会是这样,刚开始用的时候,规模小的时候可能很好,等规模大了以后会发现有些性能问题是小规模不会碰到的。比如分发,拉镜像的时候,这么多节点去到镜像仓库挖掘镜像,当节点数多的时候,镜像仓库就会是一个瓶颈。如果你可以横向扩展这项仓库,这是可以的。但是你后端存储是不是也会成为一个瓶颈?而且你说我去横向,不是说分布式存储都可以横向扩了吗?没错,但是拉镜像的场景和平常普通分布式存储的场景不太一样,只是同一部分文件去读,而不是说可能数据是在不同的节点上去写,我就是那个文件,你虽然你的节点扩了,但是我要拉这个文件,还是没有从根本上解决这个问题。怎么解决我们后面会说。

四、 容器在网易的实践

刚才说不可变基础设施其实有很多好处,但是它是有前提的,不是说现在想做一个不可变基础设施马上就做了。首先你需要有自动化的的工具去做,比如说编排调度、服务注册与发现、配置、管理、创建、销毁节点的能力,然后流程也要去适配,而且组织上来说开发和运维怎么分工,这些都需要去做一些调整来适应变化。因为这些方式的变化虽然是开源,或者说有很多好用的工具和商业化的产品,但是你会发现拼接各种工具也是很大的工作量,并不是每个工具天然就和另一个工具能很好的集成。


怎么解决以上的问题?对我们来说有一个容器云平台,公有云有一个容器云平台,私有化也有一个容器平台,它里面就把一些不可变基础设施所需要的前提能力放到了我们的容器平台上。比如说最基本的这些容器的能力,Kubernetes这种编排调度的能力,其他比如说流水线、代码仓库、测试平台这种集成的能力,包括和进项仓库这些集成能力,是不是可以部署到其他的标准化集群里面,比如说部署到AWS或者阿里云,或者说VMware或者OpenStack,在不同的平台都可以部署,它是可以和当前的很多基础架构的平台去做集成的,包括一些工具链,同时支持不同的网络方案。所以对我们内部一些需要用到容器的业务来说,就会去采用容器平台去承载它的业务。


那么我们做了哪些事情呢?一个适合我们的公有云的IaaS,适合底层的IaaS去做了很多深度的融合。它不仅仅是把一个容器跑到一个虚拟机上就完了,而是在网络层做了很多融合,它的容器和虚拟机,它们两个是在同一个网络平面,它不是一个嵌套的网络平台,所以容器到物理机它只有一跳,不是两跳。中间做了很多性能的优化,而且在规模上开源社区的规模是有限的,它可能几千个节点,但是因为我们自己有很大的电商业务,规模非常大,所以我们自己是可以支持3万以上的规模。所以我们是做了一些深度的定制化,这是我们公有云的容器平台。


我们其实是对开源的Kubernetes做了一些修改,以适应我们自己的 IaaS平台和我们业务的一些需求,而且规模大了以后会有瓶颈,进项仓库的瓶颈,存储的瓶颈,其实容器有这么几个组成,但是总的来说这几个都是文件,里面包含了不同的内容,那么文件的话相当于一个下载的过程,所以怎么去加速镜像的拉取?我们会有这些一些常用的方法,比如说去减少这些进项的层数,删除一些不必要的文件,或者base image,去大家都尽量相同,这样子就不用每次拉 base image了。包括一些多节点构建或者使用缓存这种方式,都是一些常用的方法。我们使用的是开源的harbor,另外做镜像分发的话,我们也是用了开源的叫Kraken的一个点对点的P2P的这种分发的工具,这样它就可以去做到。如果大家之前用过 BT下载的话,就很容易能理解。 

P2P的这种下载方式就是说一个节点一旦下载了,一部分文件,它可以成为一个下载源供别人去下载。多了以后大家成了互相的下载网络,所以都不需要去讨论一个中心的镜像仓库去做下载了,这就是最基本的原理。那么我们的后端存储使用对象存储,这样他能做大量的大规模的横向扩展,支持海量的镜像存在上面,但是性能不会下降太多,因为结合了 P2P的下载方式。


再有一个就是说我们的容器管理平台和开源平台不一样的地方在于,我们内部是有很多业务的。如果大家用过开源的Kubernetes,你会发现它其实是没有多租户概念的,它有namespace,但是没有租户的概念。它默认你在一个机群里面,你必须通过网络策略去做一些控制才行,那么我们其实给它做了一个租户的概念,这样我们多个业务可以做到互相隔离,包括我们的客户来说也是一样的,一个公司、一个集团有多个业务或者多个部门,他们想去用这个平台的话,可以比较方便的去用自己的租户做管理,做资源管理也好,做权限管理也好,它可以去控制这些东西,但是如果你用开源的,相对来说就没有原生支持这个能力。


我们内部使用容器时做了一些改进,可能有一些是我们自己内部的需求,另外因为我们的公有云的容器平台和私有化的容器平台也是对外给客户提供的,客户也提了很多要求,我们也做了很多改进。

以上就是我今天想给大家讲的所有内容。谢谢大家!

来源:网易云