深挖云原生的真正含义

深挖云原生的真正含义

深挖云原生的真正含义

终于抽时间总结一下对云原生的理解。 

云原生是过去一年里云计算最火的用词之一。几乎每一个云计算的产品厂商都会把自己的产品与云原生联系在一起。但是到底这个词是什么意思,它的具体含义是什么,其实却是非常含糊的。

云原生这个词最早在2014年左右起源于Pivotal。Pivotal是一家做PaaS服务的公司。之后在2015年夏天,Linux基金会创建了云原生基金会CNCF。CNCF在宣布成立时也没有一个关于云原生的具体定义。只是提到了一些相关的技术,包括开源,容器,微服务,编排工具。但是并没有明确地描述怎样使用这些工具开发出来的应用才可以被称作云原生的应用。时至今日CNCF也还没有提出过这个明确的定义。

于是很多公司按照自己的理解去使用这个概念。这导致在很多时候,大家是在说不同的事情。很多公司的理解是只要是涉及云的应用就是云原生。或者是可以给云服务用的工具或者产品就是云原生的。

下面讨论一下云原生的含义,云原生的应用都有哪些特性,以及一个技术团队要成功开发和运维真正的云原生的应用所需要的4大支柱。

究竟什么是云原生?

云原生是云计算时代的新的团队文化,新的技术架构,和新的工程方式。

云原生指的是一个灵活的工程团队,遵循敏捷的研发原则,使用高度自动化的研发工具,开发专门基于并部署在云基础设施上的应用,以满足快速变化的客户需求。这些应用采用自动化的,可扩展的,和高可用的架构。这个工程团队通过高效的云计算现网的运维来提供这一应用服务,并且根据线上反馈对服务进行不断地改进。

我这里强调了几个关键字。一个是云基础设施。云原生的应用一定是会利用云计算,云存储等云资源创建的应用。这个应用也是一定会部署在云的基础设施上的。好的云设施都会提供自动化的,可扩展的,和高可用的架构以满足云原生应用的需求。

另外一个就是灵活的工程团队。云原生的应用一定会是由灵活的工程团队开发的,以快速上线在云设施上,快速满足客户的需求。这个工程团队会使用大量的高度自动化的研发工具,才有可能快速的完成新功能的开发,测试和上线。

最后,云原生的应用在上线到云上之后,工程团队会不断关注应用的运行情况。对这些应用进行运维管理,实时监测,解决随时出现的各种线上问题。云原生的研发团队还会收集应用的线上数据作为反馈,不断地进行分析并且基于这些反馈对应用进行持续的改进。

云原生应用的特征

一般的云原生的应用都会具有以下这些特征:

  • 普遍可访问 (Universal Availability)

云原生的应用可以在任何地方从多前端访问。不需要特殊访问设备。没有网络或者地域的限制。

  • 高可用性(High Availability)

云原生的应用可以充分利用云技术保持随时在线(24x7)。由于云服务多由计算集群提供,集群中一个节点的单点失败对服务影响小。节点失败也会触发自动恢复机制。新的服务节点会被启动,补充失去的资源。服务的升级和变更会采用灰度部署。在这个过程里,会对计算集群中的节点逐渐升级。现网流量会通过负载均衡器(LBS)在新旧版本的节点间分配流量。从而保证升级过程中,服务无中断。服务所涉及的数据会进行实时在线备份。在数据丢失的情况下可以使用数据备份进行数据恢复。对于更为严重的灾难性事件,云厂商大都会提供异地多活与同城双活的架构以保证服务的持续性。

  • 高扩展性(Scalability)

云原生应用可以被在线用户随时访问。各种原因都有可能导致应用的流量在短时间内激增。云原生的应用可以随业务的需要随时迅捷地线性伸缩资源以应对流量在短时间内的大幅波动。

  • 可监控(Observability)

云原生的应用在现网的运行一定不会是一个黑盒子。运维人员可以通过运维工具实时收集应用服务的健康信息。基于这些现网信息,运维人员可以及时察觉和解决现网出现的各种问题。

  • 安全性 (Security)

云原生的应用通过对服务部署的网络(VPC)的设计,利用对网关和防火墙的设计和配置,对应用服务提供多层的安全保护。可抵御众多常规安全威胁。

  • 可迁移性 (Deployable to Different Cloud Providers)

