于是,在今年春节返乡途中的高铁上,我对跟朋友解释的内容做了一些丰富,写下此篇文章,尽可能用通俗易懂(但肯定不那么全面和准确)的方式,基于自己的理解,用自己的思路,来试图回答关于云原生的三个哲学之问:“云原生是谁?”、“云原生从哪里来?”、“云原生要到哪里去?”。
“云”就像现实中的“城市”。城市的居民是市民,而云中的居民是应用。
A城市原生 | 云原生 | |
---|---|---|
状态/手段 | 生在城市A,长在城市A | 生在云上,长在云上 |
针对的对象 | 市民(people) | 应用(application) |
结果/目的 | 具备城市A的市民的一些普遍的特性,比如谈吐上...,行为上...,思维方式上...,饮食方式上....,生活方式上...等等 | 更简单、更敏捷、更弹性、更新频率更快、上线更快,能更快递满足业务的需求 |
天生*原生 | 出生在城市A,从小就是城市A市民的生活、行为、饮食、生活和思考方式等 | 生长在云上,尽量使用云托管服务,通过架构设计等方式,实现上述结果/目的 |
迁移 - lift and shift | 搬家到城市A,但还是按照原来的方式生活、做事和思考。即使十年八年过去了,还是和本地人不一样。 | 非云原生应用直接lift and shift 到云上,不改造,结果就是没法云原生化,也就没法拥有云原生的结果、实现相应的目的。 |
迁移 - 云原生改造 | 把家搬到城市A,然后按照城市A市民的方式生活、做事和思考 | 把应用搬上云,按照云原生应用的形式进行改造,然后运行在云上。 |
笔者认为云原生的对象指的是应用。那么应用怎么定义呢?应用可以分为狭义和广义的。狭义的应用是用户在云上运行的系统,而广义的应用,是运行在云基础设施之上的所有软件,包括云服务提供商提供的云服务和用户的应用。
所以,我们经常听说,云原生数据库、云原生大数据服务之类的,很多是云服务器提供商提供的,也有不少是第三方提供的。
云原生应用最大的特点就是“快”:开发快、上线快、更新快、伸缩快、速度快,从而使得业务能更快地满足市场和用户的快速变化的需求。
笔者试着给云原生应用下个定义:一种运行在云上,充分利用云托管服务和一些相关技术,如当下的容器、Kubernetes、微服务、Devops等,来实现全面“快速”(开发快、上线快、更新快、伸缩快、速度快)的现代应用,以支撑更快、更敏捷、体验更好的业务。
前面说的是云原生的对象及其特性,那么如何实现云原生应用的这些特性呢?实际上,不同时代有不同的实现方式。
Cloud Native(云原生)这个概念首次出现在 2010年5月 Paul Fremantle 撰写的一篇博文中。他使用 Cloud Native 这个词表达一种架构,这种架构可以描述应用程序和中间件在云环境中的良好运行状态。云计算(Cloud)通常认为发端于AWS正式发布的2007年。很显然,云计算比云原生出现得早,但相距时间并不长(2年多、快3年的样子)。
所以,理论上来讲,自从云计算出现后,云原生的概念就自然而然地出现了。只不过,在2007到2010年没有人提出cloud native这个词。个人认为,云原生这个概念会随着云计算的存在而一直存在,就像城市原生会随着城市存在而一直存在一样。
早期的云原生案例,比如Netflix,作为最早全部采用公有云服务的先驱公司之一,充分利用AWS云托管服务,以及虚拟机的弹性伸缩能力,再对应用架构进行分层分拆,实现了基本的云原生应用能力。后文有更具体的阐述。
当前,构建云原生应用的主流手段是云托管服务、容器、微服务、Kubernetes和DevOps。容器让应用的形态得以标准化,而微服务将一个单体应用分拆为多个微服务,每个微服务更加轻量和独立。Kubernetes成为了应用容器的编排和管理平台,支持应用的弹性伸缩,提升了应用的运行效率。而DevOps则提升了应用的研发和上线效率。使用云托管服务,进一步简化应用的架构和逻辑复杂度,使得其主要代码是业务逻辑,从而简化应用的开发难度,也加快其开发速度。这一切手段,才使得云原生应用的特性被实现出来。
从以上的阐述可以看出来云原生和Kubernetes的关系:Kubernetes是目前实现云原生应用的主流技术之一,但不是全部;运行在Kubernetes中的应用不一定是云原生应用,只有具备前面阐述的那些特性的应用才是云原生。
所以,云原生是目的和结果,而Kubernetes是实现这个目的的当下主流技术手段之一。云原生和容器化以及其他技术之间的关系也是类似关系。
更进一步,判断一个应用是不是云原生,看的不是它是不是容器化了,是不是运行在K8S上,而应该看它是否够“快”。
下图是一个简单的不全面的云原生技术栈示意图供参考。具体可参考CNCF等提供的完整云云原生技术栈。
本节笔者想写的是云原生的第一个发展阶段。这里不谈云原生是如何起源的。关于云原生的历史,具体可在网上搜索更多资料。
有位王姓朋友 @ak 2021年11月30日在云计算微信群里讨论时,提出了他所总结的四条应用实践,并认为基本上这四样做完了,应用就大致接近一个基本云原生状态了。群友们都深表认同,并把这四条命名为“王四条”。笔者也觉得很有道理,所以直接引用过来放在这里:
“王四条” | 做法 | 价值 |
---|---|---|
第1条:用对象存储存储静态文件 | 通常认为,不需要动态生成的文件就是静态文件。比如,一次写入多次读取的文件是比较标准的静态文件。对象存储相对于块存储和对象存储而言,只需要提供简单的HTTP编程接口(API),以供客户端使用。 | 对象存储经济高效、可以轻松扩展、使用方式灵活、是一种非常适用于静态数据的存储系统。 |
第2条:用role而不是ak和sk | ak(access key)是访问秘钥,sk(secret key)是秘密访问秘钥,相当于程序使用的用户名和密码。role(角色)特指AWS提供的IAM服务里的角色,其它的还有阿里云的RAM角色、腾讯云的CAM角色等。 | 相对于使用ak和sk,role安全性高、管理方便、使用方便 |
第3条:尽量使用托管服务 | 托管服务是由公有云完全托管管理的,客户不需要关心具体的服务细节,只通过接口来使用服务,通过云控制台、api和sdk来管理和使用服务,扩展、容错和可用性通常内置在服务中 | 实现成本优化,如降低人力成本、能弹性伸缩容错能力强性能好开发优势,如操作灵活、部署快速、服务可靠 |
第4条:数据不要存在服务器上 | 数据是指除代码之前的所有东西,包括:日志:存储在对象存储或托管日志服务中配置文件和证书以及秘钥:通过外部服务或环境变量来管理和获取业务数据:存放在托管数据库服务或对象存储中中间数据:如存放在消息队列中不在代码库中管理的脚本等。服务器指的是虚拟机和容器。 | 成本优化:比如使用竞价实例,减少快存储的使用量(块存储的成本远高于对象存储)容错能力:可以使用弹性伸缩组,故障机器的移除不会造成数据丢失安全性:数据可以更好的追溯和监管开发优势:集中日志分析、这时应用容器化的前提、配置基于环境生成使得部署更简单 |
第4条:数据不要存在服务器上数据是指除代码之前的所有东西,包括:
服务器指的是虚拟机和容器。
https://github.com/lipingtababa/cloud-native-best-practices/blob/main/%E4%BA%91%E5%8E%9F%E7%94%9F%E7%8E%8B%E5%9B%9B%E6%9D%A1.md
采用“王四条”的应用基本上可以认为是处于云原生的第一个阶段。笔者认为它能够从某个层面来回答“云原生从哪里来?”这个问题。
采用这四个实践后,应用就具有了基本的云原生能力,比如,应用因为尽可能多地使用云托管服务而更加轻便,应用使用云虚拟机的弹性伸缩能力来实现分钟级的弹性伸缩特性,通过更多地使用对象存储而不是块存储来降低成本,以及使用云IAM服务提供的role来提高安全性。
Netflix作为公有云和微服务先驱公司之一,是这种云原生的典范实践者之一。Netflix不仅是全球流媒体行业的顶流平台之一,还是业界微服务和DevOps组织的楷模,有大规模生产级微服务的成功实践。
Netflix的应用架构分层:
Netflix的应用架构示例:
Netflix不仅大规模使用公有云托管服务,为了让业务团队专注业务能力交付,其平台团队还提供统一的微服务框架和库NetflixOSS Library,方便业务研发团队集成底层PaaS和服务治理能力。
笔者为Netflix对IT和云计算行业发展做出的巨大贡献向其致敬!
关于Netflix应用,笔者前期的两篇文章可供参考:云中奈飞(一):Netflix的上云之旅,云上奈飞(二):Netflix全球视频流服务的微服务架构设计。
但是,此阶段的云原生还有一些局限,比如虚拟机的弹性是分钟级的,还做不到非常快,基于虚拟机的DevOps落地也比较困难。
笔者试着通过阐述云原生的发展阶段2和3来回答这个问题。
2014年前后,有两大标志性事件推动云原生进入新的发展阶段:一是2013年3月20日,Docker发布了其首个版本。二是2014年6月6日,Kubernetes发布了其首个版本。
Linux容器技术因为Docker出现而被大规模地采用,其弹性伸缩能力比虚拟机提升了一个数量级。容器的编排能力随着Kubernetes的出现而被产品化进而被标准化。因为容器和Kubernetes,DevOps的落地难度也大幅下降,因而被广泛地采用。
这种阶段的云原生应用,因为被容器化而变得标准化和更易迁移,能真正地实现“一次开发,多处运行”;应用的运行平台因为K8S化而变得标准化,IaaS层的差异被屏蔽,应用只需要面向同一个运行平台。服务网格如istio等的出现,大量与业务无关的底层代码被下移到了网格层并成为了基础设施的一部分,应用变得更加轻薄。DevOps在千千万万企业和单位中得以落地。而大量云原生服务涌现,比如云原生数据库、云原生大数据服务、云原生中间件等等,使得整个云原生生态得以不断丰富。
但是,此阶段的云原生应用还是具有一些局限性,比如开发者还是要负责容器打包,运维人员还是需要管理容器实例和底层基础设施。
关于Serverless,笔者之前写过一篇文章可供参考:AWS 15 年(1):从 Serverful 到 Serverless,这里不再赘述。
就像本文一开始阐述的什么是“应用”,在云上至少有两种应用。
一种是云厂商提供的云服务。从AWS大规模推动其云服务Serverless化开始,其它云厂商都已在跟进。云服务的Serverless化,使得用户不需要管理云服务的实例,云服务实现了真正弹性,对用户只是接口或平台。关于AWS自身PaaS服务的Serverless化,可参考此文:年中盘点 | 2022年,PaaS 再升级。
另一种是用户开发的应用。这种应用通过AWS Lambda及其他类似云服务运行。用户只需要上传应用代码(通常称为函数),其它的一切都交给云平台和云厂商。开发人员真正实现了只需要写业务逻辑代码,应用运行真正实现了“事件驱动的按需运行,不需要就停止运行”,运维人员也不在需要管理底层的容器实例。
那Serverless是云原生应用的终极形态吗?好像是,又好像不是。说“是”,是因为应用都只剩下函数了,还能怎么进一步简化呢?说“不是”,技术的发展一日千里,将来的事情怎敢预测?!
还是引用下业界大牛的观点吧。2019 年,UC Berkeley 在论文 《Cloud Programming Simplified: A Berkeley View on Serverless Computing》 中表示 “Serverless 架构将会成为云时代默认的计算范式”。
两个附带问题
这个问题的争论很多。很多人认为,私有云不是云;很多人认为,真正的云原生还得基于公有云。
但笔者认为,阶段1和阶段2的云原生是能够在新型私有云中实现的。这是因为,越来越多的企业和单位采用公有云技术栈来搭建新型私有云,笔者将这种私有云称为“全栈云”,它具有公有云的基本能力和特性,具有较完整的云原生技术栈,只是运营模式、规模和弹性相比公有云要差一些。在前期的文章中,笔者对这种全栈私有云有过的一些阐述可供参考,比如 年终盘点 | 2020年,国内私有云正式进入3.0时代,2022年终盘点 | 数字化背景下的金融云演进。
从实际情况来看,以金融业为例,即使很多中大型金融机构最近几年都构建了这种全栈私有云,但其应用的云原生化都才刚刚起步。之前的所谓应用云化,还只是把原本运行在物理服务器上的应用搬到云虚拟机中运行(lift and shift)。
可喜的是,很多企业和单位跳过阶段1,直接在尝试甚至落地阶段2的应用云原生化了。这在某种程度上也是一种后发优势。而阶段3,那会是更久远的事情,暂时还只是玩玩或试试,小范围应用在某些特定场景中。
附带问题2:传统企业需要云原生吗?
前段时间有人写了一篇文章,认为传统企业不需要云原生。笔者不敢苟同。笔者做了一些调研和思考。首先思考的一个问题是“什么是传统企业?”,为此还写了一篇文章 到底什么是互联网企业和互联网思维?。
传统企业范围很大,还是回到笔者比较熟悉的金融行业吧。当下的金融行业(除了互联网金融行业)基本都还属于传统行业。那传统金融行业需要云原生应用吗?笔者认为是需要的。还是回到前文的观点,我们以终为始,应用云原生化的目的是为了支撑业务变得更“快”更“敏捷”,以能够更快地满足快速变化的市场和用户需求。那么,这些传统金融企业和单位不需要更快地满足快速变化的市场和用户需求吗?答案肯定是需要的。因此,顺理成章地,传统企业的应用云原生化也是有必要的,只不过考虑到投入产出、技术力量、业务场景等多种因素,要分场景分步骤分阶段实施。
写于2023年春节返乡途中