硬核科普:到底啥是云原生?

Posted Baret-H

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了硬核科普:到底啥是云原生?相关的知识,希望对你有一定的参考价值。

本文主要根据课程 什么是云原生?_哔哩哔哩_bilibili 总结而来,其他参考文章如下:

云原生

伴随云计算的的大火大热,云原生(CloudNative)的概念应运而生,但是搜集网络上的各种相关资料,对到底什么是云原生大都描述的云里雾里,究其原因,是因为云原生一直在发展变化当中,并没有确切的定义,解释权不归某个人或组织所有

接下来我将从网上搜集到的各种资料以及实习工作中我自己的理解,为大家解释一下我眼中的云原生。

预备知识——云的一些基本概念

在介绍云原生之前,我们首先需要了解云相关的专业术语

1. IaaS、PaaS、SaaS

  • 基础设施即服务laaS: Infrastructure as a Service)

    指把IT基础设施(包括服务器、存储和网络)作为一种服务通过网络对外提供,并根据用户对资源的实际使用量或占用量进行计费的一种服务模式

  • 平台即服务PaaS:Platform as a Service)

    把服务器平台作为一种服务提供的商业模式,通过网络进行程序提供的服务

    所谓PaaS实际上是指将软件研发的平台作为一种服务,以SaaS的模式提交给用户。因此,PaaS也是SaaS模式的一种应用。但是,PaaS的出现可以加快SaaS的发展,尤其是加快SaaS应用的开发速度。在2007年国内外SaaS厂商先后推出自己的PaaS平台

  • 软件即服务SaaS:Software as a Service)

    通过网络提供软件服务,SaaS平台供应商将应用软件统一部署在自己的服务器上,客户可以根据工作实际需求,通过互联网向厂商定购所需的应用软件服务,按定购的服务多少和时间长短向厂商支付费用,并通过互联网获得Saas平台供应商提供的服务

2. 公有云、私有云、混合云

云计算平台也称为云平台,是指基于硬件资源和软件资源的服务,提供计算、网络和存储能力,用于部署云计算资源。云平台通常有三种公共云私有云混合云

推荐阅读漫画:什么是公有云、私有云和混合云?_程序人生的博客-CSDN博客



一. 什么是云原生

云原生CloudNative的概念最早在2013年由 Pivotal公司的 Matt Stine提出;2015年,云原生刚推广时,Matt Stine 在《迁移到云原生架构》一书中定义了符合云原生架构的几个特征:12因素、微服务、自敏捷架构、基于API协作、扛脆弱性;与此同时,云原生计算基金会(CNCF)成立,其最初把云原生定义为包括:容器化封装+自动化管理+面向微服务;到了2017年,Matt Stine在接受InfoQ采访时又改了口风,将云原生架构归纳为模块化、可观察、可部署、可测试、可替换、可处理6特质;

而Pivotal最新官网对云原生概括为4个要点:DevOps+持续交付+微服务+容器。到了2018年,CNCF又更新了云原生的定义,把服务网格(Service Mesh)和声明式API给加了进来,其在关于云原生定义v1.0版本中这样描述云原生技术体系:

  • 云原生技术有利于各组织在公有云、私有云、混合云等新型动态环境中,构建和运行可弹性拓展的应用
  • 云原生代表技术包括容器、服务网格、微服务、不可变基础设施和声明式API
    • 这些技术能够构建容错性更好、易于管理和便于观察的松耦合系统
    • 结合可靠的自动化手段、云原生技术使工程师能够轻松地对系统做出频繁和可预测的重大变更

当今,我们可以将云原生理解为构建和运行应用程序的方法,是一套技术体系和方法论。主要包含以下几中代表技术/方法论:DevOps、容器及容器编排、声明式API、微服务及微服务治理、服务网格、不可变基础设施

为了更加细致的理解,我们将其拆分为两部分:云Cloud原生Native原生指的是用任意编程语言开发的应用程序,称为原生应用,指的是开发好的应用后我们部署到云上,使应用在云上高效运行,充分利用和发挥云平台的弹性+分布式优势。总结起来,云原生就是原生应用上云到过程以及云上的一系列解决方案。再结合相关技术栈进行理解:

