页面加载中...

云原生的理解

| 云原生 | 1 条评论 | 740浏览

云原生的背景

云原生(Cloud Native)这个词汇由来已久,以致于何时出现已无据可考。云原生开始大规模出现在受众视线中,与 Pivotal 提出的云原生应用的理念有着莫大的关系。Pivotal 推出过 Pivotal Cloud Foundry 云原生应用平台和 Spring 开源 Java 开发框架,成为云原生应用架构中先驱者和探路者。

2015 年 Google 主导成立了云原生计算基金会(CNCF)。随着近几年来云原生生态的不断壮大,所有主流云计算供应商都加入了该基金会。

关于CNCF:

云原生计算基金会(CNCF)致力于培育和维护一个厂商中立的开源生态系统,来推广云原生技术。我们通过将最前沿的模式民主化,让这些创新为大众所用。

Kubernetes 开启了云原生 1.0 的序幕,服务网格 Istio 的出现,引领了后 Kubernetes 时代的微服务,serverless 的再次兴起,使得云原生从基础设施层不断向应用架构层挺进,我们正处于一个云原生 2.0 的新时代。

—— Jimmy Song

云原生的定义

CNCF最初对云原生给出的定义是:

  • 应用容器化
  • 面向微服务架构
  • 容器可以动态编排调度

最新的定义(中英对照):

Cloud native technologies empower organizations to build and run scalable applications in modern, dynamic environments such as public, private, and hybrid clouds. Containers, service meshes, microservices, immutable infrastructure, and declarative APIs exemplify this approach.

云原生技术有利于各组织在公有云、私有云和混合云等新型动态环境中,构建和运行可弹性扩展的应用。云原生的代表技术包括容器、服务网格、微服务、不可变基础设施和声明式 API。

These techniques enable loosely coupled systems that are resilient, manageable, and observable. Combined with robust automation, they allow engineers to make high-impact changes frequently and predictably with minimal toil.

这些技术能够构建容错性好、易于管理和便于观察的松耦合系统。结合可靠的自动化手段,云原生技术使工程师能够轻松地对系统作出频繁和可预测的重大变更。

The Cloud Native Computing Foundation seeks to drive adoption of this paradigm by fostering and sustaining an ecosystem of open source, vendor-neutral projects. We democratize state-of-the-art patterns to make these innovations accessible for everyone.

云原生计算基金会(CNCF)致力于培育和维护一个厂商中立的开源生态系统,来推广云原生技术。我们通过将最前沿的模式民主化,让这些创新为大众所用。

可以认为:云原生是一种行为方式和设计理念,究其本质,凡是能够提高云上资源利用率和应用交付效率的行为或方式都是云原生的。

云原生应用

如同云改变了业务和基础设施之间的关系一样,云原生应用程序也改变了应用程序和基础设施之间的关系。

云原生本身甚至不能称为是一种架构,它首先是一种基础设施,运行在其上的应用称作云原生应用,只有符合云原生设计哲学的应用架构才叫云原生应用架构。

  • 容器化:作为应用包装的载体
  • 持续交付:利用容器的轻便的特性,构建持续集成和持续发布的流水线
  • DevOps:开发与运维之间的协同,上升到一种文化的层次,能够让应用快速的部署和发布
  • 微服务:这是应用开发的一种理念,将单体应用拆分为微服务才能更好的实现云原生,才能独立的部署、扩展和更新

一句话解释什么是云原生应用:云原生应用就是为了在云上运行而开发的应用。

云原生的设计哲学

云原生本身甚至不能称为是一种架构,它首先是一种基础设施,运行在其上的应用称作云原生应用,只有符合云原生设计哲学的应用架构才叫云原生应用架构。

云原生系统的设计理念如下:

  • 面向分布式设计(Distribution):容器、微服务、API 驱动的开发;
  • 面向配置设计(Configuration):一个镜像,多个环境配置;
  • 面向韧性设计(Resistancy):故障容忍和自愈;
  • 面向弹性设计(Elasticity):弹性扩展和对环境变化(负载)做出响应;
  • 面向交付设计(Delivery):自动拉起,缩短交付时间;
  • 面向性能设计(Performance):响应式,并发和资源高效利用;
  • 面向自动化设计(Automation):自动化的 DevOps;
  • 面向诊断性设计(Diagnosability):集群级别的日志、metric 和追踪;
  • 面向安全性设计(Security):安全端点、API Gateway、端到端加密;

