论坛5 | We. Developers. 王渊命 「Cloud Native Application」有哪些可能?



  • 时间: 2016年7月28日
    发言人: 王渊命|青云 QingCloud 容器平台负责人
    主题: 「Cloud Native Application」有哪些可能?


    下面是由我带给大家的分享,我的主题是Cloud Native Application,这个概念有人了解过吗?它本身相对的是传统应用。互联网喜欢造新词,有人说你造出来一个新词,别人是传统的,你的是新的,让大家都往你的新方向来迁移,但是这个是不是炒概念的词汇,跟大家探讨一下。

    0_1470725070311_upload-64117e4d-175d-46a9-9131-4515e2b4f88f

    这张图很多人见过很多次,最早是OpenStack提出来的,后来Bell分享的时候也用这个图。以后凡是涉及到融合、应用的分享都喜欢拿这张图来说,因为这个也说明了一个什么问题呢?这个图表达的意思是我们做系统开发人员的理想,但是这个理想到现在还没有实现。

    理想是什么呢?现在或者以前我们对待服务,就像对待宠物一样,给它起名字,要精心呵护它。万一挂了一台,我们还会心惊胆战。我们能不能像养牲畜一样对待它,养一大群我可能不关心它。如果挂了我再补一个就可以了,这是我们理想的目标,我们不用说半夜听到报警心惊胆战的。

    为什么会有这样的需求或者目标呢?我们可以简单看一下互联网应用演进的模式。最早是单机用户,没有互联网的只有大家都是单机,有互联网了我开一个端口把单机入口暴露出来,多个人共享这台机器。后来服务器发现容量不够了,撑不了那么多用户怎么办呢?我们有了分布式的集群。

    0_1470725086795_upload-e8c383d8-9c2c-4adf-9602-17d453529867

    这个是简单的互联网应用的模型示意图,这个分布式的概念其实是广义的分布式,我们用软件的方式把很多节点合在一起作为一个大的系统来解决容量上限限制的问题和系统分布式。

    0_1470725096654_upload-5c4abe4b-0929-4060-b366-cf1d5cfa144c

    这个是互联网的,因为互联网最早面临用户规模瓶颈的问题。最早演化出来,现在很多传统行业逐渐从以前的模式向分布式的模式演进。

    0_1470725104903_upload-2016f745-649c-40fa-b16b-e095157bc2e1

    我们看一下这样一个系统,它把各层分开,各层进行伸缩。它遇到的问题和需求,我们如果要向牲畜一样对待这个系统。然后我们首先要面临什么样的问题,你怎么样弹性伸缩。用户越来越多,我要越来越多的服务器,你最好自动的增加服务器,用户多了自动的进行增加,用户量降低你要自动的减少,不用每次人工去照顾它。

    另外一个是高可用,前面的架构图里面,我们引入了LoadBalance,还有MySQL的HA,都是为了解决高可用的问题。

    然后是故障恢复,前面是分布式数据库的刘奇也提到了,如果出了故障,我们不仅仅是挂一台不影响服务。能不能自动再恢复起来,在其他机器上进行恢复,这是高可用的需求。如果要实现我们这个目标,把服务当牲畜一样对待,我们首先要满足这三个需求。

    0_1470725123919_upload-7d8db7c7-b107-49ec-9b9d-41ec28939a32

    这三个需求的第一步需要更多的机器,因为我们是分布式系统,就是把很多机器弄在一起,因为系统在生长,你需要更多的机器。更多的机器我们还需要更便捷的方式购买计算和存储资源,如果服务器扛不住了,我们要增加服务器了,这个流程走下来可能一个多月过去了,你的服务可能已经挂了,我们需要更便捷的方式。

    0_1470725139309_upload-bc4f80aa-a36a-4c3d-83e6-d8fc37c04659

    这个时候我们的IaaS出现了,它首先接管了硬件的运维,整个机房做一个大的资源池,然后应用的开发者只需要关心我应用的程度和资源的使用量,按需增长就可以了。

    另外是提供了可编程接口,解决了刚才的问题。因为你要自动伸缩,你肯定是用程序控制,你要购买更多的服务或者创建更多的资源。同时IaaS的特性是对应用无侵入,因为IaaS的目标从私有物理机迁到云上来,它最好是做成无侵入的方便你迁过来,所以第一步提供了SDN模拟网络,SDS模拟存储。它的故障恢复的策略也是基于资源的,因为它只知道你这台虚拟机挂了,它可以迁移到另外一台主机上面,但是它不知道应用的状态,这台虚拟机在应用里面承担什么样的角色,它是不清楚的,你要做更智能的故障恢复。

    0_1470725154997_upload-2e685ec0-7afa-4b7b-9229-36f0ac295750

    我们再看一下,如果有了IaaS我们能不能达成目标。比如说我们有一台机器挂了,我们把物理机迁到另外一台机器上或者又增加一个节点,这个时候我们的数据库,我们的主库挂了,从库变成主库了。我们的应用需要感知到数据库的变化,我们是怎么样的方式感知变化的?比如说我们习惯是写到配置文件里面去,你怎么改配置文件。即便有了IaaS我们要达到我们的理想,我们还要在上面做很多工作才能达到目标。

    0_1470725166154_upload-8411ede7-b486-4cdb-a588-dfef51e3ea8b

    这回答了刚才讲的分布式系统的痛点,这个开发确实复杂,大家深有体会。一个大的系统,你想改动其中的一块,牵扯到很多方面。你又很难说把线上的系统克隆一个迷你型的系统出来就开发,这个很难。分布式系统首先要管理机器,无论是物理机或者是虚拟机。因为机器是硬件,同时要管理机器上的节点,我们相当于机器上的进程,因为这才是你应用的服务。

    再就是你要面对异构的环境,可能机器操作系统不一致,有历史遗留问题各种原因,你可能要混合部署一些服务,可能会牵扯到端口冲突这样的问题。还有因为机器很多,你的日志收集和监控,这都会变成一个比较难克服的问题。

    再就是服务之间的依赖问题,因为我们现有的方式是你依赖数据库,我对数据库没有控制力,我把这个功能委托给运维去管理,运维告诉我一个地址,我才可以访问它。如果数据库挂了,我可能得让运维人工干预,能不能让它做成自动的,这是我们的目标,你这个集群要接管所谓的依赖关系的处理。

    0_1470725185920_upload-bceb89d0-b5f0-4d28-be8a-75a82d28d28b

    所以有人说过一句名言,当前写分布式系统应用的复杂度相当于没有线程库的时候写并发程序,甚至是没有操作系统的时候写应用程序,这个人是老王。现在我跟大家表明一个观点,现在写分布式应用,第一步你先写一个简单的分布式操作系统,把硬件管理起来。要写一个进程调度器,然后在上面做应用,这是所有的分布式系统第一步要做的事情。

    0_1470725196623_upload-21c12e77-a704-4317-a7e4-5332e4910fb5

    后面我们需要一个什么东西呢?我们需要一个分布式的操作系统或者是调度系统,或者是另外一个比较热的词叫DCOS,把分布式的东西给接管了。比如说主机硬件资源,相当于单机系统CPU资源,应该由操作系统接管。接管分布式系统的调度层,我们所有的进程和服务应该跑在哪个节点上,这个节点会跑在哪个主机上,应该由调度层统一进行管理。

    它是面向应用的,刚才我们说了IaaS是面向资源的,它给予我们主机、网络、存储,但是它不关心上面的应用。而我们其实要关心应用,因为有一个单机操作系统,开发应用的时候不需要关心进程跑在哪个CPU上,这个对我们开发者是屏蔽细节的。

    0_1470725208622_upload-6936a645-c757-4532-9e69-19e0e6253cf4

    这样的话,我们应用和云的关系已经有变化了,不能像以前那样使用云了,因为第一你要依赖云提供的能力来实现我们的目标,然后让渡一部分职能给云。

    另外一个云需要更高的理解应用,比如说这个应用是无状态的,还是有状态。如果是无状态的挂了立刻重启一台,非常容易迁移和故障恢复,如果有状态的我要关心它的存储怎么处理,这是一个简单的例子。甚至你知道了应用互相之间的关系,你可以调度到相应的硬件上提高性能,这些都是可以做的,云需要理解应用,这是应用和云的变化。

    0_1470725221763_upload-94ea8ef7-cb0c-4cc9-8b97-b1c1808e2d5b

    这里有几个例子,分布式系统调度演进的例子,Yarn,这是Hadoop生态圈里面演进出来的。Hadoop要管理很多节点,后来它发现有几个,比如说Spark和Storm,每个都要资源管理写一遍。以后Spark和Storm可以不用关心资源,可以跑在Yarn上面就行了。

    后来又出来Mesos,Yarn只关注Hadoop生态圈,其他的分布式我跟多个应用共享一套资源,所以Mesos又做了抽象层,它接受了所有的资源管理,对应用进行简单的改造可以实现资源共享。

    后来Kubernetes出现了,它想做一套标准的集群定义方式,应用按照我的集群定义方式来进行部署,自动的享有分布式的优势。

    0_1470725238060_upload-92efff04-65ba-4db6-817f-655618e8b6ed

    当然现在还有很多的厂家或者是开源的系统在尝试这方面,我不举更多的例子了。我们可以对云原生应用做一个定义,让渡一部分功能给云,以实现弹性,高可用,故障恢复,降低研发运维成本的应用。

    0_1470725246543_upload-4dfd6ba0-ed85-4938-8dcf-2b99ab793a80

    具体的表现方面,我简单列了这几方面,应该还有更多的变化。

    0_1470725254700_upload-375cfc90-9fe3-48fd-b643-9e5d176afa7c

    第一是我们的DevOps变化,最近有容器或者刚才提到的Mesos对它整个影响比较大。

    现在我们面临的问题是,我们的CI和CD流程很难标准化,因为你最后要部署的服务器环境不一样,你所经过的流程也不一样。所以现在我们的CI、CD工具只能做什么呢?做一个调度系统,如果我们以后可以和CI、CD标准化,它的自动化测试和自动化部署,可以集成在在CI、CD工具的标准化。

    另外是部署习惯的变化,比如说现在我们为了资源共享,在单机上部署多个服务。如果是云原生应用的话,它带来的思路是每一个隔离单元,因为它迁移或者伸缩的时候以镜像或者容器这一层来伸缩的。

    我们以前都习惯应用代码和部署结构分离,应用由开发负责,部署可能由运维负责。但是这样的话有很多弊端,运维要深入的理解应用,你才能做好运维。所以云原生应用代码的部署结构,应该是我们代码的一部分,应用的部署结构应该是代码的一部分。你在写代码的时候应该定义清楚我们的应用应该是怎么样的部署。

    我们这个集群像森林一样,不断的往上面加东西,尤其是互联网的应用,不像是企业应用可能有私有部署,它还可能不会那么复杂。互联网应用是服务器上来之后,整个像森林,大家不断的往上面加东西,但是没有追踪,等到你需要重新部署一套环境的时候,你发现就是个灾难了,没有严格的追踪。

    0_1470725282637_upload-9cb60706-1f4b-48f5-a7ab-e2fdd7643d8a

    依赖和包管理变化,我们前面提到了依赖和现在的操作系统和编程语言相关,这是一个非常艰难的过程。如果使用过的不光是编程,你可能跟操作系统的版本冲突了或者跟其他应用版本冲突了可能要跟运维做很长时间的斗争。云原生应用以后,我们统一用镜像发布,你的应用应该跟你的依赖是一体的,比如说我们跟一个盆花和植物是一体的,你迁移的把盆搬走就可以了。

    0_1470725293089_upload-fba9e25f-bcfb-404e-8b4d-21e3b81abae4

    我们以前习惯的配置是写一大堆配置文件,如果云原生应用的话配置应该按照不同的分类和不同的方式处理,比如说集群相关的配置,你应该把它中心化了。因为你集群了无论是变化,如果中心化的话你只要修改一处就可以了,因为你的节点是不断伸缩的,你跟实例相关的配置,比如说Java启动的内存,这个东西应该是通过参数或者是镜像模板的方式。因为这样的话你可以方便的用调度工具快速的部署你的新的节点,而不是说部署节点之后再修改你的配置。

    依赖服务前面也提到了,你怎么让应用感知呢?这种应该按集群提供的依赖服务注入的方式,你不能在配置里面写死,而是给你注入的变量或者是注入的域名或者是其他的方式来实现这种自动变更。

    0_1470725305573_upload-44b99393-a0f8-4905-a201-86f23ac106a0

    日志这方面的变化,现在我们习惯在本地写本地文件,其实它的变化是阶段静态输出,因为你不需要关心日志。它本来是如果你写到文件里,它是有状态的,你的容器要跟日志对应。并且日志也不能随意丢。所以如果你是静态从控制台输出,最后日志谁来收集,最后中心化展示就可以了。

    0_1470725316730_upload-f90ec8b0-c707-4e9a-9bec-b3d74c63e685

    服务发现和依赖我们前面提到了,最好用集群的方式,它知道我们哪些节点是哪个服务的。它对应用是有感觉的。

    0_1470725326557_upload-1375a5c6-9265-465e-8f39-26ca596db26a

    另外一个是服务架构上的变化,现在习惯是一体化的架构,如果延伸的话希望是微服务的架构。一体化的架构就是所有的层写在一个大的应用里面,整个团队一起更新应用,弊端其实很明显,你很难并行做。团队变更的并行度是受限的,你的新技术的接纳成本也是很高的。比如说你要变更集中的框架或者变更其中的语言,如果用微服务的话这些都不是问题,这是微服务现在流行的原因。

    0_1470725336823_upload-63901911-15f4-41b8-bb72-f3f0b54f4743

    最后一个是自管理,自管理这个话题很大,我们前面提到了如果你用对待生命的方式对待服务,我们前面提到的东西都是自管理。这里我举的例子,就是我们以前第一行代码是C语言启动进程的方式。现在我有一个进程,我发现我处理不过来了,我启动另外一个进程一起处理。如果我们分布式的系统,现在这个节点我处理不完了,我能不能启动另外一个节点,一起来处理呢?这就是一种思路。也就是说,在这种思路下,它的集群资源应该是由程序来自管理的,程序自己对这个是有感知的。

    0_1470725348058_upload-fd2fbb75-27a6-425f-b78d-b0452f2388be

    讲到这里,如果这几个问题都解决了,现在的问题是,我们云原生应用的标准还不成立,大家都是在探索,你哪些功能可以让渡给集群来管理,哪些应该是应用自己要管理的,这是要经过很长时间的演变。单机系统它的内核应该承载哪些功能,这是大家一直在争论的,至少现在还没有一个标准,大家一直在探索。它的成熟度,无状态的服务成熟度已经没有问题了,但是有状态的存储,这个还是有点欠缺的。其他的还有生态,比如说我们前面谈的例子,数据库比如说MySQL你的数据怎么分片,这些都需要生态,比如前面提到的TiDB这样的分布式数据库的成熟跟大家一起结合才能实现这个目标。

    0_1470725358526_upload-300b1171-bc79-4688-b942-1bcb4f7db5af

    所以你说了这么多现在又不成熟,那不是白说吗?能干什么呢?我今天分享的议题,一个是以前离这个目标还很遥远,现在已经看到曙光了。所以我们架构应用的时候可以充分的考虑以后怎么适应分布式系统。

    另外一个是这些思想是可以借鉴的,尽管它不成熟,但是它的思想都是我们在应用架构中可以借鉴的。因为技术变革,技术其实是比较容易变革的,最难变革的是人的思维方式和做事习惯。另外,有的客户希望我们在上面加一个审批的功能,开发者要创建虚拟机的时候要先经过审批,然后才能通过。这样的话我们怎么自动伸缩呢?这个思维方式得改变,比如说我们写程序的时候,可能与这个有关。

    0_1470725371276_upload-0515d4f2-a0c3-4cf0-94cc-e0ccdcd1b188

    最后提一下青云QingCloud的容器策略,我们会支持主流开源的调度系统,比如说Mesos或者是Kubernetes。然后我们主要做的是让这个容器平台更方便的运行上青云平台上,因为它有很多需要IaaS支持的。最后是通过AppCenter平台支持的,我就分享到这里。


登录后回复
 

与 青云QingCloud 社区 的连接断开,我们正在尝试重连,请耐心等待