符合云原生架构的应用程序应该是:采用开源堆栈(K8S+Docker)进行容器化,基于微服务架构提高灵活性和可维护性,借助敏捷方法、DevOps支持持续迭代和运维自动化,利用云平台设施实现弹性伸缩、动态调度、优化资源利用率。



二. 云原生诞生背景

上述我们对云原生的概念有了基本了解,接下来我们来谈谈云原生的诞生由来。任何新潮技术/方法论的提出都有实际需求的驱动,云原生的提出正是为了适应当今火热的复杂应用体系下的分布式架构。

从上世纪80年代至今,软件和信息系统领域相关的技术都进行了各自不同形式的迭代,也附有各自的里程碑式的代表技术,其中主要体现在开发流程应用架构打包部署基础设施四个方面,如下图所示,其中:

  • 开发流程 从瀑布模型、敏捷模型再到如今的火热的DevOps、GitOps等模型
  • 软件架构 从单体架构、分层架构、分布式架构再到如今的微服务架构
  • 打包部署 技术从裸服务器、虚拟机再到今天主流的容器化技术
  • 基础设施 从数据中心、数据托管再到今天的云计算

可以看到:DevOps微服务容器化云计算是当今的主流模型。

随着业务规模的扩张,从单体架构走到分布式架构,以纵向或者横向切分的方式将大的应用拆分为多个小应用几乎是提升系统容量加强系统可用性的必然选择,分布式架构方便我们开发与实现、将出现故障的影响范围缩小、将开发系统的拓展性大大增强,但是分布式带来这些优点的同时也包含许多很多问题,例如发布频率变高、部署变复杂、系统架构设计难度大大增强、并且由于网络通信的引入,响应时间也是重要因素,此外,对于运维的难度也是成倍放大。

为了解决以上问题,提出了一系列解决方案:

  • 服务治理(依赖关系、调用链)
  • 架构管理(版本管理、生命周期管理、[编排、聚合、调度])
  • DevOps
  • 自动化运维
  • 资源调度监控
  • 整体架构监控
  • 流量治理(负载均衡、路由、熔断…)

简单总结起来,运行分布式系统的典型需求主要有以下四个方面:

  1. 生命周期管理
  2. 网络管理
  3. 状态存储管理
  4. 分布式系统内外应用绑定与集成管理

下图大概展示了以上每个需求分别涉及到的一些技术问题:

能够满足以上需求方案曾经的主流系统是ESB(企业服务总线,Enterprise Service Bus)

ESB说白了就是一个中间件,比如面向消息的中间件以及一些轻量级的集成框架,支持利用面向服务的架构支持异构环境中的服务、消息,以及基于事件的交互,并且具有适当的服务级别和可管理性。它提供了良好的功能集,但是单体架构以及业务逻辑和平台之间紧密的技术耦合会导致技术和组织中心化,这是与分布式系统背道而驰的。从上述四个需求方面分析,ESB系统对于分布式支持的局限性如下:

  • 生命周期:ESB通常只支持一个语言运行,这限定了软件打包、可用库、打补丁频率等诸多方面
  • 网络:只支持一个语言及其相关技术,且网络问题和语意深深嵌套与业务中,这时候后续的架构升级等需要对代码做出极大的变更
  • 状态:与状态交互的库和接口没有完全抽象出来,也没有与服务运行时完全解耦
  • 绑定:必须使用根据消息交换模式构造代码和设计流程,与分布式所需的多协议、多数据格式、多消息交换模式来连接其他系统相违和,导致系统拓展及其受限

针对ESB系统的不足,当今云计算时代提出:基于容器化、容器编排、DevOps、微服务及典型的治理系统服务网格等技术的云原生解决方案

以上就是云原生的诞生背景,说白了就是随着发展实际需求而驱动所得。



三. 云原生系列技术/方法论