上述的设计理念比较多,但是我们仍然无法辨认什么样的设施才是云原生基础设施,不过可以先用排除法,可以现看看什么不是云原生基础设施:

  • 云原生基础设施不等于在公有云上运行的基础设施:光是租用服务器并不会使您的基础设施云原生化。管理 IaaS 的流程与运维物理数据中心没什么两样,将现有架构迁移到云上也未必能获得回报
  • 云原生不是指在容器中运行应用程序:除了把代码打包部署在容器中,还有很多事情需要做,比如容器编排、调度、健康检查以及自动化等等;
  • 云原生不是微服务或基础设施即代码:微服务意味着更快的开发周期和更小的独特功能,但是单体应用程序可以具有相同的功能,使其能够通过软件有效管理,并且还可以从云原生基础设施中受益。

云原生技术的"三架马车"

  1. 容器化
  2. 服务网格
  3. 无服务器

容器化

容器化是指将软件代码和所需的所有组件(例如库、框架和其他依赖项)打包在一起,让它们隔离在自己的"容器"中。

容器

容器是继虚拟机之后更高层次的抽象,在这层抽象中,整个应用程序的每个组件被单独打包成一个个独立的单元,这个单元就是所谓的容器。

通过这种方式,可以将代码和应用服务从底层架构中分离出来,实现了完全的可移植性(在任何操作系统或环境上运行应用的能力)。

Docker开源于 2013 年, 是最常用的容器化工具,也是最流行的容器运行时。用于打包和创建容器,管理基于容器的应用。

Kubernetes

image-20211019104901198

要运行这样的应用必须有一个操作系统,就像我们运行PC或手机应用一样,而Kubernetes就是一个这样的操作系统。

Kubernetes 是 Google 于 2014 年 6 月基于其内部使用的 Borg 系统开源出来的容器编排调度引擎,Kubernetes 的目标不仅仅是一个编排系统,而是提供一个规范用以描述集群的架构,定义服务的最终状态,使系统自动地达到和维持该状态。Kubernetes 作为云原生应用的基石,相当于一个云原生操作系统,其重要性不言而喻。

服务网格

服务网格用于管理服务之间的网络流量,是云原生的网络基础设施层,也是 Kubernetes 次世代的云原生应用 的重要组成部分。服务网格利用容器之间的网络设置来控制或改变应用程序中不同组件之间的交互。

比如你想测试 Nginx 的新版本,检查它是否与你的 Web 应用兼容。你用新的 Nginx 版本创建了一个新的容器 (Container2),并从当前容器 (Container1) 中复制了当前的 Nginx webserver 配置。但你不想影响组成 web 应用的其他微服务(假设每个容器对应一个单独的微服务)—— 就是 MySQL 数据库、Node.js 前端、负载均衡器等。

所以使用服务网格,你可以立即只把 webserver 微服务改成 Container2(新 Nginx 版本的那个)进行测试。如果确定它不能工作,比如因为它导致网站出现一些兼容性问题,那么你就调用服务网格来快速切换回原来的 Container1。而这一切都不需要对其他容器进行任何配置变更 —— 这些变更对其他容器是完全透明的

如果没有服务网格,对容器来说这项工作将十分繁琐,因为这涉及到逐一更改所有其他容器上的配置,将它们所包含的服务从 Container1 指向 Container2,然后在测试失败后,将它们全部改回来。

Serverless

Serverless(无服务器架构)指的是由开发者实现的服务端逻辑运行在无状态的计算容器中,它由事件触发, 完全被第三方管理,其业务层面的状态则被开发者使用的数据库和存储资源所记录。

image-20211019164901570

Serverless与云原生的关系

Serverless 是云原生技术发展的高级阶段,使开发者更聚焦在业务逻辑,而减少对基础架构的关注。

在逻辑层面上:Serverless架构是云原生的自然延伸;

在物理层面上:Serverless是构建在容器之上的一层,与应用本身的关系更加密切。

image-20211019165110499

附录

云原生时代下的12因素(12 factor)应用原则

  1. 基准代码