云原生的应用一定会具有很强的可迁移性。云原生的应用会与底层的云计算基础设施分离。整个应用易于迁移到不同的云计算供应商。甚至应用的不同服务可以部署到不同的云计算供应商。整个应用仍然可以正常且有效地运行。

  • 演进式设计与快速迭代 (Evolutionary Design and Fast Iteration)

云原生的应用由于使用微服务架构,微服务之间相互解耦,导致它们可以独立开发,测试,部署和运维。这样每个服务可以独立创新。只要保持接口稳定,不会对应用的其他部分产生影响。而且云原生的工程团队会使用高度自动化的研发测试和运维工具。这使得云原生的应用的更新可以更加快速频繁。达成创新速度提高的最终目的。

上面总结了云原生的应用应该具备的一些主要特征。可以用来辨别一个应用是不是真正的云原生的应用。

云原生的4大支柱

云原生作为一个云时代的企业组织文化,它有4大支柱。我把它们总结成TATO,即:

  • Team & Process 团队与流程
  • Architecture 架构
  • Tools 工具
  • Operations 运维

这4大支柱从四个维度具体描述了云原生的本质含义。4大支柱里提及的每一点都可以进行大幅度地具体的技术展开。由于时间原因,我在这里只是提出提纲,以及一些少量的具体讨论。以后有机会再完成对每一点的更深入的展开。

云原生的团队与流程

  • 小团队开发 (2-pizza Team)

云原生的应用一般由多个小团队共同开发。各个团队负责应用的不同部分,即不同的微服务。这样才能使得团队具有灵活性,对客户要求进行快速反应。团队的具体大小没有固定的定义。一个参照是在午餐时,两个比萨饼可以把团队喂饱。

  • 全栈团队 (Full Stack Team)

云原生的团队成员的工作性质会随着不同的项目而变化。每个工程师既负责开发,也负责测试。按照项目需要,可能前端和后端的开发工作都有。

  • 研发与运维的结合(DevOps)

云原生团队的成员对微服务有端到端的责任(End to End Ownership)。他们既负责服务的开发,也负责服务的运维。这样工程师在做服务开发时就会考虑服务的可运维性。如何更好的部署?如何方便地排错?如何快速地回滚?如何在服务失败后尽快地恢复?而且这样做还使得工程师更贴近客户,了解应用是如何被客户使用的,从而更有效地对服务进行持续改进。

  • 去中心化(Decentralization)

云原生团队对服务的开发和运维有充分的技术决策权。使用什么技术栈,什么工具,什么数据库都可以由团队在整体大方向下自主地根据具体项目需要来做最佳的选取。

  • 敏捷的研发流程 (Agile Development)

云原生的团队由于更加贴近客户,所以对客户的需求有更好的了解。团队可以根据这种了解对工作内容和优先级做及时的调整。而不会被自上而下的统筹安排所束缚。从而得以极快的速度来满足客户的诉求。

云原生的架构

系统框架是云原生的另外一个基石。系统架构在任何计算机系统里都是至关重要的。系统的架构对系统的性能,可靠性,可扩展性,长期可维护性,和可运维性等等都起着决定性的作用。对于云原生系统也不例外。

  • 微服务化架构(Micro Service Architecture)

云原生的应用一般不是单体架构,而是由一些功能专一的微服务组成。这些微服务高度解耦,相互之间沟通是通过接口调用,这些服务可以独立开发,测试,部署,和运维。

  • 基于云基础设施(Based on Cloud Infrastructure)

云原生的应用都会搭建在基于云的基础设施上。应用会按需自动获取或释放云基础设施提供的计算、网络、存储等云服务。

  • 分布式云化部署 (Distributed Deployment)

组成云原生应用的微服务大都部署在虚拟IP地址(VIP)后面的虚机集群的多个节点上。通过负载均衡器(ELB)来管理服务请求的分发。这样可以避免单机失败对服务的影响,提高服务的韧性。同时也方便调整资源的容量。这些服务还可以部署到不同地理区域的数据中心。这样可以获得更加坚固的冗余性。对全球客户的支持也会有更佳的性能。分布式部署的去中心化的服务可以使用自己独立的数据库存储,以满足服务的需要。

  • 无状态(Stateless)

为了提高服务的处理效率和有效地支持服务的横向扩展,需要保证对服务的调用请求可以由任意一个节点处理。所以云原生应用会采取无状态的服务架构,服务请求中已包括处理此请求所需的足够信息。这样也会保证单点失败对服务功能无影响。

  • 无本地依赖 (Localless)

