在学习K8S的时候,提到了一个概念,云原生,什么是云原生呢?英文介绍如下:
- 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 API exemplify this approach.
- 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.
上面一大堆英文,提到了应用在云上的弹性伸缩,有助于实现云原生的方法,便于管理监控和观察,自动化部署。看着是不是稍微有点晕?下面使用中文介绍针对云原生应用开发的最佳实践原则,12-Factor。
12-Factor 全称叫 TheTwelve-Factor App,由Heroku创始人AdamWiggins首次提出并开源。它定义了一个优雅的互联网应用在设计过程中,需要遵循的一些基本原则。
1.基准代码:一份基准代码(Codebase),多份部署(deploy)。
基准代码和应用之间总是保持一一对应的关系,一份代码可以部署在开发环境、测试环境、预发环境及产线环境。
多个应用共享一份基准代码是有悖于12-Factor原则的。解决方案如下:
将共享的代码拆分为独立的类库,然后使用依赖管理策略去加载它们。所有部署的基准代码相同,但每份部署可以使用其不同的版本。比如,开发人员可能有一些提交还没有同步至预发布环境;预发布环境也有一些提交没有同步至生产环境。但它们都共享一份基准代码,我们就认为它们只是相同应用的不同部署而已。
2.依赖——显式声明依赖关系(dependency)
12-Factor规则下的应用程序不会隐式依赖系统级的类库。它一定通过依赖清单,确切地声明所有依赖项。大多数编程语言都会提供一个打包系统,比如java使用maven,应用依赖了哪些第三方库,要显示地定义在POM文件里。
3.配置:在环境中存储配置
配置要和代码完全分离,环境变量可以非常方便地在不同的部署间做修改,却不动一行代码。
配置主要包括数据库信息,缓存信息,第三方服务证书,每份部署特有的配置,如域名等信息。
判断一个应用是否正确地将配置排除在代码之外,一个简单的方法,看该应用的基准代码是否可以立刻开源,而不用担心会暴露任何敏感的信息。
4.后端服务:把后端服务当作附加资源(backing services)
后端服务是指程序运行所需要的通过网络调用的各种服务,如数据库,消息系统及缓存系统。
12-Factor应用的任意部署,都应该可以在不进行任何代码改动的情况下,进行后端服务的切换,比如将本地MySQL数据库换成第三方服务(例如阿里云的 RDS)。另外,部署可以按需加载或卸载资源。例如,如果应用的数据库服务由于硬件问题出现异常,管理员可以从最近的备份中恢复一个数据库,卸载当前的数据库,然后加载新的数据库 。整个过程都不需要修改代码。
5.构建->发布->运行:严格分离构建和运行
基准代码 转化为一份部署(非开发环境)需要以下三个阶段:
(1)构建阶段,将代码仓库转化为可执行包的过程。构建时会使用指定版本的代码,获取和打包依赖项,编译成二进制文件和资源文件。
(2)发布阶段,将构建的结果和当前部署所需配置相结合,并能够立刻在运行环境中投入使用。
(3)运行阶段(“运行时”),针对选定的发布版本,在执行环境中启动一系列应用程序进程。
每一个发布版本必须对应一个唯一的发布 ID,一旦发布就不可修改,任何的变动都应该产生一个新的发布版本。另外,发布管理工具需要能方便的回退至较旧的发布版本。
6.进程:以一个或多个无状态进程运行应用
运行环境中,应用程序通常是以一个和多个进程运行的。12-Factor应用的进程必须无状态且无共享,任何需要持久化的数据都要存储在后端服务内,比如数据库或缓存。
7.端口绑定:通过端口绑定提供服务
12-Factor应用完全自我加载,而不依赖于任何网络服务器就可以创建一个面向网络的服务。互联网应用通过端口绑定来提供服务,并监听发送至该端口的请求。比如,在线上环境中,请求统一发送至公共域名,然后路由至绑定了端口的网络进程。
8.并发:通过进程模型进行扩展
在 12-factor 应用中,进程是一等公民。12-Factor 应用的进程主要借鉴于 unix 守护进程模型 。开发人员可以运用这个模型去设计应用架构,将不同的工作分配给不同的进程类型。例如,HTTP 请求可以交给web进程来处理,而常驻的后台工作则交由 worker进程负责。
9.易处理:快速启动和优雅终止可最大化健壮性
12-Factor应用的进程是易处理的,即它们可以瞬间开启或停止。这有利于快速、弹性的伸缩应用,迅速部署变化的代码或配置,稳健的部署应用。
进程应当追求最小启动时间,并且一旦接收到终止信号(SIGTERM),可以优雅的终止。进程还应当在面对突然死亡时保持健壮,例如底层硬件故障。无论如何,12-Factor应用都应该可以设计能够应对意外的、不优雅的终结。
10.开发环境与线上环境等价:尽可能的保持开发,预发布,线上环境相同
12-Factor 应用的开发人员应该避免在不同环境间使用不同的后端服务,即使适配器已经可以几乎消除使用上的差异。这是因为,不同的后端服务意味着会突然出现的不兼容,从而导致测试、预发布都正常的代码在线上出现问题。这些错误会给持续部署带来阻力。从应用程序的生命周期来看,消除这种阻力需要花费很大的代价。
11.日志:把日志当作事件流
12-factor应用本身从不考虑存储自己的输出流。 不应该试图去写或者管理日志文件。相反,每一个运行的进程都会直接的标准输出(stdout)事件流。开发环境中,开发人员可以通过这些数据流,实时在终端看到应用的活动。
12.管理进程:后台管理任务当作一次性进程运行
一次性管理进程主要指一些管理或维护应用的一次性任务,比如,运行数据迁移,运行一些提交到代码仓库的一次性脚本等。它们应该和正常的常驻进程使用同样的环境。这些管理进程和任何其他的进程一样使用相同的代码和配置,基于某个发布版本运行。后台管理代码应该随其他应用程序代码一起发布,从而避免同步问题。
以上了解了12-Factor应用原则。在学习K8S的过程中,个人认为K8S结合service mesh很好的满足了上面的每条原则。设计K8S和service mesh的人很伟大,提出12原则的AdamWiggins很伟大。
参考文档:
https://blog.csdn.net/weiwoyonzhe/article/details/88611362
https://blog.csdn.net/wufaliang003/article/details/79533345