通过本文您将了解到:
-
Knative 是如何让普通的应用具备 Serverless 能力的?为什么说 Knative 是云原生的应用 Serverless 编排引擎?Knative 为什么是由 Tekton 、Eventing 和 Serving 三个模块组成,以及这三个模块的协作方式。本文共有四部分内容:首先咱们一起来看一下云的核心驱动力是什么,接着从这个核心驱动力出发看一下云原生应用是什么样子。然后咱们再一起来看看 Knative 到底给应用的云原生化带来了什么价值,最后咱们通过一个 Demo 亲身感受一下 Knative 带来的这些能力。云的核心驱动力在讨论云原生之前我们先来思考一下:为什么企业要上云、为什么技术人员要学习面向云的编程思维以及咱们应该怎么看待云这件事儿。咱们先来剖析一下发生这些事情的核心驱动力,然后通过这个核心驱动力出发看看整个云原生技术栈是什么样子。社会分工
我们先从一顿火锅谈起,一顿火锅虽然很简单,但会涉及到非常多的东西,比如各种蔬菜、牛羊肉等。细想一下,所有的这些东西我们都经常食用,但是其中有哪些东西是我们自己亲手种植或养殖的呢?事实上都没有,我们每天都是坐在办公室,下班的路上到市场或超市买到这些东西,不知道也并不关心这些东西的具体生产过程。我小时候在内蒙的农村长大,大家都知道,内蒙很大。村里每户人家都有一个大园子,夏天的时候家家户户都会在园子里种植各种蔬菜,如西红柿、黄瓜、茄子、辣椒等;但到了冬天,由于天气很冷,根本见不到新鲜的蔬菜,大家吃的都是咸菜、酸菜,或者是秋天晾晒的一些干菜。我们可以发现:一个地域非常容易受到季节的影响,虽然夏天可以种植各种蔬菜,但是到了冬天就什么都没有了。但是现在就不同了,全国各地随处都能非常容易地买到新鲜蔬菜,这其实是 社会分工的结果、是不同地域、不同角间通过市场相互协作的成果。现在因为有专业的人在做这些事情,所以我们大多数人都无需劳心蔬菜是怎么种植的。而我们工程师所做的和计算机打交道的事情也能通过其他的渠道反过来帮助那些种菜的人。分工提高效率,这是现代经济学之父亚当斯密 200 多年前在他的经典著作《国富论》中的开篇观点。其实现代社会的运行机制也印证了该理论;我认为它也是企业拥抱云计算的根本原因。因为大家需要把一些非业务核心的部分“承包”给专业的人士去完成,那些和自己的业务强相关的部分才是企业的核心竞争力。应用上云
接着咱们再来看看一个应用都是由哪些部分构成的。应用要提供服务首先要有计算、存储和网络资源才能把进程跑起来。当然这些也仅仅是把进程跑起来,如果要承接具体的业务还需要依赖数据库等服务;如果要做分布式架构还需要做微服务拆分,这时候就需要缓存、注册中心、消息各种中间件的服务。以上的情况都是程序已经存在,如何把程序跑起来承接业务的部分。还有一部分是如何把代码变成可启动的程序,这就是 CICD 部分了。从代码到应用启动再到应用依赖的周边系统支撑都说完了,还有一部分就是日常运维相关的:比如日志收集、分析比如监控和告警虽然我们本来只是想要写一个应用,来为业务提供服务。但是应用周边的这些支撑系统比这个应用自身的消耗还要高上很多。这其实不是我们期望的结果,让业务团队更多的聚焦在业务逻辑本身,而不是周边的这些系统上,这才是我们希望看到的。
实际上有一定规模的公司,内部的组织架构基本也都是由一个基础平台团队和多个业务团队构成的,基础平台团队负责提供这些应用需要的公共能力支撑,业务团队更聚焦在业务上,直接使用基础平台团队的能力即可。这其实就是社会分工在 IT 组织中的体现, 专业的人做专业的事儿,分工提升效率。现在我们再回顾一下刚才吃火锅的例子。如果时间倒退 20 年,回到北方的冬天,我们想要吃一顿有肉、有蔬菜、还有金针菇的火锅,根本就不可能,但是现在,我们可以随时随地买到这些东西,而所有这些都是专业的人士生产的,我们无法自给自足这么丰富的资源。那么对于一家企业而言,也是一样的。虽然每个企业都有自己的基础平台团队,但是由于规模或者资金投入等原因,不可能提供像云这么丰富的平台支撑。如果有,那一定也是一个云厂商。所以对于业务来说,把所有和应用相关的周边系统都使用云的初始设施搭建,把这些周边系统承包给云厂商才是高效率的做法。我理解为这就是云原生出现的背景。分工提高效率这是大家使用云的根本动力。云原生理念是在各大企业上云的过程中逐渐形成和完善的。这套理念是协调所有参与方对服务上云逐渐形成的统一标准,这个统一的标准可以很好地帮助企业上云、帮助云厂商释放云的能力。从云的客户角度来讲,这个统一标准就是避免云厂商锁定。比如 Kubernetes 就是一个非常好的统一共识,因为所有云平台都支持 Kubernetes。
那么这个标准的价值是什么呢?为什么云厂商和上云的企业都积极参与这个标准的“制定”呢?这其实是一个互利互惠的结果。在具体谈论这个标准的作用之前,我们先来聊聊两种资源分配模式的差别。排队(先到先得)这部分咱们以就医为例进行说明。去医院看病需要提前挂号,医生的号源这是一种先到先得的资源分式。特别是在北上广这些大城市,好医生的号源更是一号难求。如果想保证一定要拿到某个医生的就诊号,就要保证比别人都更早地到医院排队,提前排队可以优先拿到就诊号。我们现在来分析一下,提前排队的人所付出的努力都有什么价值。对于排队的当事人:当事人付出的努力对于自己是有意义的,自己拿到了就诊号,得到了回报;对于其他的排队者而言,是没有任何好处的。早来的人拿到了就诊号,这就给别的竞争号源的人发出了一个信号——来的越早就越有可能得到号源。这有可能引发更多人更早的前来排队,这是一个恶性循环;对于医生来说,没有任何意义,谁来看病都是一样,谁得到这个号对医生来说差别不大。很多时候甚至患者要求加号,但医生其实是不愿意的,因为每增加一个号源就意味着医生要付出一点儿休息的时间。对于医生而言,多付出的休息时间是不能换来更多报酬的,因为这是一个先到先得的排队秩序规则,每一个号源的价格都是一样的。有没有发现在排队的过程中所做出的付出只对排队的当事人是有意义的,对于医生以及其他排队者都没有任何意义,甚至会带来恶性竞争,造成社会资源的巨大浪费。在排队的过程中,大量的资源都白白地流失,没有给社会带来任何价值。市场经济这部分我们以购买云服务器 ECS 为例进行说明。假设目前阿里云的 ECS 是性价比最高的,大家上云都优先选择使用阿里云的 ECS,那么如果出现供不应求的情况就可能会导致 ECS 价格上涨,而价格上涨就会导致更多的云厂商供应 ECS ,最终导致价格又回落下来。我们分析一下在这个过程中购买 ECS 的人和提供 ECS 的云厂商之间的关系:我们发现大量客户选购 ECS 这件事情本身对于上云的客户是有益无害的,因为大量的需求会导致云厂商做更多的供应,价格不可能持续高攀。所以 ECS 需求的竞争者之间其实不是零和博弈,而是一个相互合作的关系。大家一起把饼做大,就让整个供应链更稳定、便宜。就好比我买苹果手机,你也买苹果手机,但是咱俩不是竞争关系,而且买的人越多,苹果手机的质量就会越来越好;大量的 ECS 需求会促使 ECS 技术的成熟。对于 ECS 的提供者云厂商而言,越多的人购买自己的服务就越好,所有的客户和云厂商之间都是相互促进的关系。市场经济这种基于价格的自由交易能够非常高效地促进大家的合作,任何一方的努力对于其他的参与者而言都是有价值的。和医院排队中先到的人付出的努力只对自己产生价值相比较,市场经济的自由交易方式中,每一方的付出都让整个系统得到了优化,这是社会资源合理利用、合理分配的一种非常好的方式。
是不是感觉扯远了,这和云计算有什么关系?我们继续来剖析一下市场经济,就可以看到和云计算的密切关系了。我们先来看一下这个场景:如果云厂商 A 提供的服务性价比很高,但是有一天云厂商 B 提供了性价比更高的服务,客户会不会立即把服务迁移到云厂商 B 上去?答案是客户想要迁移,但是比较难迁移。因为每一个云厂商提供的服务标准都不太一样,服务迁移的过程需要适配大量差异化的底层基础设施,这给迁移带来了巨大的成本,甚至抵消了云厂商 B 提供的高性价比,所以平常比较少见到这种迁移。前面咱们分析了市场经济的资源分式是非常有利于社会各方面资源进行最优配置的,可是如果云客户不能在云厂商之间低成本的流动,其实就很难选择性价比高的云厂商。所以从有效配置社会资源这个角度来分析,现在 迫切需要一个能够让客户在不同云厂商之间低成本“流动”的体系,而这就是云原生的意义所在。如果把客户要在云上托管的应用比喻成水的话,那么云服务的价格就是海拔的高度。哪里海拔低,水就很自然的流到哪里去。无限降低迁移的成本,对于客户和云厂商来说都是非常有价值的一件事情。 云原生旨在以标准化云服务的提供方式衔接云厂商和客户。这种方式对于客户而言降低了上云和跨云迁移的成本,让客户始终保有和云厂商议价的能力;对云厂商而言,因为客户跨云迁移的成本低,所以只要能提供性价比更高的云服务,就能很容易的聚集大量用户。云原生是在不断促进整个系统的良性循环:既能让客户始终保有选择的能力,又能让优秀的云厂商快速服务更多的客户。 如果客户的业务服务能像水一样低成本在不同云厂商之间流通,那么云厂商提供的服务就能像货币一样在客户之间流通。这是一个多赢的局面。云原生应用说完云原生这个理念,我们来看一下云原生应用,以及在云原生的这个大背景下,如何看待传统的应用架构?云上基础设施
无论是云上的应用,还是云下的应用,其实依赖的核心要素都没有变,只是这些核心要素的提供形式发生了变化。如上图所示,共有 7 个核心要素。这 7 个要素中日常运维这一块其实不是强依赖的,虽然它对业务的稳定性影响极大,但是这并不是业务跑起来的核心链路,没有这些业务也能跑,而其它的几块都是核心链路。那么我们就来看一下在云原生架构下,这些核心链路的要素都处于什么位置?然后剖析一下云原生应用的基本范式。云原生技术栈
我们先来看看最右边的中间件这一块,里面有数据库、Redis 以及消息中间件组件。而这一块其实是应用代码里面直接调用的,并且这里包含的所有能力都有标准的协议,比如无论是使用 SQL Server 还是使用 MySQL,我们程序里都可以使用 SQL 规范进行操作。这部分其实早就被标准化了。如图所示,计算、存储和网络这三个核心要素已经被 Kubernetes 层统一了。很多云服务已经实现了计算、存储和网络资源的无服务器化,比如阿里云的 ECI 和 ASK(Aliyun Serverless Kubernetes)。那么还有两块 CICD 和应用托管没有标准化,这就是应用编排这一层需要标准化的事情。Serverless 其实不单单是无服务器,还包括应用本身的编排,这也是应用编排这一层的价值所在。云原生应用 Serverless 编排Serverless Kubernetes 已经提供了 Pod 的无服务器支持,而应用层想要用好这个能力其实还有很多事情需要处理。弹性:缩容到零突发流量灰度发布如何实现灰度发布灰度发布和弹性的关系流量管理灰度发布的时候如何在 v1 和 v2 之间动态调整流量比例流量管理和弹性是怎样一个关系当有突发流量的时候如何和弹性配合,做到突发请求不丢失我们发现虽然基础资源可以动态申请,但是应用如果要做到实时弹性、按需分配和按量付费的能力还是需要有一层编排系统来完成应用和 Kubernetes 的适配。这个适配不单单要负责弹性,还要有能力同时管理流量和灰度发布。Knative 应运而生上文中的内容就是 Knative 要解决的问题,这也是 Knative 出现的背景。接下来咱们来看看 Knative 。Knative 是什么
我们先看看官方给出的定义:“基于 Kubernetes 平台,用于构建、部署和管理现代 Serverless 工作负载”。Knative 就是基于 Kubernetes 的应用 Serverless 编排系统。实际上 Knative 包含的不单单是 Workload,它还有 Kubernetes 原生的流程编排引擎和完备的事件系统。前面提到 Kubernetes 实现了计算、存储和网络的标准化,而 Knative 目标基于 Kubernetes 提供了应用 Serverless 工作负载编排的标准化。Knative 核心模块
Knative 由三个核心模块构成:Tekton、Eventing 和 Serving。Tekton 是 Kubernetes 原生的流程编排框架,主要用于构建 CICD 系统;Eventing 主要负责事件处理功能,可以接入外部系统的事件,事件接入以后进行一系列的流程处理以及触发 Serving 消费事件;Serving 是应用运行工作负载的核心管理模块,主要负责流量调度、弹性以及灰度发布等职责。Tekton
Tekton 是一套 Kubernetes 原生的流程编排框架,主要用于构建 CICD 系统。比如从源码编译成镜像,以及对镜像里的服务进行测试、把镜像发布成应用等一系列的操作都可以基于 Tekton 完成。Tekton 里面基本的执行单元是 Task。>Task 里面可以包含多个顺序执行的 Step。一个 Task 最终就是一个 Pod,里面的每一个 Step 最终执行的时候就是一个 Container 。每提交一个 TaskRun CRD 到 Kubernetes 就会触发一次 Task 的执行;Pipeline 可以编排多个 Task,Pipeline 中的 Task 是可以设置依赖关系。Pipeline 会根据依赖关系生成一个有向无环图,然后生成的根据有向无环图并发或者串行执行一系列的 Task。每提交一个 PipelineRun CRD 就会触发 Pipeline 的一次执行;