云原生理解为构建和运行应用程序的方法,是一套技术体系和方法论。主要包含以下几中代表技术/方法论:DevOps、容器及容器编排、微服务及微服务治理、服务网格、不可变基础设施

1. DevOps

DevOps 是一系列做法和工具,可以使 IT 和软件开发团队之间的流程实现自动化。其中,随着敏捷软件开发日趋流行,持续集成 (CI)持续交付 (CD) 已经成为该领域一个理想的解决方案。在 CI/CD 工作流中,每次集成都通过自动化构建来验证,包括编码、发布和测试,从而帮助开发者提前发现集成错误,团队也可以快速、安全、可靠地将内部软件交付到生产环境。

  • 持续集成CI:代码编写完成后,后续的构建、测试、合并到代码仓库这一系列操作持续自动化完成
  • 持续交付CD:自动化的将代码打包成镜像然后发布到镜像仓库中
  • 持续部署:自动的仓库中的镜像部署到k8s平台上,然后就能监控代码的运行期间的各种指标过程以及日志信息

总结一句话就是:DevOps就是只要代码发生变更,通过一系列的自动化流程,就能在线上的云平台看到代码变更后的效果,减少了开发人员和运维人员之间大量工作,全部交给自动化链路来完成

也就是就是自动化的进行代码编写、构建、分析、测试、合并代码库、构建打包成镜像、部署、线上运维分析这一闭环

2. 容器&容器编排

容器技术由来以久,只不过2013年前后,dotCloud这家公司在Docker项目中发明了“容器镜像”技术之后,创造性的解决了应用打包的难题,将容器技术焕发出新的生命力,并以应用容器的面目风靡于世。

所谓应用容器,与传统容器比较起来,可以将此前的容器技术称为系统容器,使用方式类似于一个轻量的虚拟机,其上运行了很多应用,而应用容器中通常只运行某一个特定应用的进程及其子进程,不会再运行其他进程。

基于Dokcer引进,应用容器的出现,如果某个容器中只运行单个应用的话,考虑到应用开发的分布式甚至是微服务的模型下,我们只有将一个系统相关的所有应用均以容器化方式运行并组织编排好其中的关系、运行逻辑以及通信机制,才能够确保整个系统流畅平滑的运行。

因此单个容器的管理系统难以产生价值,容器编排才是根本。其中最为著名的容器编排系统就是kubernetes,也就是常说的k8s,现代的容器技术与k8s将打包、分发和应用部署演化成了与编程语言无关的格式

k8s有以下几个关键特性:

  • 遵循声明式API编程范式,将声明式API引入到了云计算管理平台来,它结合控制器模式支撑起整个k8s系统运行的基本逻辑
  • “以应用为中心”的现代应用基础设施,该设施纳管各类基础支撑类服务,并经由声明式api向上层应用暴露这些基础设施能力。单机操作系统本身存在的主要目的也是创建运行调度编排应用程序,只不过k8s是把应用程序的创建启动运行调度编排运行在一个更大的云计算环境中去
  • platform for platform类型的系统,也就是为构建其他平台而提供的平台系统,所以大多数情况下,为了更加完善的运行应用,一般不直接使用k8s的原生api接口来构建运行应用,而是在k8s之上添加补充完善出其他平台系统后再去运行应用程序,其中最为著名的两个系统就是服务网格Service Mash和无服务计算Serverless

3. 微服务&微服务治理

微服务是一种流行的架构风格,用于构建弹性化、高度可拓展、可独立部署且能够快速迭代的应用程序。本质就是将大服务拆分成小服务,每个小服务都是自包含的,应该在有界上下文中实现单个业务功能。

动态化是云原生应用的天然属性,而微服务架构是支撑该目标的关键所在,服务治理工具又是支撑微服务运行的根本所在。为了便于用户开发创建维护运行微服务应用,通常需要依赖对应的服务治理框架,著名的有Dubbo、Spring Cloud Alibaba、以及未来的服务治理框架ServiceMesh等

4. 服务网格

