2015 年,Google 牵头创立了 CNCF(Cloud Native Computing Foundation),同年,CNCF 发布了其标志性作品——Kubernetes 1.0。由此,围绕 CNCF 又产生了许多很有价值的云原生项 目。CNCF 独立维护了一个全景图项目,该项目发布非常频繁,截止到本书写作时,其最新版 本是 0.9.9。大家可以在 GitHub 上查看相关内容。
如图所示,在 CNCF 全景图中,云原生的生态圈在横切面上被划分为五层,同时在纵 切面上又规划出两部分作为共用层。五层分别是应用定义与开发层、编排与治理层、运行时层、 供应保障层和云设施层。另外两部分是观察与分析、平台。将这些功能整合起来就是一个完善 的云平台服务产品。
图中所含信息量巨大,无法看清细节,下面我们就层层递进地来仔细解读一下 CNCF 全景图。首先来看看横切面五层中每层涵盖的内容。
应用定义与开发层
应用定义与开发层中的内容对于有经验的技术人员来说是比较熟悉的。无论是否要开发基于云原生的应用,这些内容都是开发和运维的基础,与传统开发模式并无二致。
应用定义与开发层包括数据库与数据分析、流式处理、软件配置管理、应用定义以及持续 集成/持续交付,下面分别来看。
1.数据库与数据分析
图 1-15 展示了 CNCF 应用定义与开发层中数据库与数据分析部分的内容。
这部分主要包括数据库与大数据分析工具,涉及关系型数据库、NoSQL、NewSQL、数据库中间层以及大数据处理方案。
基于 SQL 操作的关系型数据库主要包括 Oracle、SQL Server、MySQL、PostgreSQL、DB2、 MariaDB 等。虽然各种新型数据库层出不穷,但关系型数据库的存储引擎毕竟经历了数十年的 打磨,又有经典的 ACID 事务模型作为支撑,因此它作为核心数据存储选型的地位不可撼动。 针对关键业务,大部分企业依然倾向于采用关系型数据库进行存储,如存储交易数据、订单信 息等。数据库本身的稳定性、SQL 的查询灵活度、开发工程师的熟悉程度以及数据库管理员的 专业度等,共同形成了关系型数据库的强大生态圈,使得关系型数据库始终是格式化数据存储 行业最优先的选择。
作为关系型数据库的有效补充,NoSQL 数据库在数据存储领域也占据重要地位,常用的有 MongoDB、Couchbase、Redis、Cassandra、HBase、Neo4j 等。面向文档、面向列簇、面向 Key-Value、 面向图等的 NoSQL 数据库在数据的分布式处理方面表现得更加优秀,编程模型也更加贴近面 向对象原有的方式,虽然查询的灵活度远不如 SQL,但在特定场景中的性能、对面向对象的原 生存储能力、无 Schema 模式等方面都做得很不错,因此在适合的业务场景下,NoSQL 数据库 也大有用武之地。比如,将 Redis 当作缓存,将 Neo4j 当作关系分析的数据库,将 MongoDB 当 作存储 Schema 易变型数据的数据库,这些都是很常见的使用方式。
NewSQL 数据库目前是新一代数据库的焦点,是颠覆关系型数据库统治地位的有力竞争者。它在兼容 SQL 的同时,更加擅长分布式处理。其中的优秀代表是 PingCAP 开源的 TiDB。
TiDB 采用 Key-Value 存储引擎,采用不同于 ACID 的强一致分布式事务,可动态平滑地进 行数据迁移,自动水平伸缩,也可以在线修改 Schema,进行索引变更,是完整的数据存储方案。 但新的存储引擎的成熟度毕竟还需要时间来检验,而且“无须专业数据库管理员运维”的理念 也需要时间来让更多的企业接受。因此,愿意尝试的公司仍然秉持“关系型数据库和 NewSQL 数据库共用”的较为谨慎的态度。随着时间的沉淀,相信 NewSQL 的前景会越来越光明。
大数据处理方案用在离线或准实时的计算大数据的技术栈中,如 Hadoop、Spark、Druid 等。 这里的 Druid 不是指阿里巴巴开源的数据库连接池,而是一个用于大数据实时处理的分布式系统。
以 Map/Reduce 闻名的 Hadoop 体系,将计算任务抽象成 Mapper 和 Reducer 的编程模型, 能够通过分布式手段在由成百上千台 PC 服务器组成的不完全可靠的集群中并发处理大量的数 据集,并且将分布式和故障恢复等实现细节隐藏起来。它将数据处理过程分解为多个包含 Mapper 和 Reducer 的作业,将这些作业放入集群执行,并最终得出计算结果。但由于 Map/Reduce 任务将中间结果存入 HDFS 文件系统,因此延时较长,只适合高吞吐和大批量的数据处理场景, 无法满足交互式数据处理的需要。
以 RDD(Resilient Distributed Dataset)作为计算模型的 Spark,提供了一个供集群使用的分 布式内存。在 Spark 中,RDD 转换操作后会生成新的 RDD,而新的 RDD 数据仍然依赖于原来 的 RDD。因此,程序构造了一个由多个相互依赖的 RDD 组成的 DAG(有向无环图),并将其 作为一个作业交由 Spark 执行。由于每次迭代的数据并不需要写入磁盘,而可以保存在内存中, 因此 Spark 的性能较 Hadoop 有很大提升。
2.流式处理
流式处理所包含的内容如图 1-16 所示。
流式处理包括消息中间件以及流式实时计算框架。
消息中间件用于异步化和解耦系统依赖,如 RabbitMQ 和 Kafka,未上榜的还有老牌消息中 间件 ActiveMQ,以及国产的优秀消息中间件 RocketMQ 等。由于存储引擎不同,ActiveMQ、 RabbitMQ 这种可以基于消息索引查询的消息中间件,功能虽然完善,但分布式能力和性能不尽 如人意。Kafka 以及早期的 RocketMQ 采用日志追加的存储引擎,因此分布式能力和性能大幅 提升,但自身对于消息的控制能力有限。新一代的 RocketMQ 以及阿里巴巴随之孵化的 OpenMessaging,正在努力平衡和兼容两种流派的消息中间件。
流式实时计算框架包括 Strom、Flink 等,相较于 Hadoop 这样的离线计算体系,这类框架 更加关注实时性。Storm 与 Flink 都是将输入流进行转换和计算,并将结果作为输出流传输至下 一个计算节点的。对于实时统计 PV、UV 等需求,采用流式实时计算框架来实现是不错的选择。
3.软件配置管理
软件配置管理即 SCM(Software Configuration Management),它通过执行版本控制来保证 所有代码和配置项变更的完整性和可跟踪性。在源代码版本控制工具领域,老牌的 SVN 已是明 日黄花,将会逐渐退出历史舞台,取而代之的是 Git,Git 已是当前的行业标准。Git 的出现使得 源代码版本控制工具升级为分布式工具,进而愈加受到青睐。
GitLab 使用 Git 作为其源代码版本控制工具,在管理源码的同时可以提供便捷的 Web 服务, 在成为代码托管服务平台的同时还可以通过安装配置各种插件完成代码评审、代码质量检查等 工作。企业一般都使用 GitLab 来搭建自己的软件配置管理系统。
对于个人开发者、开源项目负责人、企业付费用户来说,推荐采用 GitHub 来管理源代码, 世界顶级公司大多将顶级开源项目源码托管在 GitHub 上。
由开源中国搭建的码云同样采用 Git 作为其源代码管理工具,它在国内的访问速度优于 GitHub,更加符合国人的使用习惯,也是非常优秀的源码管理平台。
4.应用定义
对于熟悉 Java 技术栈的工程师来说,图 1-14 中可能没有特别熟悉的产品。其实,Java 中 的 Maven 就属于该范畴,它由于功能稳定、周边生态多元化,因此成为业界的主流,也是 Java 用于编译打包和依赖管理的首选。Maven 使用项目对象模型(Project Object Model)声明和管 理项目的生命周期和应用依赖,并且可以自定义插件开发方式。大量的第三方插件使得 Maven 的应用场景被无限扩大,比如,代码静态检查、代码风格评审、测试覆盖率计算等都会用到 Maven。
5.持续集成/持续交付
持续集成是指自动且持续不断地构建和测试软件项目并监控其结果是否正确。有了持续集 成工具的支持,项目可以频繁地将代码集成到主干位置,进而使得错误能够快速被发现。它的 目的是让产品在快速迭代的同时还能保持高质量。持续集成并不能消除 Bug,但是它能让 Bug 被快速发现并且容易被改正。
持续交付是指频繁地将应用的新迭代版本交付给测试团队或最终用户以供评审,如果评审通过,则自动部署至生产环境。持续交付的中心思想是,无论应用如何更新,它都可以随时随地交付并自动化部署。
常见的持续集成/持续交付工具有 Jenkins、Bamboo、CircleCI、Travis 等。 上面讲到的软件配置管理、应用定义、持续集成/持续交付三个部分的内容如图 1-17 所示。
应用定义与开发层的变动非常频繁,之前 CNCF 将开发语言、开发框架等都纳入这一层, 但从 0.9.6 版本起,新的全景图却将这些内容全部删除了。原因大概是 CNCF 认为这些内容属于业务开发范畴,云原生无须关注。因此,无论选择 Java 还是 PHP 进行开发,也不管使用 Spring 还是 Play 搭建架构,都可能开发出契合云原生的应用,也可能开发出不契合云原生的应用。
编排与治理层
将应用框架的分布式治理与云原生所需的调度、编排等功能抽象出来,形成独立的一层, 即编排与治理层,如图 1-18 所示。这种划分方式使业务开发工程师对云原生的了解更准确,云 原生中间件工程师也无须过多关注业务。相对来说,CNCF 的产品更多地集中在这一层,这是 云原生产品比较容易发力的部分。
这一层包括调度与编排、分布式协调与服务发现、服务管理。下面我们具体来看一下每个部分涉及的内容。
1.调度与编排
调度与编排提供了面向应用的容器集群部署和管理功能,目的是解耦 CPU、GPU、内存、 网络以及存储等基础设施与应用程序间的依赖,使开发人员将重点完全放在核心业务应用的研 发上,而不必操心资源管理的问题,同时也使运维人员将重点放在硬件基础设施以及操作系统 和网络本身的维护上,而不必操心资源利用率最大化的问题。调度与编排负责按照预定的策略 将承载着应用的容器调度到拥有相应运行资源的执行服务器中。除了 CNCF 的核心成员 Kubernetes,Mesos、Swarm 也属于此范畴。
虽然调度与编排同属一部分,但它们负责的内容并不相同,调度是将分布式系统中的闲置资源合理分配给需要运行的进程并采用容器进行封装的过程,编排则是对系统中的容器进行健康检查、自动扩缩容、自动重启、滚动发布等的过程。
Mesos 采用两级调度架构,因此能将调度和编排分离得比较彻底。由 Mesos 自身负责资源 的调度,由运行在 Mesos 系统中的 Marathon 进行容器的编排。
调度与编排是云原生中最基础的需求,其中包含的内容如图 1-19 所示。
2.分布式协调与服务发现
分布式场景由于网络的延迟以及不确定性,因此复杂度非常高。分布式系统一般都是通过一个可靠性非常高的注册中心对分布式服务进行协调与发现的。注册中心需要确保数据在分布式场景下的一致性,并且能够将分布式集群的状态变化及时通知给每个分布式节点。
在很多分布式系统中,我们都可以看到分布式协调和服务发现的身影,如 Hadoop、Kafka、 Dubbo 中的 ZooKeeper,Spring Cloud 中的 Eureka,Swarm 中的 Consul,其他常见的产品还有 CNCF 的项目 CoreDNS,以及负责 Kubernetes 元数据存储的 etcd。虽然 etcd 并未在 Kubernetes 中扮演分布式协调和服务发现的角色,但它可以作为注册中心提供这方面的能力。分布式协调 与服务发现中包含的内容如图 1-20 所示。
3.服务管理
如同编排与调度是云原生的基础需求一样,服务管理是云原生的另一个重要基础,也是 CNCF 的重点关注点之一。服务管理的产品主要集中在三个方面:远程通信、反向代理、服务治理。
服务间的远程通信需要依托高性能和跨语言的通信框架,gRPC、Thrift、Avro 等跨语言框 架集序列化和通信功能于一身,是分布式系统的重要基石。
关于反向代理的产品目前已经非常成熟,有涉及硬件的 F5,涉及软件的 HAProxy、Nginx 等。它们负责承载入口流量,并将请求按照规则配置分发给相关的系统。
在服务治理方面,也已经有很多成熟的框架可以使用,如 Netfix OSS 负责网关的 Zuul、负责客 户端负载均衡的 Ribbon、负责熔断的 Hystrix 等,它们也是 Spring Cloud 开发套件中的重要组成部 分。由 Twitter 开源的用 Scala 语言开发的 Finagle,以及国内非常流行的 Dubbo,也属于此范畴。
在服务治理方面,业界新兴的 Service Mesh 概念正在渐渐被更多人认同,它的中文翻译为 服务网格。Linkerd 和 Istio 是这方面的代表,由于技术实在太新,目前还处于快速发展时期。 其中 Linkerd 和 Istio 的通信底层组件 Envoy 都已加入 CNCF。Istio 是与英文 sail 对应的希腊文 单词,中文则是“航行”的意思,它与 Kubernetes 一脉相承,Kubernetes 同为希腊文,是“舵 手”的意思。除了 Envoy,Linkerd 也实现了 Istio 的接口并提供了底层通信能力。因此,Kubernetes 掌控编排,Istio 掌控服务治理,云原生的未来秩序已逐渐清晰。
值得一提的是,Kubernetes 也内置了服务管理的功能,它们并未从 Kubernetes 的核心中抽 离出来。Kubernetes 使用 Service 和 Ingress 处理服务发现和负载均衡。未来的 Service Mesh 是 否能够从 Kubernetes 中将服务治理完全接管过来,这将是一个值得关注的重点。
服务管理中包含的内容如图 1-21 所示。
运行时层
云原生的应用并不直接运行在物理服务器或传统的虚拟机之上,通常为了运行云原生应用,会在物理服务器或传统的虚拟机之上再构建一层,用于轻量和灵活地运行更多的实例。
云原生应用的运行时环境与传统应用的运行时环境有很大不同,但是它们的抽象层级是类 似的,与传统应用的文件系统、进程以及网络环境相对应的是云原生存储、容器和云原生网络。 运行时层包含的内容如图 1-22 所示,下面我们具体来看一下每个部分涉及的内容。
1.云原生存储
云原生存储是指适合云服务的分布式文件存储系统,它能将运行在云平台上的应用所需的 或产生的数据放入一个可以不依赖本地磁盘且可以平滑扩容的高可靠文件系统,典型的产品有 HDFS、Ceph、ClusterFS 等。
云原生存储与专门用于存储业务数据的数据库并不是一个概念,目前很少有将数据库安装 在云原生存储上的成熟方案。云原生存储目前最广泛的应用途径是存放日志、图片、文档等文 件。云原生存储中包含的内容如图 1-23 所示。
2.容器
容器是过去几年的热门话题。云原生应用选择容器这种更加轻量级的方案作为运行应用的载体,将容器作为最小单元对应用进行资源隔离以保证云平台的隔离性,并且通过容器打包环境和应用来提供更易复制的部署方式。不过需要注意的是,Kubernetes 采用 Pod 作为应用的最 小单元,一个 Pod 内可以包含多个容器。Docker 是目前使用最广泛的容器,业界也有 rkt 等替 代方案。关于容器,其中包含的内容如图 1-24 所示。
3.云原生网络
云原生网络可以解决为每个容器(或 Pod)分配独立 IP 地址的问题。若采用和宿主机一样 的 IP 地址,运行在同一个宿主机中的容器 IP 地址则会发生冲突。虽然可以通过改造应用程序 来屏蔽对 IP 地址的依赖,但为了使应用透明化,令每个容器都拥有一个独立的 IP 地址才是上 策。为了实现这一点,使用软件定义网络(SDN)是最佳方案。
云原生网络比较复杂,各种网络方案也层出不穷,因此产生了 CNI(Container Network Interface)这样的容器网络接口标准,它的主要实现有 Flannel、Calico、OVS、weave 等。云原 生网络包含的如容见图 1-25 所示。
供应保障层
供应保障层包括宿主机管理工具、基础设施自动化工具、容器仓库、镜像安全和密钥管理, 如图 1-26 所示,这一层用于为宿主机和容器本身提供保障,它的关注点更加偏向于运维。下面 我们来具体看一下其中的每个部分。
1.宿主机管理工具
虽然云原生应用运行在一个相互隔离的由调度系统掌控的容器环境中,但它们最终仍然是 运行在真正的物理服务器或虚拟机之上的。因此,我们需要通过管理工具将 Docker、Kubernetes、 Mesos、etcd、ZooKeeper、Flannel 等众多运行时所需环境和工具自动安装和配置在应用运行的 宿主机上。
原有的自动化运维工具在这里仍然有用武之地,它们无须再安装复杂的软件应用环境,只 搭建容器运行环境和编排调度平台即可,这类工具包括 Ansible、Puppet、Chef 等。自动化运维 工具的目标不再是安装应用及其相关环境,而是安装云原生应用所需的环境。
2.基础设施自动化工具
对于云原生的系统来说,调度编排平台即基础设施。基础设施自动化工具的用途是为调度 编排平台安装插件。常见的相关工具有 Docker 的包管理工具 Infrakit,以及简化 Kubernetes 应 用的部署工具 Helm。Helm 可以看作 Kubernetes 的 apt-get 或 yum,它通过 Helm Charts 帮助使 用者安装和更新复杂的 Kubernetes 应用,支持版本管理和控制,这在很大程度上降低了 Kubernetes 应用部署和管理的复杂性。
宿主机管理工具与基础设施自动化工具有类似之处,都属于系统软件安装的范畴,它们包 含的内容如图 1-27 所示。
3.容器仓库
容器仓库负责容器镜像内容的存储与分发。Docker Registry 是 Docker 的核心组件之一,客 户端的 docker pull 以及 docker push 命令都与它交互。Harbor 是一个比较知名的项目,它的目 标是帮助用户迅速搭建一个企业级的 Docker Registry 服务。
4.镜像安全
安全漏洞一直存在于程序世界。升级为容器之后,此类安全威胁仍然存在,因此我们需要 一个能够发现容器中可能存在的安全问题的工具,如 Clair、Twistlock 等工具均可以检查容器中 应用的漏洞。
供应保障层中还包含一个密钥管理的部分,是新加入 CNCF 的部分,笔者并不是很熟悉, 因此不做详细介绍。以上三个部分的内容如图 1-28 所示。
云设施层
云设施层主要包括用于提供物理服务器的云厂商,如图 1-29 所示。
按照公有云和私有云来分,常见的公有云有 AWS、Azure、阿里云、腾讯云、华为云等, 常见的私有云有 OpenStack、VMware 等。严格来讲,这一层其实并不在 CNCF 的范畴内,它们仅用于提供服务所需的资源。
下面再介绍一下另一个维度下的云原生应用。观察与分析是每一层都需要的功能,平台则是将每一层功能组合起来的整体解决方案。
观察与分析
观察与分析包括对系统指标的监控,对链路调用的追踪,以及对分布式日志的收集。除了收集相关数据,还能够通过对这些数据进行解读,将系统当前状态以易懂的可视化图形形式展现出来,以便运维工程师掌控整个系统。
1.监控
监控部分包括以下内容:对物理服务器指标进行采集与报警的工具,如 Nagios、Zabbix 等; 对容器指标进行采集的工具,如 CAdvisor 等;存储海量采集信息的时间序列数据库,如 Prometheus、InfluxDB 等。监控部分的具体内容如图 1-30 所示。
监控往往通过“采集、存储、分析、报警(展现)”的流程自动将系统状态通知给系统责任 人,令其处理或定期分析。一般可以采用 Grafana 等专门用于监控分析的图形工具来展示数据。
2.日志
由于云原生应用是无状态的,因此不应该将日志写入本地磁盘,而是应该写入日志中心。 用于采集标准输出并将日志输入其他流的工具主要有 Fluentd、Flume、FileBeat、Logstash 等, 然后这些工具会将日志通过各种缓冲的管道进行处理,写入日志中心,日志中心的存储介质可 以是 Elasticsearch、HBase 等。Elastic 公司提供的由搜索引擎 Elasticsearch、日志收集工具 Logstash 和图形界面 Kibana 所组成的日志中心套件(简称 ELK)是一站式的开源解决方案,也有如 Splunk 这样的一体化商业日志解决方案。
3.追踪
云原生应用运行实例多,应用调用复杂,因此一旦系统响应变慢,便会难以定位问题。因 此需要提供一套梳理和分析服务之间调用链以及服务内部调用栈的解决方案。OpenTracing 是调 用链的一个标准协议,遵循该协议的开源解决方案主要有 ZipKin、JAEGER,以及国产的优秀 开源项目 SkyWalking 等。也有一些开源解决方案并未遵循此协议,如 PinPoint、Open-Falcon、 CAT 等。
平台
基于云的整合平台是目前各个云公司都着力打造的产品,比较知名的有 Mesosphere 公司围 绕 Mesos 打造的 DC/OS,以及 Rancher 公司打造的可以整合 Mesos 和 Kubernetes 的 Rancher 平台等。
上面提到的技术只是整个云原生技术的冰山一角,无论是开源产品还是商业产品,优秀的 解决方案非常多。云原生可以有不同的实现方式,但它的本质在于弹性地利用云平台的资源。 无论是通过“应用程序 + 分布式中间件 + 自动化运维”的方式,还是通过“应用程序 + 调 度编排平台 + 容器 + 服务治理”的方式,都可以实现健壮的系统。
相关文章:
本文节选自图书《未来架构:从服务化到云原生》第一章。本书对快速演进中的云原生数据架构、典型分布式数据库中间件进行了剖析,重点介绍 Service Mesh 等新兴概念,创新性地提出了 Database Mesh 的理念,深度揭秘 Apache 项目——ShardingSphere。
购买链接: https://u.jd.com/sbmG4Y
作者简介:
张亮
京东数科数据研发负责人,Apache ShardingSphere 发起人兼 PPMC 成员。热爱分享,拥抱开源,主张代码优雅化,擅长以 Java 为主的分布式架构以及以 Kubernetes 和 Mesos 为主的云平台的构建。ShardingSphere 已进入 Apache 软件基金会,是京东集团首个进入 Apache 的开源项目,也是 Apache 首个分布式数据库中间件。
吴晟
Apache SkyWalking 创始人及 PPMC 成员,Apache ShardingSphere 原型作者及 PPMC 成员,Apache Zipkin 贡献者,Apache 孵化器导师,CNCF 基金会 OpenTracing 标准化委员会成员,W3C Trace Context 规范贡献者。擅长分布式架构、性能监控与诊断、分布式追踪、云原生监控等领域。
敖小剑
具有十七年软件开发经验,资深码农,微服务专家,Cloud Native 拥护者,敏捷实践者,Service Mesh 布道师,ServiceMesher 中文社区联合创始人。专注于基础架构建设,对微服务、云计算等相关技术有着深入研究和独到见解。
宋净超
蚂蚁金服云原生布道师,ServiceMesher 中文社区联合创始人,Kubernetes 社区成员,Istio 社区成员,《Cloud Native Go》《Python 云原生》《云原生 Java》等图书译者。
评论 1 条评论