分布式的多节点部署带来的一个问题是这些单个节点可以由于硬盘、网络等各种原因导致其失败。当一个节点失败时,节点上的数据也会丢失。因此,云原生的应用会尽量使用云资源而避免使用本地资源。比如使用云存储,云数据库,基于云的缓存,消息队列等等云服务。

  • 可水平自动弹性伸缩(Horizontal Auto Scaling)

为了应对服务的流量变化,云原生的应用会利用无状态无本地依赖等架构设计使得应用的性能可以随着调整节点数量而得到线性调整,从而提高应用性能和资源利用率。应用可以通过自动伸缩引擎定义弹性伸缩的规则,使得在流量负载达到特定指标时在不经手工干预的情况下完成对资源的调整。在资源调整过程中,现有服务连接会被优雅地管理,做到前端无感知。

  • 服务注册与发现 (Service Registration and Discovery)

像前面已经讨论的,分布式的多节点部署带来的一个问题是这些单个节点可以由于硬盘、网络等各种原因导致其失败。新的节点会补上来。另外计算节点在做自动伸缩时,节点地址也会发生动态变化。服务注册与发现可以体现服务的最新的可用节点。负载均衡器可以基于这个信息安排调用请求的导流。

云原生的工具

工欲善其事必先利其器。云原生的应用由很多微服务组成。云原生应用的特点就是能够快速更新以满足市场和用户的需要。应用的更新是通过微服务的快速更新迭代来实现的。行业顶尖公司的应用在现网更新是以秒级来计算的。也就是每天的更新可以达到近万次。为了支持如此高频的现网更新,同时还要保证更新的质量,有效的高度自动化的研发工具是能否成功地持续开发云原生应用的关键。

  • 自助环境获取(Self Serviced Environment Acquisition)

无论是开发新功能,或者复现一个问题,工程师最大的抱怨就是建立相应的开发环境。装操作系统,装工具,下代码,做配置。要折腾好几天才可以开始看具体问题。切换成本非常大。所以有预制的开发资源(虚机或者容器),上面预装了相应的开发环境和配置,并且这些资源可以自助获取,可以大幅提高研发人员的工作效率。

  • 统一标准的服务开发框架或基础设施 (Standardized Service Framework or infrastructure)

开发一个高质量的微服务,需要考虑的因素很多。除了服务本身的商业逻辑,还需要关注每个服务都需要处理的公共功能,例如身份验证与授权,限流,缓存,日志,监控与度量,等等。这样使得开发人员不能专注于自己的商业逻辑,降低了开发效率,而且对开发人员的要求也更高,公共功能的实现也不能达到一致的质量和行为,所以使用统一标准的服务开发框架有助于云原生应用的开发。Spring Boot是一个这样的开源的服务框架,亚马逊使用Coral服务框架,不过这些源代码级的服务框架会对编程语言有限制。最近兴起的服务网格(Service Mesh)从网络层面解决这个问题,应该是一个长期的发展方向。

  • 贴近现网环境的模拟开发环境 (Production Environment Simulation for Local Development)

开发的一大痛点就是程序在开发机上运行正常,但是到现网环境不工作。简单的环境可以提供通过基础设施即代码(Infrastructure as Code)的方式自动建立,谷歌的Cloud Code工具就是采用这种做法,亚马逊的AWS CDK也提供了类似功能。

依赖复杂环境和相关数据的程序调试则相对困难,同一服务的多个版本的存在更需要借助API网关进行管理。即使这样仍需要把开发机的最新代码打包部署到测试环境,无法直接在开发人员本地的开发机上进行代码调试,降低开发效率。目前最佳的解决办法是使用开源的Telepresence用双向代理把本地开发机接入到测试环境里,这样本地机被虚拟成在测试环境里的一个节点,开发者就可以直接在本机上做调试了。

  • 分布式跟踪(Distributed Tracing)

一个用户服务请求很有可能需要提供调用多个服务完成,即A服务调用B服务,B服务调用C服务的方式,于是用于跨服务的调用链的跟踪就变得非常重要。像Zipkin,Jaeger这样的分布式跟踪工具可以提供这种的能力。这样在做端到端的调试和调用链分析的时候就非常有用了。

  • 测试自动化 (Test Automation)

