腾讯大牛深入浅出详解云原生
本文介绍目前业界非常火热的“云原生(CloudNative)”相关知识结构,包括微服务、DevOps、持续交付、服务网格、Serverless等相关知识点。“云原生”通过提供一套完整的技术体系和方法论来指导我们在云环境下,在系统功能越来越复杂的情况下,还能够做到敏捷开发并保证系统可用性。
云原生产生背景
随着云计算平台的成熟和分布式框架的普及,应用上云已经是不可逆转的趋势,未来应用会分成两种,一种是“构建云”的,另一种是“基于云构建”的应用。
真正的云化不仅仅是基础设施和平台的变化,应用也需要做出改变,摈弃传统的土方法,在架构设计、开发方式、部署维护等各个阶段和方面都基于云的特点重新设计,从而建设全新的云化的应用,即云原生应用。
在云环境下怎样保证在应用程序越来庞大、功能越来越复杂的情况下,还能够做到敏捷开发并保证可用性呢?云原生有一套完整的体系和方法论。
何谓云原生?
云原生是一种构建和运行应用程序的方法,是一套技术体系和方法论。云原生(CloudNative)是一个组合词,Cloud+Native。
Cloud表示应用程序位于云中,而不是传统的数据中心;
Native表示应用程序从设计之初即考虑到云的环境,原生为云而设计,在云上以最佳姿势运行,充分利用和发挥云平台的弹性+分布式优势。
不同的人和组织对云原生有不同的定义,相同的人和组织在不同时间点对云原生也有不同的定义:
- 2013年,Pivotal公司的Matt Stine首次提出云原生(CloudNative)的概念;
- 2015年,Matt Stine在《迁移到云原生架构》一书中定义了符合云原生架构的几个特征:12因素、微服务、自敏捷架构、基于API协作、扛脆弱性;
- 2017年,Pivotal最新官网对云原生概括为4个要点:DevOps+持续交付+微服务+容器;
- 2018年,CNCF又更新了云原生的定义,把服务网格(Service Mesh)和声明式API给加了进来;
可以简单的理解为:
云原生 = DevOps+持续交付(Continuous Delivery)+微服务(Micro Services)+敏捷基础设施(Agile Infrastructure)+12要素(The Twelve-Factor App)+服务网格(Service Mesh)+声明式API。
云原生不但包括根据业务能力对公司进行文化、组织架构的重组与建设,也包括方法论与原则,还有具体的操作工具。采用基于云原生的技术和管理方法,可以更好地把业务生于“云”或迁移到云平台,从而享受“云”的高效和持续的服务能力。
云原生范畴:
方法论与原则 | 12要素,声明式API |
流程规范 | DevOps,持续交付,自动化测试,Code Review |
软件架构 | 微服务,服务网格,无服务 |
基础设施 | 敏捷基础设施,如K8S、Docker、云服务器、云数据库、云存储等 |
工具集 | Prometheus,Envoy,Jaeger等 |
云原生与传统应用有比较明显的区别,云原生更倡导敏捷、自动化、容错,而传统应用则大多还处于原生的瀑布开发模型和人工运维阶段。
云原生应用和传统应用的区别:
传统应用 | 云原生应用 | |
开发语言 | C/C++、企业级Java编写 | Go、Node.js等新兴语言编写 |
依赖关系 | 单体服务耦合严重 | 微服务化,高内聚,低耦合 |
部署方式 | 对机器、网络资源强绑定 | 容器化,对网络和存储都没有这种限制 |
运维方式 | 人肉部署、手工运维 | 自动化部署,支撑频繁变更,持续交付,蓝绿部署 |
开发模式 | 瀑布式开发 | DevOps、持续集成、敏捷开发 |
扩展性 | 运维手工扩容 | 动态扩缩容 |
可用性 | 故障后可能影响业务 | 无状态,面向失败编程 |
可靠性 | 本地资源,故障率高 | 云资源,可靠性高 |
1. 敏捷基础设施
敏捷的不可变基础设施交付类似于IaaS,用来提供计算网络存储等基础资源,这些资源是可编程且不可变的,直接通过API可以对外提供服务。
开发运维同学可以通过代码或者配置来定义一组基础设施,并通过版本化的管理能够保证业务的快速变更,开发人员可以随时拉取一套基础设施来服务于开发、测试、联调和灰度上线等需求。
最佳实践:docker+kubernetes+云资源(云服务器,云数据库、云存储等)。
kubernetes作为云原生生态的基石,可以说“Kubernetes是云原生时代的Linux”,CNCF整个技术栈都是围绕k8s建立,它不仅是解决了容器的编排问题,更进一步可以说对云原生应用提供了定义规范,通过kubernetes可以很方便的拉取一套基础设施用户开发,测试、发布。
2. 持续交付
为了满足业务需求频繁变动,通过快速迭代,产品能做到随时都能发布的能力,是一系列的开发实践方法。分为持续集成、持续部署、持续发布等阶段,用来确保从需求的提出到设计开发和测试,再到让代码快速、安全地部署到产品环境中。
最佳实践:
CI/CD, Jenkins,流水线pipeline
3. DevOps
DevOps如果从字面上来理解只是Dev(开发人员)+Ops(运维人员),实际上,它是一组过程、方法与系统的统称;
DevOps强调的是如何通过自动化的工具协作和沟通来完成软件的生命周期(开发,测试,运维)管理,从而更快、更频繁地交付更稳定的软件。
最佳实践:Git,Jenkins,Bamboo,Docker,Kubernetes
4. 12要素
“12要素”英文全称是The Twelve-Factor App,最初由Heroku的工程师首次提出并开源,并由众多经验丰富的开发者共同完善。
它定义了一个优雅的互联网应用在设计过程中,需要遵循的一些基本原则,可看做云原生应用开发的“十二条军规”。
那具体有哪十二原则呢,见下图:
1)基准代码
每一个部署的应用都在版本控制代码库中被追踪,一份代码,可部署在多个环境。
在云计算架构中,所有的基础设施都是代码配置,即Infrastructure as Code(IaC),整个应用通过配置文件就可以编排出来,而不再需要手工的干预,做到基础服务也是可以追踪的。
最佳实践:git代码管理
2)依赖
应用程序不会隐式依赖系统级的类库,通过依赖清单声明所有依赖项,应用可以很清晰地对部署环境公开和隔绝依赖性,而不是模糊地对部署环境产生依赖性。
最佳实践:Maven、Go Modules
3)配置
配置与代码分离,代码中不能出现运行时依赖的配置,通过运行时环境获取配置,根据不同的环境配置运行在不同的环境中
最佳实践:配置中心化
4)后端服务
不用区别对待本地或第三方服务,统一把依赖的后端作为一种服务来对待,比如在云架构的基础服务中,计算、网络、存储资源都可以看作是一种服务去对待使用即可,不用区分是远程还是本地的。
最佳实践:API、云函数、serverless
5)构建、发布、运行
应用严格区分构建,发布,运行这三个阶段。举例来说,直接修改处于运行状态的代码是非常不可取的做法,因为这些修改很难再同步回构建步骤。
云原生应用的构建流程可以把发布配置挪到开发阶段,包括实际的代码构建和运行应用所需的生产环境配置。
在云原生应用中,基于容器的Build-Ship-Run和这三个阶段完全吻合,也是Docker对本原则的最佳实践。
最佳实践:Docker
6)进程
进程必须无状态且无共享,即云应用以一个或多个无状态不共享的程序运行。任何必要状态都被服务化到后端服务中(缓存、对象存储等);
所有的应用在设计时就认为随时随地会失败,面向失败而设计,因此进程可能会被随时拉起或消失,特别是在弹性扩容的阶段。
最佳实践:无状态,面向失败设计
7)端口绑定
本身不依赖其他组件(如java依赖tomcat)就能提供网络服务,同时暴露一个监听端口来对外提供服务;
在容器应用中,应用通过暴露端口来服务,尽量避免通过本地文件或进程来通信,每种服务通过服务发现而服务;
最佳实践:微服务架构
8)并发
应用设计要实现能够轻易的水平扩展,通过水平扩展来实现扩容;
在互联网的服务中,业务的爆发性随时可能发生,因此不太可能通过硬件扩容来随时提供扩容服务,需要依赖横向扩展能力进行扩容。
最佳实践:无状态化,水平扩容
9)易处理
应用要能快速启动和优雅终止,更少的启动时间提供了更敏捷的发布以及扩展过程,此外还增加了健壮性,应对快速迭代场景;
此类型的进程所隐含的要求是,任务都应该 可重复执行, 这主要由将结果包装进事务或是使重复操作 幂等 来实现。
在云环境中,由于业务的高低峰值经常需要能实现快速灵活、弹性的伸缩应用,以及不可控的硬件因素等,应用可能随时会发生故障,因此应用在架构设计上需要尽可能无状态,应用能随时随地拉起,也能随时随地销毁,同时保证进程最小启动时间和架构的可弃性,也可以提供更敏捷的发布及扩展过程。
最佳实践:无状态化,热重启,可重入,幂等
10)环境等价
确保环境的一致性,保持研发、测试和生产环境尽可能相似,这样可以提供应用的持续交付和部署服务。
在容器化应用中,通过文件构建的环境运行能做到版本化,因此保证各个不同环境的差异性,同时还能大大减少环境不同带来的排错等成本沟通问题。
最佳实践:docker,devops
11)日志
应用的日志要以流式的方式输出到远程日志服务或者本地stdout,不要写本地文件;
日志是系统运行状态的部分体现,无论在系统诊断、业务跟踪还是后续大数据服务的必要条件中,Docker提供标准的日志服务,用户可以根据需求做自定义的插件开发来处理日志。
最佳实践:日志中心化,filebeat(日志采集),opentracing(调用链),prometheus(监控)
12)管理进程
把后台管理任务当作一次性进程运行;
一些工具类在生产环境上的操作可能是一次性的,因此最好把它们放在生产环境中执行,而不是本地,并且需要把它们像管理应用一样管理起来。例如定时任务,可以通过分布式任务调度平台统一管理。
最佳实践:统一的调度平台
5. 微服务(MicroServices)
随着业务越来越复杂,业务架构也经历了不断变化和演进,每一次演进都是为了解决上一代系统架构的痛点,下图是业务架构演进路线图:
第一代单体架构把所有业务依赖的组件、库全部打包到一个执行程序,业务相互调用,大大增加了系统复杂度,导致系统维护成本高,改动影响大,发布风险高;并且系统完全封闭,内部组件不能共享给其他组件调用,导致产品能力不能共享,大大降低开发效率。
第二代面向服务架构SOA(Service Oriented Architecture)是一种设计方法,其中包含多个服务, 服务之间通过相互依赖最终提供一系列的功能。一个服务通常以独立的形式存在与操作系统进程中,各个服务之间通过网络调用。
第三代微服务架构是在 SOA 上做的升华,微服务架构强调的一个重点是“业务需要彻底的组件化和服务化”,原有的单个业务系统会拆分为多个可以独立开发、设计、运行的小应用。这些小应用之间通过服务完成交互和集成。
SOA架构和微服务架构的区别:
SOA | 微服务 |
应用程序服务的可重用性的最大化 | 专注于解耦 |
系统性的改变需要修改整体 | 系统性的改变是创建一个新的服务 |
DevOps和持续交付正在变得流行,但还不是主流 | 强烈关注DevOps和持续交付 |
专注于业务功能重用 | 更重视“上下文边界”的概念 |
通信使用企业服务总线ESB | 对于通信而言,使用较少精细和简单的消息系统 |
支持多种消息协议 | 使用轻量级协议,例如HTTP,REST或Thrift API |
对部署到它的所有服务使用通用平台 | 应用程序服务器不是真的被使用,通常使用云平台 |
容器(如Docker)的使用不太受欢迎 | 容器在微服务方面效果很好 |
SOA服务共享数据存储 | 每个微服务可以有一个独立的数据存储 |
共同的治理和标准 | 轻松的治理,更加关注团队协作和选择自由 |
微服务架构确实有很多吸引人的地方,然而它的引入也是有成本的,它并不是银弹,使用它会引入更多技术挑战,比如性能延迟、分布式事务、集成测试、故障诊断等方面,企业需要根据业务的不同的阶段进行合理的引入,不能完全为了微服务而“微服务”。
6. 服务网格(Service Mesh)
服务网格(Service Mesh)很多人将之称为下一代微服务,或直接称之为微服务2.0。
微服务1.0时代的主要问题主要包括如下三方面:
- 技术门槛高:开发团队在实施微服务的过程中,除了基础的服务发现、配置中心和鉴权管理之外,团队在服务治理层面面临了诸多的挑战,包括负载均衡、熔断降级、灰度发布、故障切换、分布式跟踪等,这对开发团队提出了非常高的技术要求。
- 多语言支持不足:对于互联网公司,尤其是快速发展的互联网创业公司,多语言的技术栈、跨语言的服务调用也是常态,但目前开源社区上并没有一套统一的、跨语言的微服务技术栈,而跨语言调用恰恰是微服务概念诞生之初的要实现的一个重要特性之一。
- 代码侵入性强:Spring Cloud、Dubbo等主流的微服务框架都对业务代码有一定的侵入性,技术升级替换成本高,导致开发团队配合意愿低,微服务落地困难。
为了解决微服务1.0时代的诸多问题,Service Mesh概念开始走入了开发者的视线中。
介绍Service Mesh概念之前,我们先来了解一下Sidecar。Sidecar是以第一次世界大战时活跃在战场上的军用边斗车命名(也是我们在抗日神剧中最常见的道具之一)。
Sidecar是Service Mesh中的重要组成部分,Sidecar在软件系统架构中特指边斗车模式,这个模式的精髓在于实现了数据面(业务逻辑)和控制面的解耦。
在Service Mesh架构中,非业务功能下层到Sidecar,用户只需要关系业务逻辑,而不用关系服务治理等非业务功能,每个微服务实例部署一个Sidecar Proxy。该Sidecar Proxy负责接管对应服务的入流量和出流量,并将微服务架构中的服务订阅、服务发现、熔断、限流、降级、分布式跟踪等功能从服务中抽离到该Proxy中。
最佳实践:Istio,Envoy
Istio:Service Mesh的开源框架,Istio在逻辑架构上由数据平面和控制平面组成。
Istio提供一种简单的方式来为已部署的服务建立网络,该网络具有负载均衡、服务间认证、监控等功能,而不需要对服务的代码做任何改动。
Envoy:数据层Sidecar,协调服务网格中所有服务的出入站流量,并提供服务发现、负载均衡、限流熔断等能力,还可以收集与流量相关的性能指标。
7. 无服务架构(Serverless)
Serverless被翻译为“无服务架构”,这个概念在2012年时便已经存在,比微服务和Service Mesh的概念出现都要早,但是直到微服务概念大红大紫之后,Serverless才重新又被人们所关注。
Serverless(无服务器架构)并不意味着没有任何服务器去运行代码,Serverless是无需管理服务器,只需要关注代码,而提供者将处理其余部分工作。
对于开发者来说,Serverless架构可以将其服务器端应用程序分解成多个执行不同任务的函数,整个应用分为几个独立、松散耦合的组件,这些组件可以在任何规模上运行。
使用Serverless架构可以免除所有运维性操作,开发人员可以更加专注于核心业务的开发,实现快速上线和迭代,把握业务发展的节奏。Serverless架构可以认为是对微服务和容器化的一种补充,为用户提供了一种新的选择,来应对复杂多变的需求,尤其适合快速发展的初创型公司。
云原生成熟度模型
我们可以通过云原生成熟度模型来衡量我们系统目前所处的阶段,借助于云计算平台,我们可以比较容易把我们的云原生成熟度提高到第三级别。
云原生成熟度模型:
成熟度 | 描述 | 关键技术点 | 效果 |
第一级 |
应用运行在虚拟化环境中; 应用可以通过镜像或者脚本自动化部署; |
负载均衡服 模块化 虚拟化隔离 |
瀑布式开发 系统维护性差 系统可用性严重依赖运维人员 |
第二级 |
微服务架构、服务满足无状态、自治、隔离的条件; 服务根据业务划分等级; 非核心业务可以实现快速降级; 不受服务失败的影响,快速隔离; |
微服务框架 持续交付流水线 调用链分析 分布式配置 自动化测试 监控系统 |
交付周期提升明显 小团队开发,效率提升 对测试人员依赖降低 |
第三级 |
可编程基础设施; 中间件作为后端服务提供; 任何时刻业务无中断; 实现1%-100%的灰度发布流程; 自动扩缩容; 自动化降级; 开发、测试、生产环境统一; 全球化的业务发布能力,异地多活; |
分布式数据库 分布式缓存 分布式消息队列 灰度发布平台 全局容灾方案 全局一致性方案 混沌测试 容器 资源调度平台 |
不需要择时发布 开发人员专注于业务,架构能力由基础设置提供 公共基础服务共享重用 |
第四级 |
系统具有自学习、自诊断、自调整、自恢复能力; 高度可视化、自动化; 实现自动发布(AI选择发布时间)、自动降级、自动回滚; 可根据AI自动调整参数、如超时时间; 所有公共服务形成统一的整体,通过接口实现数据共享; |
人工智能决策 强大的公共基础服务 智能化运维 高度自动化能力 可实现Severless架构 |
AIOps/NoOps 资源利用率极大提升 瞬间扩展能力 强大的可用性 强一致性 |
云原生技术图谱
2015年Google牵头创立云原生计算基金会(www.cncf.io),致力于云原生技术普及和可持续发展,发布了标志性作品k8s,也维护CNCF云原生技术图谱Landscape(https://landscape.cncf.io/images/landscape.png),具体包括:
- 应用定义开发层(App Definition and Development)
- 编排管理(Orchestration & Management)
- 运行环境(Runtime )
- 供应保障(Provisioning)
- 平台管理(Platform)
- 监控分析(Observability and Analysis)
- 无服务(Serverless)
- 合作伙伴(Special)
- 成员构成(Member)
目前,在整个Landscape中按照功能或者模块分为了29个部分,分别归属于9种类型或者称为分层(包括生态中的培训等部分,不是特别严谨),包括当前CNCF在孵化中和已经毕业的22个项目,相关的详细信息如下所示:
序号 | 分层 | 功能模块 | CNCF项目数量 | CNCF项目详细 |
1 | 应用定义与开发 | 数据库 | 2 | TiKV(孵化中)、Vitess(孵化中) |
2 | 应用定义与开发 | 流与消息 | 1 | NATS(孵化中) |
3 | 应用定义与开发 | 应用定义与镜像构建 | 1 | HELM |
4 | 应用定义与开发 | 持续集成与持续交付 | - | - |
5 | 编排管理 | 编排调度 | 1 | Kubernetes(已毕业) |
6 | 编排管理 | 协同与服务发现 | 2 | CoreDNS(已毕业)、etcd(孵化中) |
7 | 编排管理 | RPC远程调用 | 1 | gRPC(孵化中) |
8 | 编排管理 | 服务代理 | 1 | envoy(已毕业) |
9 | 编排管理 | 服务网关 | - | - |
10 | 编排管理 | 服务网格 | 1 | LINKERD(孵化中) |
11 | 运行环境 | 云原生存储 | 1 | ROOK(孵化中) |
12 | 运行环境 | 云原生网络 | 1 | CNI(孵化中) |
13 | 运行环境 | 容器运行环境 | 2 | containerd(已毕业)、cri-o(孵化中) |
14 | 配置管理 | 自动化与配置 | - | - |
15 | 配置管理 | 容器私库 | 1 | HARBOR(孵化中) |
16 | 配置管理 | 安全与合规 | 3 | Notary(孵化中)、Open Policy Agent(孵化中)、TUF(孵化中) |
17 | 配置管理 | 私钥管理 | - | - |
18 | 平台管理 | 通过认证的K8S平台提供商 | - | - |
19 | 平台管理 | 通过认证的K8S托管服务提供商 | - | - |
20 | 平台管理 | 通过认证的K8S安装提供商 | - | - |
21 | 平台管理 | PaaS/容器服务提供商 | - | - |
22 | 监控分析 | 监控 | 1 | Prometheus(已毕业) |
23 | 监控分析 | 日志 | 1 | fluentd(已毕业) |
24 | 监控分析 | 调用链追踪 | 2 | JAEGER(孵化中)、OPENTRACING(孵化中) |
25 | 监控分析 | 混沌工程 | - | - |
26 | 无服务(Serverless) | 0 | - | - |
27 | 合作伙伴(Special) | - | - | - |
28 | 合作伙伴(Special) | - | - | - |
29 | 成员构成 | 0 | - | - |
CNCF的Landscape提供了非常之多的云原生相关的工具、平台与框架进行选择,并给出了大体方向的指引,它提供具体的可供落地实施的工具方法,在企业推行云原生应用落地的时候,应该作为首选参照的内容之一。
总结
云原生是一种构建和运行应用程序的方法,是一套技术体系和方法论,它还包括研发流程规范,软件架构,基础设施和工具集,为我们在基于的云上开发提供了指导思想和最佳实践。
只有按照云原生的技术和管理方法,才能更好地把业务生于“云”或迁移到云平台,从而享受“云”的高效和持续的服务能力。
为了让我们的产品更加符合云原生,我们应该紧跟开源社区,顺势而为,迎合云原生的理念,迎合社区的发展方向。
参考资料:
https://blog.csdn.net/csdnnews/article/details/90093190
https://blog.csdn.net/wufaliang003/article/details/79533345
https://skyao.io/talk/201902-cloudnative-freely-talk/
https://skyao.io/talk/201902-cloudnative-freely-talk2/
https://skyao.io/publication/201902-service-mesh-2018-summary/
https://www.liangzl.com/get-article-detail-4046.html
https://www.jianshu.com/p/e21594c2e9e7
https://www.cnblogs.com/xiao2shiqi/p/11298663.html
https://www.jianshu.com/p/cf4d4258b7f6
http://www.geekpark.net/news/243185
https://blog.csdn.net/liumiaocn/article/details/100713072
https://jimmysong.io/kubernetes-handbook/cloud-native/from-kubernetes-to-cloud-native.html
《持续演进的Cloud Native - 云原生架构下微服务最佳实践》
作者:王珏,腾讯云数据库高级研发工程师,主要负责腾讯云MySQL数据库、数据库中台等研发工作。
文章转自公众号:腾讯云数据库