云原生是什么?

定义

云原生(Cloud Native)这个词汇由来已久,以致于何时出现已无据可考。云原生开始大规模出现在受众视线中,与 Pivotal 提出的云原生应用的理念有着莫大的关系。我们现在谈到云原生,更多的指的是一种文化,而不具象为哪些技术体系。

Pivotal 推出过 Pivotal Cloud Foundry 云原生应用平台和 Spring 开源 Java 开发框架,成为云原生应用架构中先驱者和探路者。Pivotal 是云原生应用平台第一股,2018 年在纽交所上市,2019 年底被 VMWare 以 27 亿美元收购,加入到 VMware 新的产品线 Tanzu

Pivotal 最初的定义

早在 2015 年 Pivotal 公司的 Matt Stine 写了一本叫做 迁移到云原生应用架构 的小册子,其中探讨了云原生应用架构的几个主要特征:

  • 符合 12 因素应用
  • 面向微服务架构
  • 自服务敏捷架构
  • 基于 API 的协作
  • 抗脆弱性

CNCF 最初的定义

到了 2015 年 Google 主导成立了云原生计算基金会(CNCF),起初 CNCF 对云原生(Cloud Native)的定义包含以下三个方面:

  • 应用容器化
  • 面向微服务架构
  • 应用支持容器的编排调度

重定义

到了 2018 年,随着近几年来云原生生态的不断壮大,所有主流云计算供应商都加入了该基金会,且从 Cloud Native Landscape 中可以看出云原生有意蚕食原先非云原生应用的部分。CNCF 基金会中的会员以及容纳的项目越来越多,该定义已经限制了云原生生态的发展,CNCF 为云原生进行了重新定位。

以下是 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)致力于培育和维护一个厂商中立的开源生态系统,来推广云原生技术。我们通过将最前沿的模式民主化,让这些创新为大众所用。

总结

关于什么是云原生的争论还在进行中,究其本质,凡是能够提高云上资源利用率和应用交付效率的行为或方式都是云原生的。云计算的发展史就是一部云原生化的历史。Kubernetes 开启了云原生的序幕,服务网格 Istio 的出现,引领了后 Kubernetes 时代的微服务,serverless 的再次兴起,使得云原生从基础设施层不断向应用架构层挺进,我们正处于一个云原生的新时代。

云原生设计的哲学

云原生一词已经被过度的采用,很多软件都号称是云原生,很多打着云原生旗号的会议也如雨后春笋般涌现。

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

云原生的设计理念

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

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

云原生应用程序如何影响基础设施?

希望你可以知道云原生应用程序与传统应用程序不同。云原生应用程序不能直接在 PaaS 上运行或与服务器的操作系统紧密耦合。它们期望在一个拥有大多数自治系统的动态环境中运行。

云原生基础设施在提供自主应用管理的 IaaS 之上创建了一个平台。该平台建立在动态创建的基础设施之上,以抽象出单个服务器并促进动态资源分配调度。

自动化与自治不一样。自动化使人类对他们所采取的行动产生更大的影响。

云原生是关于不需要人类做出决定的自治系统。它仍然使用自动化,但只有在决定了所需的操作之后。只有在系统不能自动确定正确的事情时才应该通知人。

具有这些特征的应用程序需要一个能够实际监控,收集度量标准并在发生故障时做出反应的平台。云原生应用程序不依赖于人员设置 ping 检查或创建 Syslog 规则。他们需要从选择基本操作系统或软件包管理器的过程中提取自助服务资源,并依靠服务发现和强大的网络通信来提供丰富的功能体验。

Kubernetes 的诞生

众所周知,Kubernetes 是 Google 于 2014 年 6 月基于其内部使用的 Borg 系统开源出来的容器编排调度引擎。其实从 2000 年开始,Google 就开始基于容器研发三个容器管理系统,分别是 Borg、Omega 和 Kubernetes。这篇由 Google 工程师 Brendan Burns、Brian Grant、David Oppenheimer、Eric Brewer 和 John Wilkes 几人在 2016 年发表的《Borg, Omega, and Kubernetes》论文里,阐述了 Google 从 Borg 到 Kubernetes 这个旅程中所获得知识和经验教训。

Borg、Omega 和 Kubernetes

Google 从 2000 年初就开始使用容器(Linux 容器)系统,Google 开发出来的第一个统一的容器管理系统在内部称之为 “Borg”,用来管理长时间运行的生产服务和批处理服务。由于 Borg 的规模、功能的广泛性和超高的稳定性,一直到现在 Borg 在 Google 内部依然是主要的容器管理系统。