在分布式/微服务架构系统当中,服务间的通信是至关重要的,因此我们需要保证通信通道无故障、安全、高可用足够健壮,这些需求恰恰是服务网格作为基础结构组件出现的原因,它的实现方式就是通过在每一个应用实例的外层附加一个服务代理来确保受控的服务到服务的通信,这个代理称之为sidecar,主要负责各个业务单元实例之间的通信相关的功能(例如服务发现、负载均衡、断路、超时、重置等等),服务网格并不是一蹴而就的,而是从最早期的ESB到Dubbo、SpringCloud一路发展基础之上所衍生出来的新一代的通信模型

如果说前一个时代,例如Dubbo+SpringCloud这种纯粹的微服务框架当中,开发系统中的每一个业务逻辑几乎都需要与同系统中其他模块进行通信,因此为了实现各种各样的高级网络功能,它必须内嵌与网络相关的例如服务发现、负载均衡、熔断限流、服务路由等网络功能,这些功能早期是通过sdk的方式进行加载,如果考虑到分布式系统中的每个模块可能是由不同编程语言所开发的话,那么这个sdk本身就需要支持多种不同语言来调用接口,这就使得存在几个问题:

  1. 可用sdk语言版本有限
  2. sdk的更新会导致业务代码的更新

于是发展到服务网格时期,我们的每一个微服务应用本身就被切分成两部分,如上图所示,每一个业务逻辑只需要对特定的一个轻量级sdk发一个请求调用即可,对应的网络功能则由专门开发独立运行只需要通过标准协议进行通信的而无需与编程语言强绑定强耦合的sidecar完成,这两者联合起来形成独立应用。这里的sidecar专门处理服务间的通信,与业务逻辑无关,这样业务逻辑专注于本身即可,无需感知sdk。这就解决了每一个业务逻辑的开发人员无需再关心有哪些sdk可以调用,只需要实现自己服务该有的业务逻辑并且能够与对应的sidecar的标准接口进行关联即刻。

因而,服务网格以sidecar的形式,将服务治理从业务逻辑中剥离,并拆解为独立进程,实现异构系统的统一治理和网络安全。

服务网格最为典型的代表产品为IstioOpen Service Mesh 以及 阿里云的ASM

5. 不可变基础设施

不可变基础设施早在2013年由Chad Fowler在一篇博客中提出,提出该构想的原因在于:过去非容器化时代,我们通常将应用部署在裸服务器/虚拟机上,它们底层支持配置的多次变更,因而会导致一旦灾难发生时,重新构建出一模一样的配置环境非常困难,除非我们确保每一个运维/开发人员实现变更的时候能够按照确切的流程提交工单并按照工单本身的要求一字不差的来执行变更;此外,还会存在导致状态不一致的风险。

因此为了改变这种现状,最好的方式就是确保底层环境不变,至少是运行应用程序的周边依赖到的系统环境不变,很显然,容器化时代能够很好解决这个问题,因为现代应用容器当中,每一个容器运行单个应用,如果将这个应用的数据和状态保存在容器外围独立于容器生命周期的存储系统上,一旦这个容器启动后自己本地不存储除临时数据外的其他任何数据,就确保了这个容器接近于只读状态,一旦容器本身出现故障或者其他原因需要重建时,只需要基于同一个镜像启动一个新的容器关联到原存储系统上就能恢复出一摸一样的环境。

因而,不可变基础设施核心思想在于任何基础设施的实例一旦创建出来就变味只读状态,若需要修改和升级,都不能通过配置该实例实现,而只能通过替换为新实例来实现

这样,在公有云、私有云、混合云等云计算时代,如果要让系统运行在IaaS环境之上的话,考虑到如果数据及不存在于容器中也不存在于容器运行所在主机上,而是存在于机器外围一个统一的存储系统之上,这个存储系统的声明周期与该主机生命周期无关,这样就算主机故障导致容器故障,我们重建主机容器都可以完全复现未出故障前的状态,也就避免了导致状态不一致的风险。

