云原生的4大支柱
Posted 超级技术工厂
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了云原生的4大支柱相关的知识,希望对你有一定的参考价值。
云原生是过去一年里云计算最火的用词之一。几乎每一个云计算的产品厂商都会把自己的产品与云原生联系在一起。但是到底这个词是什么意思,它的具体含义是什么,其实却是非常含糊的。
云原生这个词最早在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)
无状态(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从不同角度去解决这个问题。
云原生的运维
基于容器的部署(Container Based Deployment)
云原生的一个基本要求是应用可以快速部署。容器的秒级拉起时间可以完全满足这一要求。如果一个容器挂机,也可以马上被替补。容器在一定程度上还完成了跨云兼容的任务。另外,容器如果与服务网格结合使用,可以简洁方便地完成几乎所有复杂的网络导流的需求。
服务状态的实时感知(Real Time Service Status through Monitoring)
云原生的运维必须可以实时感知服务的运行状态。任何黑盒的服务都是不可支持的。运维人员可以通过对资源和应用收集预定参数,以监控服务的运行状况。根据服务的实时运行状况,运维人员可以采取相应的措施使得服务健康地持续运行。
实时报警(Real Time Alerting)
基于日志的运维数据采集和处理(Log Based Data Collection and Processing)
微服务在运行中会产生大量的系统和服务日志。这些日志里包含了大量关于系统和服务的运行信息。云原生的运维需要有一个高性能的分布式日志处理系统,去从各个节点收集日志,存储日志,和处理这些日志。
资源管理与调度(Resource Management and Allocation)
云计算厂商需要保证资源合理,有效和充分的应用,以获得最佳性价比。一方面,我们不想资源闲置造成浪费。另一方面,我们不想有需求却由于没有可用资源而影响服务性能。另外资源调度系统需要管理硬件的定期主动下线维修和软件的主动更新和系统重启,以降低服务的被动故障率,提高服务在线时间。
运维和业务相关指标的图形化的数据仪表盘 (Visualized Dashboards for Operational and Business Metrics)
很多服务厂商需要运维大量的微服务。理解系统的整体性能状况和每一个微服务的运行状况是一项极端复杂的任务。清晰反映系统和服务运行状况的图形化的数据仪表盘对运维人员的工作效率至关重要。仪表盘需要反映系统的整体状况,又可以利用点击深入到具体服务的运行状况。重要报警信息也可以在这里显示和处理。仪表盘数据需要及时更新。仪表盘内容可以由运维人员进行选择和自定义。
快速问题定位 (Fast Issue Isolation)
多数公司需要运维成百上千的微服务。当你的微服务变慢或者系统不能正常工作,快速找到问题的根源变得非常具有挑战性。一个功能的完成可能经过多个服务。一个服务的集群通常会有多个节点。所以一个功能的完成,很有可能是前端调用了服务A(使用了A集群里的A1节点),服务A再调用服务B(使用了B集群里的B2节点),服务B又调用了服务C(使用了C集群里的C3节点)。所以你会有一个类似这样的数据链:Client<->A1<->B2<->C3。云原生的运维需要有工具帮助快速定位问题出现在哪个服务的哪个节点上。
故障的自动恢复 (Automated Recovery from Failure)
云原生的应用需要服务有高可用性。服务不中断。所以当服务失败发生时,如何快速地恢复服务是一个需要解决的问题。服务的错误种类很多,处理方式也不尽相同。高度自动化的服务恢复系统,可以根据不同的服务错误,自动触发相应的处理机制。
自动在线备份和灾难恢复。(Automated Backup and Disaster Recovery)
由于云计算提供的云服务的故障原因,或者是业务服务自己的缺陷,甚至是人为的因素,都有可能导致服务的失败。严重的会导致数据的丢失。云原生运维需要通过在线备份来恢复数据,避免数据的永久丢失。云原生的运维还需要提供方便的数据检验机制,以确认备份和灾难恢复机制是确实在运行正确的。以避免备份貌似工作,实际数据有问题或者恢复环节有问题,在实际需要时发现数据无法从备份恢复。
现网测试和现网探针 (Test in Production/Probe in Production)
即使工程团队力图使测试环境尽量贴近生产环境,完全的一致性是不可能的。当一个服务更新使用灰度部署上线的过程中,应当使用现网的测试能力去确认功能在现网运行如同预期。在服务在现网的运行过程中,除了后台的各种监控机制,还可以提供现网探针的功能,从使用者的视角去监控评估服务的运行状态。
工单系统 (Ticketing System)
现网出现问题后,问题需要有统一的全员可见的系统用来跟踪问题的解决状态。状态更新的通知机制也会使运维更有效率。
多版本部署 (Multiple Versions in Production)
由于微服务的独立性,各服务以自身的节奏向前推进。各种各样的现实情况会导致某个服务需要在现网有多版本的存在。云原生的运维需要支持这样的部署方式。并且需要利用接口路由把调用引导到正确的服务版本的节点。
历史审计 (Audit Trail Information)
由于云原生应用的分布式特点,每一个有一定规模的站点都可能有成千上万的节点组成。每个节点上都会有事件不断的发生。一个详尽并且全面的历史审计系统对整个云应用的管理至关重要。
可测量的服务SLA (Measurable Service Level Agreement)
云原生的应用一定会有可测量的服务SLA。服务运维过程中会产生大量的系统和服务数据。这些数据提供了从多个维度衡量一个服务的客观依据。这个是实现DataOps的基石。
资源记账 (Resource and its Usage Accounting)
云计算的资源的使用效率需要不断优化。这个能力是云计算与传统数据中心相比的一个根本优势。云原生的运维会有效的利用运维数据与相应的工具对这个需求提供支持。
以上是关于云原生的4大支柱的主要内容,如果未能解决你的问题,请参考以下文章