Google 的第二套容器管理系统叫做 Omega,作为 Borg 的延伸,它的出现是出于提升 Borg 生态系统软件工程的愿望。Omega 应用到了很多在 Borg 内已经被认证的成功的模式,但是是从头开始来搭建以期更为一致的构架。由于越来越多的应用被开发并运行在 Borg 上,Google 开发了一个广泛的工具和服务的生态系统。它被应用到了很多在 Borg 内已经被认证的成功的模式,但是是从头开始来搭建以期更为一致的构架。这些系统提供了配置和更新 job 的机制,能够预测资源需求,动态地对在运行中的程序推送配置文件、服务发现、负载均衡、自动扩容、机器生命周期管理、额度管理等。许多 Omega 的创新(包括多个调度器)都被收录进了 Borg。

Google 的第三套容器管理系统就是我们所熟知的 Kubernetes,它是针对在 Google 外部的对 Linux 容器感兴趣的开发者以及 Google 在公有云底层商业增长的考虑而研发的。和 Borg、Omega 完全是谷歌内部系统相比,Kubernetes 是开源的。像 Omega 一样,Kubernetes 在其核心有一个被分享的持久存储,有组件来检测相关 object 的变化。跟 Omega 不同的是,Omega 把存储直接暴露给信任的控制平面的组件,而在 Kubernete 中,提供了完全由特定领域更高层面的版本控制、认证、语义、策略的 REST API 接口,以服务更多的用户。更重要的是,Kubernetes 是由一群底层开发能力更强的开发者开发的,他们主要的设计目标是用更容易的方法去部署和管理复杂的分布式系统,同时仍能从容器提升的效率中受益。

2014 年 Kubernetes 正式开源,2015 年被作为初创项目贡献给了云原生计算基金会(CNCF),从此开启了 Kubernetes 及云原生化的大潮。

Kubernetes 与云原生应用概览

2017 年 9 月,Mesos 宣布支持 Kubernetes,而在 2017 年 10 月份的 DockerCon EU 上,Docker 公司宣布官方同时支持 Swarm 和 Kubernetes 容器编排,Kubernetes 已然成为容器编排调度的标准。

从云计算到微服务再到云原生计算

云计算介绍

云计算包含的内容十分繁杂,也有很多技术和公司牵强附会说自己是云计算公司,说自己是做云的,实际上可能风马牛不相及。说白了,云计算就是一种配置资源的方式,根据资源配置方式的不同我们可以把云计算从宏观上分为以下三种类型:

  • IaaS:这是为了想要建立自己的商业模式并进行自定义的客户,例如亚马逊的 EC2、S3 存储、Rackspace 虚拟机等都是 IaaS。
  • PaaS:工具和服务的集合,对于想用它来构建自己的应用程序或者想快速得将应用程序部署到生产环境而不必关心底层硬件的用户和开发者来说是特别有用的,比如 Cloud Foundry、Google App Engine、Heroku 等。
  • SaaS:终端用户可以直接使用的应用程序。这个就太多,我们生活中用到的很多软件都是 SaaS 服务,只要基于互联网来提供的服务基本都是 SaaS 服务,有的服务是免费的,比如 Google Docs,还有更多的是根据我们购买的 Plan 和使用量付费,比如 GitHub、各种云存储。

微服务介绍

微服务(Microservices)是一种分布式架构设计理念,为了推动细粒度服务的使用,这些服务要能协同工作,每个服务都有自己的生命周期。一个微服务就是一个独立的实体,可以独立的部署在 PAAS 平台上,也可以作为一个独立的进程在主机中运行。服务之间通过 API 访问,修改一个服务不会影响其它服务。

下文中会谈到 Kubernetes 与微服务的关系,其中 Kubernetes 的 service 天生就适合于微服务。

云原生概念介绍

下面是云原生概念思维导图:

云原生准确来说是一种文化,更是一种潮流,它是云计算的一个必然导向。它的意义在于让云成为云化战略成功的基石,而不是阻碍,如果业务应用上云之后开发和运维人员比原先还痛苦,成本还高的话,这样的云我们宁愿不上。

自从云的概念开始普及,许多公司都部署了实施云化的策略,纷纷搭建起云平台,希望完成传统应用到云端的迁移。但是这个过程中会遇到一些技术难题,上云以后,效率并没有变得更高,故障也没有迅速定位。