此外,如果我们遵循不可变基础设施的话,现在还有一种IaC技术,即基础设施即代码,通过借助于调用对应的IaaS云的api等等来确保底层系统环境当中的不仅是容器包括容器网络等一切环境都可重构可复现机制,那么整体的系统运维将变得更加简单和易于实现。



四. 云原生系统功能特征

据上文所述,动态化是云原生应用和云原生基础设施的天然属性,而微服务架构是支撑该目标的关键所在,因此云原生系统往往需要具备以下功能特征:

1️⃣ 构建云原生系统时,应该有一个统一的API网关

每一个服务本身都通过 api 向外提供其功能,我们当然不希望客户端获取所需功能的时候需要独立的与对应每一个微服务进行通信,所以各个微服务提供的 api 应该聚合成为复合api,也就是对外提供一个统一的访问接口。那因而我们再去构建云原生系统的时候,还应该有一个关键性的组件叫做api 网关。

2️⃣ 微服务治理

服务治理工具又是支撑微服务运行的根本所在,例如IstioOpen Service MeshLinkerd 等等都是微服治理尤其是服务网格时代的微服治理的工具

3️⃣ Serverless平台

Serverless 是一种由开发人员和企业共同推动的运动,他们意识到软件正在吞噬世界,但如果您自己构建和维护所有软件,您也会被吞噬。这一运动要求将构建应用程序中最琐碎的部分抽象化,以便开发人员能够真正将时间花在交付业务价值上。

这一运动的目的是让开发人员能够单枪匹马地构建处理生产级流量的应用程序。他们不必管理扩展他们的基础设施,他们不必配置服务器,也不必为未使用的资源付费。他们可以专注于开发。

最著名的的Serverless平台就是上文提到的Knative

4️⃣ 云原生编排平台

云原生的编排平台去调度运行应用程序,并对其做健康监测、监控、弹性扩缩容等,最著名的就是k8s

5️⃣ 灵活部署

微服务治理通常还能够支持像对应服务灵活部署功能,例如灰度发布、蓝绿发布,金丝雀部署、A/B测试、影子Shadow部署等等相关功能



五. 云原生架构模型

为了能够正常的运行云原生应用程序,云原生的架构模型至少需要组织以下五个层级:

1️⃣ 基础设施层

第一层为基础设施层,即infrastructure。它主要由主机、存储和网络来组成。事实上它也可以是基于对应的私有云、公有云或者混合云来进行构建。那我们这个时候可以使用云端的主机,也就是所谓的计算,还有网络用通信以及存储技术。

2️⃣ 供应层

第二层为供应层/预配层,即provisioning。这个层次主要是用来完成主机创建、操作系统,安装、存储空间分配、网络创建等底层基础架构或基础设施所提供的资源,用于配置给上层应用程序所使用的一个关键的中间供给层。所以这个层呢我们称之为叫做主机管理层。那这他们通常要用到的是包括DevOps工具链或者是其他预配工具的相关层级。

3️⃣ 运行时层

第三层为运行时层,主要包含了容器运行时环境相关联的几个关键接口。包括像容器运行时接口CRI、容器网络接口CNI、容器存储接口CSI。那这样就能够用于确保在该运行时环境之上,以容器化的方式运行一个应用程序的时候它能够调用底层所提供容器时运行环境,包括我们的计算资源、网络资源和存储资源等非常重要的标准接口。所以这个时候我们需要一个运行时层来解决诸如此类的问题。

4️⃣ 容器编排及管理层

第四层为容器编排与管理层,我们前面强调过单个容器没有价值,只有将多个容器联合起来统一进行编排,才能发挥其价值。于是在容器运行时层环境之上,我们需要提供一个容器编排和管理系统,其中最著名就是kubernetes,但kubernetes是一个platform for platform的平台,它在设计上不是直接面向去组织维护运行我们的现代应用/云原生应用的。而是要在其基础上再去添加组织出来其他的平台来运行应用。比如我们要运行微服务应用的话,我们还应该在我们的kubernestes之上去附加一个istio这样的服务网格系统,然后由该网格系统借助于底层的kubernetes去维护运行我们对应的微服务,主要是微服务之间安全可靠的通信等等。此外,如果我们期望运行的是一个serverless类型的应用的话,那么我们还需要在kubernetes基础上去附加一个serverless的运行时环境,这其中比较著名的开源产品有knative等等。