开发中我们使用的git等版本管理工具,保留一份用于追钟代码修改的代码基准,基准代码于应用之间是一一对应,多个基准代码不能称为一个应用。如果多个应用共享一个基准代码的时候,考虑用共享独立的库。对于共享一份基准代码,我们在部署的时候仍可以借助于分支的方式进行多版本的部署,比如开发版本和测试版本的部署。

  1. 依赖

使用依赖的时候,一定要隔离系统的依赖,通过建立虚拟环境并建立完整的依赖声明清单来进行依赖的隔离。依赖声明和依赖隔离必须一起使用,否则不满足于12因素规范。也不要调用一些系统工具比如curl或者imageMagick.

  1. 配置

在环境中存储配置,不同的部署可能都会涉及不同的配置差异,比如缓存,数据库的配置等等。代码和配置需要严格的分离,判断基准代码是否可以立刻开源, 如果可以则代表其配置排除在代码之外。另外推荐在环境变量中存储配置,这样可以在部署的时候声明部署环境变量,代码不需要任何的改动。如果使用组合的方式比如,production,test和development 来定义不同的配置文件,则可能导致组合的固定,不灵活。

  1. 后端服务

后端服务指的是运行所需要的网络调用的各种服务,比如数据库,缓存系统或者邮件系统 ,甚至是调用的第三方发布和管理的服务。可以把这些都作为资源,这些资源的管理尽量不要修改任何的代码,比如把本地的mysql换成一些第三方的服务。另外资源及部署也要保持一个松散耦合,增加可扩展性。

  1. 构建,发布和运行

严格区分构建,发布和运行三个步骤,比如不允许直接修改运行状态的代码,每一个发布版本都需要对应一个唯一的发布ID,一旦发布就不能更改,任何的变动都需要产生一个新的发布版本。构建阶段一般需要人为参与,发现问题能够及时的追踪和定位,而发布和运行则应该保持一个自动化的过程,减少操作的失误。

  1. 进程

应用进程保持无状态和无共享,任何需要持久化的数据都需要存储在后端服务内。一些系统依赖于粘性session,指将用户session中的数据缓存在某些进程的内存中,并将同一个用户的后续请求路由到同一个进程,这种方式是在12因素中极力反对的,session中的数据应该保持在redis或者memcached中,并设置过期时间。

  1. 端口绑定

12因素要求应用完全自我加载,而不依赖于任何网络服务器就可以创建一个面向网络的服务。比如http://localhost:5000/ 访问应用,一个应用可以将另外一个应用作为后端服务,建立起微服务的框架结构。

  1. 并发

在12因素的应用设计中,进程为一等公民。web进程和后台进程(交由worker进程)分别负责不同职责,应用的进程具备无共享,水平分区的特性保证了并发的简单和稳妥。应用的进程不需要守护进程或者其他方式,一般借助于进程管理器比如systemd或者分布式的进程管理方式来管理进程和请求。

  1. 易处理

快速启动和优雅终止,易于处理保证了瞬间的开启和停止,进程应该追求最小启动时间,保证更小的启动时间和更敏捷的发布扩展。 一旦程序接收到终止信号,就可以保证程序的优雅终止。对于worker的终止,应该将未完成的任务退回到队列中,并且在系统故障的时候能够处理,保持程序的健壮性。比如beanstalkd.

  1. 开发环境和线上环境等价

缩小与线上环境的差异。减少差异也就会减少了部署的间隔,开发人员和运维人员也可以共享知识,甚至可以是相同的人。使用一些适配器来完成不同的后端服务的聚合,比如使用ActiveRecord来适配MySQL和SQLite,Celery来适配队列。但是适配仍旧由一定的差异,可能导致运行时候的兼容性,所以尽量使用docker或者vagrant来部署在本地开发

  1. 日志

使用一些开源工具自动的去处理日志事件流,并统一存储在Hapdoop或者hive这样的通用数据存储系统中,便于后期的查询和过滤,另外通过可视化的方式将一些数据展示在前端更直观一些,并设置一些告警门限,自动触发告警操作。

  1. 管理进程

一次性执行的进程和常驻进程应该使用同样的环境和配置以及程序代码。这样在执行的时候可以很方便的管理进程的状态和执行一些操作,比如数据库的迁移和状态监测。

参考资料

发表评论

最新评论

  1. Jovian

    Cloud Native go!