为了解决传统应用升级缓慢、架构臃肿、不能快速迭代、故障不能快速定位、问题无法快速解决等问题,云原生这一概念横空出世。云原生可以改进应用开发的效率,改变企业的组织结构,甚至会在文化层面上直接影响一个公司的决策。

另外,云原生也很好地解释了云上运行的应用应该具备什么样的架构特性 —— 敏捷性、可扩展性、故障可恢复性。

综上所述,云原生应用应该具备以下几个关键词:

  • 敏捷
  • 可靠
  • 高弹性
  • 易扩展
  • 故障隔离保护
  • 不中断业务持续更新

以上特性也是云原生区别于传统云应用的优势特点。

从宏观概念上讲,云原生是不同思想的集合,集目前各种热门技术之大成。

Kubernetes 与云原生的关系

Kuberentes 可以说是乘着 Docker 和微服务的东风,一经推出便迅速蹿红,它的很多设计思想都契合了微服务和云原生应用的设计法则,这其中最著名的就是开发了 Heroku PaaS 平台的工程师们总结的 Twelve-factor App 了。

下面将讲解 Kubernetes 设计时是如何按照了十二因素应用法则,并给出 Kubernetes 中的应用示例,并附上一句话简短的介绍。

Kubernetes 介绍

Kubernetes 是 Google 基于 Borg 开源的容器编排调度引擎,作为 CNCF(Cloud Native Computing Foundation)最重要的组件之一,它的目标不仅仅是一个编排系统,而是提供一个规范,可以让你来描述集群的架构,定义服务的最终状态,Kubernetes 可以帮你将系统自动得达到和维持在这个状态。

更直白的说,Kubernetes 用户可以通过编写一个 YAML 或者 json 格式的配置文件,也可以通过工具 / 代码生成或直接请求 Kubernetes API 创建应用,该配置文件中包含了用户想要应用程序保持的状态,不论整个 Kubernetes 集群中的个别主机发生什么问题,都不会影响应用程序的状态,你还可以通过改变该配置文件或请求 Kubernetes API 来改变应用程序的状态。

12 因素应用

1. 基准代码

每个代码仓库(repo)都生成 docker image 保存到镜像仓库中,并使用唯一的 ID 管理,在 Jenkins 中使用编译时的 ID。

2. 依赖

显式的声明代码中的依赖,使用软件包管理工具声明,比如 Go 中的 Glide。

3. 配置

将配置与代码分离,应用部署到 Kubernetes 中可以使用容器的环境变量或 ConfigMap 挂载到容器中。

4. 后端服务

把后端服务当作附加资源,实质上是计算存储分离和降低服务耦合,分解单体应用。

5. 构建、发布、运行

严格分离构建和运行,每次修改代码生成新的镜像,重新发布,不能直接修改运行时的代码和配置。

6. 进程

应用程序进程应该是无状态的,这意味着再次重启后还可以计算出原先的状态。

7. 端口绑定

在 Kubernetes 中每个 Pod 都有独立的 IP,每个运行在 Pod 中的应用不必关心端口是否重复,只需在 service 中指定端口,集群内的 service 通过配置互相发现。

8. 并发

每个容器都是一个进程,通过增加容器的副本数实现并发。

9. 易处理

快速启动和优雅终止可最大化健壮性,Kuberentes 优秀的 Pod 生存周期控制。

10. 开发环境与线上环境等价

在 Kubernetes 中可以创建多个 namespace,使用相同的镜像可以很方便的复制一套环境出来,镜像的使用可以很方便的部署一个后端服务。

11. 日志

把日志当作事件流,使用 stdout 输出并收集汇聚起来,例如到 ES 中统一查看。

12. 管理进程

后台管理任务当作一次性进程运行,kubectl exec 进入容器内部操作。

另外,Cloud Native Go 这本书的作者,CapitalOne 公司的 Kevin Hoffman 在 TalkingData T11 峰会上的 High Level Cloud Native 的演讲中讲述了云原生应用的 15 个因素,在原先的 12 因素应用的基础上又增加了如下三个因素:

API 优先

  • 服务间的合约
  • 团队协作的规约
  • 文档化、规范化
  • RESTful 或 RPC

监控

  • 实时监控远程应用
  • 应用性能监控(APM)
  • 应用健康监控
  • 系统日志
  • 不建议在线 Debug

认证授权

  • 不要等最后才去考虑应用的安全性
  • 详细设计、明确声明、文档化
  • Bearer token、OAuth、OIDC 认证
  • 操作审计

Kubernetes 中的资源管理与容器设计模式