应用的质量至关重要。对要上线的功能执行相应测试用例才能确认软件包的质量。快速上线的要求需要测试用例的高度自动化来保障。首先是自动化尽量多的单元测试。功能测试中的API测试由于不涉及UI,所以测试用例的自动化也比较好维护。因此在设计功能的测试用例时,尽量使用API测试。对于UI测试,由于UI可能的变化,UI在测试运行时所处状态和时间问题,导致UI的自动化测试用例的运行不够稳定。所以在设计UI测试用例时要着重注意提高测试稳定性。需要考虑的策略包括:使用类似辅助功能模型(accessibility model)的功能来驱动UI,初始状态的检验和重设,用智能等待(smart wait)解决时间问题(timing issue),简化或者隔离测试环境以降低环境噪音。最后就是有足够的测试日志和截屏信息。这样当有测试用例失败时,可以迅速找到失败的原因。

  • 场景模拟 (Scenario Simulation)

当你调试应用的一些时候,你需要调用到其他服务。并且需要这些接口返回特定的数据。有时候这些接口还没有准备好,或者设置那个接口返回你所需要的数据比较困难。这时可以采用接口模拟工具(mock)去模拟你需要的场景。

  • A/B测试 (A/B Testing)

云原生的应用应该利用云应用的实时反馈优势,理解客户的诉求。像开源软件Convert就是一个不错的A/B测试的选择。

  • 开发者工具网站 (Simple developer web portal)

这个比较容易理解。所有研发工具最好有一个公共入口。这样可以提高工具的可发现性。

  • 持续集成 (Continuous Integration)

一个应用一般会有很多服务组成。这些服务都在由不同的研发团队并行开发。持续集成系统会定期把不同开发人员提交的新代码集成在一起,进行编译和自动化测试,以时刻保证应用的质量。

  • 持续交付流水线 (CD Pipeline)

与持续集成相关的是持续交付流水线。持续交付流水线的目的是确认应用发布包的质量并最终将发布包部署到现网环境。持续交付流水线一般会包含几个阶段,每一个阶段会对应一个部署环境,每一个阶段会定义此阶段需要执行的测试内容。流水线会负责这些环境的管理并根据每个阶段的测试执行结果决定是否把新的发布包沿着流水线继续向前推动。Jenkins是目前极为流行的CI/CD的执行工具。

  • 灰度发布和回滚自动化 (Gray Release and Automated Rollback)

研发的最后一步就是把发布包部署到现网。云原生的应用在新版本更新时要保证服务的持续性。如果一个应用仍然需要定期地下线进行维护,在此时间段不能使用,那这个应用还没有完成云原生的征程。云原生的应用经常会通过灰度发布等方式达到服务的持续性。灰度发布过程中,灰度发布引擎会先把部分节点下线,进行服务的版本更新和测试。版本更新过程一般不会覆盖旧的版本,这样在需要的时候方便版本回滚。新版本测试成功后,会把更新后的节点上线,把现网的正常流量部分导流到新版本的节点上。如此循环操作,直到所有节点都转到新版本上。在这个发布的过程里,如果发生新版本更新失败,灰度发布引擎会触发回滚机制,把已更新的版本节点回退到更新前的版本。当然在这个过程里会涉及到具体的升级和回滚的策略,比如每次升级的节点数量,现网导流到新节点的流量,如何定义更新失败,回滚的次序和节点数量等等,都可以在灰度发布引擎中定义。

  • 依赖与版本管理 (Dependency and Version Management)

云原生的应用使用微服务的架构,微服务的功能相对独立,微服务需要与其他微服务合作去完成某项任务。不同版本的服务功能会有所不同,有时某个服务需要另外一个服务的某个特定版本里的功能,这就产生了服务的版本依赖。在服务众多的情况下,这个依赖关系会比较复杂,依赖和版本的有效管理对服务编译和上线的运维都有重要的影响,亚马逊的VersionSet和LinkedIn的Dependency Service从不同角度去解决这个问题。

如果你看到了这里,希望上面的内容对你有帮助。

上面讨论了云原生的具体含义是什么,云原生应用具备哪些特征,以及云原生的4大支柱TATO里面的3个,即团队与流程,架构,和工具。下面有时间我会再加上关于第4大支柱,即云原生的运维的讨论。如果有需要切磋,可以下面微信联系我。

 

来源:知乎, 原文链接

posted @ 2021-01-24 21:11  云社区  阅读(233)  评论(0编辑  收藏  举报