5️⃣ 云原生应用程序定义与开发层

第五层为云原生应用程序的定义与开发层,在前四层的技术之上,我们便可对云原生应用便捷的进行开发与定义。

因此架构图如下所示:

首先底层基础设施,很可能是私有云、公有云或者是混合云。在云环境的基础之上,就是一个容器编排平台,也就是k8s。然后如果需要用到无服务计算的话,那我们还需要额外提供一个Faas的平台,就是serverless的运行时。接着在该平台之上,我们就可以提供类似于叫做容器及服务的接口,叫Caas接口。再接着向上,我们应该去提部署和提供一个微服务的运行平台,就是服务网格系统Istio去运行各种各样的以微服务形式存在的业务业务单元。接着这些业务单元甚至包括我们底层平台自身都应该纳入到监控系统中来,没有监控,那几乎就没办法管理,所以我们的立体化监控系统由日志、指标监控以及对应的分布式链路跟踪系统等所组成,这是现代云系统几乎所必然要具备的几个监控组件。还有就是api网关,用于实现api 统一的流量管理,尤其是接入外部系统式的流量管理,包括api治理、流量控制等相关功能。此外,对于这么多的微服务应用,必要时我们还应该提供一个统一的认证和访问管理接口Iaam组件。再加上一层,那其实就是我们的开发人员所应该拥有和使用的开发环境。

进一步细化,架构图如下所示:

在公有云、私有云之上,应该有kubernetes,然后在此基础之上,我们应该提供一个微服务的技术中台,通常它是一个Service Mesh。在这个Service Mesh的基础上,我们应该提供开发框架、各种各样的中间件系统、立体化监控系统以及微服务治理工具,以确保实现服务发现、服务监控、服务间通信以及各种各样的网络功能。此外,为了确保高效的去交付每一个微服务应用,那我们还应该遵循DevOps,甚至是GItOps这样的模型来实现应用的CI/CD等相关功能。当然接入外部的访问流量时,我们应该有一个服务的统一接入层,就是API网关。

说到这儿相信您呢对现代的这种云原生架构体系有了基本的认识。如果要简单总结一下的话,那么我们云原生的技术范畴大体可以分为以下六个方面:

  1. 云应用与定义与开发流程
  2. 云原生底层技术
  3. 云应用编排与管理
  4. 云原生工具集
  5. 监控与可观测性
  6. Serverless


六. 如何构建云原生系统

有鉴于此,那我们究竟该如何构建云原生呢?只要遵循前面的范式,把对应系统组合起来,其实我们基本上就能够构建出一个云原生的基础平台了

在这个云设计的平台当中,它的每一层各有各的作用:

  • 微服务架构就是解决单体架构导致的应用复杂性问题的。但事实上我们把它拆分成微服务以后,这个复杂性就留给了我们外部的治理系统,而并不是而并不是真正的减少了这个服务的服务的服务的服务的复杂性。
  • 服务治理框架和立体化监控方案能够解决服务间协同及调用异常的相关问题。
  • 容器技术用于解决应用构建、分发和部署等相关的问题。
  • k8s 用于解决服务编排、调度和弹性化等需求。
  • Service Mesh 用于解决微服务框架的侵入式、流量治理等问题。将Service Mesh 运行于k8s 之上,可以提供更好的容器底层环境支持。
  • 借助于 IaaS云和容器技术,可以解决不可变基础设施相关的问题。

以上是关于硬核科普:到底啥是云原生?的主要内容,如果未能解决你的问题,请参考以下文章

硬核科普:到底啥是云原生?

硬核科普:到底啥是云原生?

就烦别人问我到底什么是云原生?

干货:到底什么是云原生(Cloud Native)?

啥是云主机,云主机是啥样的?

什么是云原生