Kubernetes 通过声明式配置,真正让开发人员能够理解应用的状态,并通过同一份配置可以立马启动一个一模一样的环境,大大提高了应用开发和部署的效率,其中 Kubernetes 设计的多种资源类型可以帮助我们定义应用的运行状态,并使用资源配置来细粒度的明确限制应用的资源使用。

服务发现与负载均衡

Kubernetes 在设计之初就充分考虑了针对容器的服务发现与负载均衡机制,提供了 Service 资源,并通过 kube-proxy 配合 cloud provider 来适应不同的应用场景。随着 Kubernetes 用户的激增,用户场景的不断丰富,又产生了一些新的负载均衡机制。目前,Kubernetes 中的负载均衡大致可以分为以下几种机制,每种机制都有其特定的应用场景:

  • Service:直接用 Service 提供 cluster 内部的负载均衡,并借助 cloud provider 提供的 LB 提供外部访问
  • Ingress:还是用 Service 提供 cluster 内部的负载均衡,但是通过自定义 LB 提供外部访问
  • Service Load Balancer:把 load balancer 直接跑在容器中,实现 Bare Metal 的 Service Load Balancer
  • Custom Load Balancer:自定义负载均衡,并替代 kube-proxy,一般在物理部署 Kubernetes 时使用,方便接入公司已有的外部服务

持续集成与发布

应用构建和发布流程说明:

  1. 用户向 Gitlab 提交代码,代码中必须包含 Dockerfile
  2. 将代码提交到远程仓库
  3. 用户在发布应用时需要填写 git 仓库地址和分支、服务类型、服务名称、资源数量、实例个数,确定后触发 Jenkins 自动构建
  4. Jenkins 的 CI 流水线自动编译代码并打包成 Docker 镜像推送到 Harbor 镜像仓库
  5. Jenkins 的 CI 流水线中包括了自定义脚本,根据我们已准备好的 Kubernetes 的 YAML 模板,将其中的变量替换成用户输入的选项
  6. 生成应用的 Kubernetes YAML 配置文件
  7. 更新 Ingress 的配置,根据新部署的应用的名称,在 Ingress 的配置文件中增加一条路由信息
  8. 更新 PowerDNS,向其中插入一条 DNS 记录,IP 地址是边缘节点的 IP 地址。关于边缘节点,请查看 边缘节点配置
  9. Jenkins 调用 Kubernetes 的 API,部署应用

日志收集与监控

基于现有的 ELK 日志收集方案,稍作改造,选用 filebeat 来收集日志,可以作为 sidecar 的形式跟应用运行在同一个 Pod 中,比较轻量级消耗资源比较少。

安全性与权限管理

Kubernetes 是一个多租户的云平台,因此必须对用户的权限加以限制,对用户空间进行隔离。Kubernetes 中的隔离主要包括这几种:

  • 网络隔离:需要使用网络插件,比如 flannel, calico
  • 资源隔离:kubernetes 原生支持资源隔离,pod 就是资源隔离和调度的最小单位,同时使用 namespace 限制用户空间和资源限额。
  • 身份隔离:使用 RBAC - 基于角色的访问控制,多租户的身份认证和权限控制。

为什么使用 Kubernetes

容器最初是通过开发者工具而流行,可以使用它来做隔离的开发测试环境和持续集成环境,这些都是因为容器轻量级,易于配置和使用带来的优势,docker 和 docker-compose 这样的工具极大的方便的了应用开发环境的搭建,开发者就像是化学家一样在其中小心翼翼的进行各种调试和开发。

Kubernetes—— 让容器应用进入大规模工业生产。

Kubernetes 是容器编排系统的事实标准

在单机上运行容器,无法发挥它的最大效能,只有形成集群,才能最大程度发挥容器的良好隔离、资源分配与编排管理的优势,而对于容器的编排管理,Swarm、Mesos 和 Kubernetes 的大战已经基本宣告结束,Kubernetes 成为了无可争议的赢家。

下面这张图是 Kubernetes 的架构图,其中显示了组件之间交互的接口 CNI、CRI、OCI 等,这些将 Kubernetes 与某款具体产品解耦,给用户最大的定制程度,使得 Kubernetes 有机会成为跨云的真正的云原生应用的操作系统。

Kubernetes构建云原生架构:

参考

https://cloudnative.to/

https://jimmysong.io/awesome-cloud-native/

posted @ 2022-02-14 18:04  Ricardo_ML  阅读(511)  评论(0编辑  收藏  举报