你好,我是孔令飞。
上一节课,我详细介绍了什么是云原生。云原生中包含了三大核心内容:云原生技术栈、方法论和云原生应用。其中,云原生技术栈是基石,所有云原生理念的落地,都依赖于这些技术栈的支持。那么,云原生技术栈具体有哪些呢?它们又有什么特性?以至于可以通过它们来实现云原生的各种理念。
本节课,我将详细介绍这些云原生技术栈。这些技术栈,在你今后的研发生涯中,也会持续不断地应用到。
云原生中有哪些核心技术栈?
Pivotal 公司和 CNCF 定义下的云原生在不同阶段分别包含了不同的技术栈,当前包含的技术栈如下(Pivotal 和 CNCF 的技术栈并集):
-
微服务
-
容器
-
服务网格
-
声明式 API
-
不可变基础设施
-
持续集成和持续交付(CI/CD)
-
DevOps
但在我看来,云原生核心技术栈中,还应该包括以下技术栈:
-
Kubernetes
-
Serverless
需要强调的是,上面这些云原生核心技术栈,都是以 Kubernetes 为基石来构建的。
因为云原生技术栈中的核心技术很多,所以我会分上下两节课来介绍。在本节课中,我将重点讲解以下核心技术栈:
-
微服务
-
容器
-
容器编排
-
Serverless

微服务(Microservice)
纵观云原生的发展历程,几乎所有对云原生的定义都包含了微服务,可见其重要性。微服务是一种软件架构方式,使用微服务架构,可以将一个大型应用程序按照功能模块拆分成多个独立自治的微服务,每个微服务仅实现一种功能,具有明确的边界。
为了让应用程序的各个微服务之间协同工作,通常需要互相调用 REST、RPC 等形式的标准接口进行通信和数据交换,这是一种松耦合的交互形式,可以提升系统的灵活性和可维护性。
微服务架构最早在 2011 年被提出,但近几年才逐渐流行起来。这是什么原因呢?一方面,微服务架构基于自身的特点,确实能够解决其他软件架构中存在的一些问题;另一方面,Docker + Kubernetes 等云原生技术这几年也发展了起来,能够很好地支撑微服务的部署和生命周期管理。
微服务基于分布式计算架构,其主要特点可以概括为以下三点:
-
单一职责:微服务架构中的每一个服务,都应是符合高内聚、低耦合以及单一职责原则的业务逻辑单元,不同的微服务通过 REST 等形式的标准接口互相调用,进行灵活的通信和组合,从而构建出庞大的系统。
-
独立自治性:每个微服务都应该是一个独立的组件,它可以被独立部署、测试、升级和发布,应用程序中的某个或某几个微服务被替换时,其他的微服务都不应该被影响。
-
采用轻量的通信协议:微服务架构提供的服务之间采用 RESTful、RPC 等轻量协议传输。
基于分布式计算、可弹性扩展和组件自治的微服务,与云原生技术相辅相成,为应用程序的设计、开发和部署提供了极大便利,可总结为以下几点:
-
简化复杂应用:微服务的单一职责原则要求一个微服务只负责一项明确的业务,相对于构建一个可以完成所有任务的大型应用程序,实现和理解只提供一个功能的小型应用程序要容易得多。每个微服务单独开发,可以加快开发速度,使服务更容易适应变化和新的需求。
-
简化应用部署:在单体的大型应用程序中,即使只修改某个模块的一行代码,也需要对整个系统进行重新构建、部署、测试和交付。而微服务则可以单独对某一个指定的组件进行构建、部署、测试和交付。
-
灵活组合:在微服务架构中,可以重用一些已有的微服务组合新的应用程序,降低应用开发成本。
-
可扩展性:根据应用程序中不同的微服务负载情况,可以为负载高的微服务横向扩展多个副本。
-
技术异构性:通常在一个大型应用程序中,不同的模块具有不同的功能特点,可能需要不同的团队使用不同的技术栈进行开发。我们可以使用任意新技术对某个微服务进行技术架构升级,只要对外提供的接口保持不变,其他微服务就不会受到影响。
-
高可靠性、高容错性:微服务独立部署和自治,当某个微服务出现故障时,其他微服务不受影响。
微服务架构有很多优点,但也存在着问题。因为一个应用被拆分成一个个的微服务,随着微服务的增多,就会引入一些问题,比如微服务过多导致服务部署复杂。微服务的分布式特点也带来了一些复杂度,比如需要提供服务发现能力、调用链难以追踪、测试困难等等。服务之间相互依赖,有可能形成复杂的依赖链路,往往单个服务异常,其他服务都会受到影响,出现服务雪崩效应。
针对这些问题,目前业界也有一些标准的解决方案。比如,通过使用容器化(Docker + Kubernetes)的部署方式,来简化运维工作,提高运维效率,解决微服务部署复杂的问题。至于微服务的分布式特点所带来的复杂性,可以通过一些微服务开发框架来解决。一些业界比较知名的微服务开发框架,比如 go-micro、go-kratos、go-kit 等,已经很好地解决了上面的问题。另外,云原生相关的技术也可以解决微服务调用链跟踪复杂、故障排障困难等问题。
在企业开发中,是否采用微服务架构需要根据应用程序的特点、企业的组织架构和团队能力等多个方面来综合评估。鉴于微服务所具备的优点,我比较建议一开始应用就采用微服务化设计。
总结来说,微服务从软件架构形态上来看,是一个增强版的小型单体架构。首先微服务软件架构是一个单体架构,只不过这个单体架构代码量小、功能聚焦(少)、可独立更新。增强型,是因为这个单体架构,集成了很多其他功能,这些功能主要用来解决服务变多带来的运维复杂度。例如,通常一个微服务会集成调用链追踪、服务注册和服务发现、配置中心等扩展功能。因为微服务中集成了很多功能,这些功能你可以基于一个基础的 Web 框架自行集成,也可以使用别人集成好的软件包来开发,所以一个集成了众多微服务扩展功能的软件框架,我们也称之为微服务框架。
容器(Container)
容器技术的的代表项目就是 Docker,这是 Docker 公司于 2013 年推出的一款容器化工具。凭借其轻量、易用的特点,Docker 迅速获得了广泛的应用。它的普及使得系统资源的形态由虚拟机阶段进入到了容器阶段。
基于 Docker 容器化技术,开发者可以将他们的应用及其依赖和配置打包到一个可移植的容器中,然后发布到任何流行的 Linux/Windows 机器上。开发者无需关注底层系统、环境依赖,这使得容器成为部署单个微服务的最理想的工具。
Docker 通过 Linux Namespace 技术来进行资源隔离,通过 Cgroup 技术来进行资源分配,具有更高的资源利用率。Docker 跟宿主机共用一个内核,不需要模拟整个操作系统,所以具有更快的启动速度。此外,Docker 镜像中已经打包了所有的依赖和配置,确保在不同环境中有一个一致的运行环境,因此能够支持更快速的迁移。另外,Docker 的这些特性也促进了 DevOps 技术的发展。
我这里拿 Docker 和虚拟机来做个对比,让你感受下 Docker 的强大。二者的架构对比如下图所示:

可以看到,Container 相比于虚拟机,不用模拟出一个完整的操作系统,非常轻量。因此,和虚拟机相比,容器具有下面这些优势:

从这张表格里你可以看到,在启动时间、硬盘占用量、性能、系统支持量、资源使用率、环境配置这些方面,Docker 和虚拟机相比优势显著,也使得 Docker 成为比虚拟机更流行的应用部署媒介。
也许这时你想问了:Docker 就这么好,一点缺点都没有吗?显然不是的,Docker 也有自己的局限性。
我们先来看一下生产环境的 Docker 容器是什么样的:一个生产环境的容器数量可能极其庞大,关系错综复杂,并且生产环境的应用可能天生就是集群化的,具备高可用、负载均衡等能力。Docker 更多是用来解决单个服务的部署问题,无法解决生产环境中的这些问题。并且,不同节点间的 Docker 容器无法相互通信。
不过,这些问题都可以通过容器编排技术来解决。业界目前也有很多优秀的容器编排技术,比较受欢迎的有 Kubernetes、Mesos、Docker Swarm、Rancher 等。这两年,随着 Kubernetes 的发展壮大,Kubernetes 已经成为容器编排的事实标准。
容器编排(Kubernetes)
Kubernetes 是 Google 在 2014 年开源的生产级别容器编排技术(编排也可以简单理解为调度、管理),用于容器化应用的自动化部署、扩展和管理。它的前身是 Google 内部的 Borg 项目。Kubernetes 的主要特性有:网络通信、服务发现与负载均衡、滚动更新 & 回滚、自愈、安全配置管理、资源管理、自动伸缩、监控、服务健康检查等。
提示:Kubernetes 简称 K8s,其中 8 代表 K 和 s 中有 8 个字符。这种缩写方式,是行业中常见的一种缩写方式。
Kubernetes 通过这些特性,解决了生产环境中 Docker 存在的问题。Kubernetes 和 Docker 相辅相成,Kubernetes 的成功也使 Docker 有了更大规模的使用,最终使得 Docker 成为比虚拟机更流行的计算资源提供方式。
Kubernetes 架构
提示:第二章会详细介绍 Kubernetes。本节课为了云原生技术栈讲解上的完整性,仍然会介绍 Kubernetes 基础知识。后面章节如果有学习到同类知识,你就当温故知新了。
Kubernetes 架构图如下:

Kubernetes 采用的是 Master-Worker 架构模式。其中,Master 节点是 Kubernetes 最重要的节点,里面部署了 Kubernetes 的核心组件,这些核心组件共同构成了 Kubernetes 的 Control Plane(控制面板)。而 Worker,也就是图中的 Node Cluster,就是节点集群。其中,每一个 Node 就是具体的计算资源,它既可以是一台物理服务器,也可以是虚拟机。
我们先来介绍下 Master 节点上的组件。
-
Kube API Server:提供了资源操作的唯一入口,并提供认证、授权、访问控制、API 注册和发现等机制。
-
Kube Scheduler:负责资源的调度,按照预定的调度策略将 Pod 调度到相应的机器上。
-
Kube Controller Manager:负责维护集群的状态,比如故障检测、自动扩展、滚动更新等。
-
Cloud Controller Manager:这个组件是在 Kubernetes 1.6 版本加入的与基础云提供商交互的控制器。
-
Etcd:分布式的 K-V 存储,独立于 Kubernetes 的开源组件。主要存储关键的元数据,支持水平扩容保障元数据的高可用性。基于 Raft 算法实现强一致性,独特的 Watch 机制是 Kubernetes 设计的关键。
介绍完了 Master,再看看每一个 Kubernetes Node 需要哪些组件。
-
Kubelet:负责维持容器的生命周期,同时也负责 volume(CVI)和网络(CNI)的管理。
-
kube-proxy:kube-proxy 是集群中每个节点上运行的网络代理,维护节点上的网络规则,它允许从集群的内部或外部网络与 Pod 进行网络通信,并负责为 Service 提供集群内部的服务发现和负载均衡。
-
Container Runtime:负责镜像管理、Pod 和容器的真正运行(CRI),默认的容器运行时为 Docker。
上面那张架构图里的 Service、Deployment、Pod 等,都不算是组件,而是属于 Kubernetes 资源对象,我们稍后再做介绍。这里我先简单介绍下架构图的 UI dashboard 和 kubectl。
- UI dashboard 是 Kubernetes 官方提供的 Web 控制面板,可以对集群进行各种控制,直接与 API Server 进行交互,其实就是 API Server 暴露出来的可视化接口。在这里可以直观地创建 Kubernetes 对象、查看 Pod 运行状态等。UI dashboard 界面如下图所示:

- kubectl 是 Kubernetes 的客户端工具,提供了非常多的命令、子命令、命令行选项,支持开发或运维人员在命令行快速操作 Kubernetes 集群,例如对各类 Kubernetes 资源进行增删改查操作,给资源打标签,等等。下面是执行
kubectl describe service onex-usercenter命令获取 onex-usercenter 服务详细信息的命令行截图:

Kubernetes 核心资源
Kubernetes 有多种多样的 Objects,如果要查看所有 Objects 的 Kind,可以使用命令 kubectl api-resources。我们通过这些 Objects 来完成 Kubernetes 各类资源的创建、删除等操作。因为我们这一讲的核心目的是介绍云原生技术的演进,所以不会详细介绍 Kubernetes 资源对象的使用方式。你如果感兴趣,可以查看 Kubernetes 官方文档。
我这里简单介绍一下 Kubernetes 对象的一些基本信息,以及在架构图中出现的 Deployment、Pod、Service 三种对象。
下面是一个典型的 Kubernetes 对象 YAML 描述文件:
apiVersion: v1
kind: Pod
metadata:
name: nginx
labels:
name: nginx
spec:
# ...
在这个描述文件中,apiVersion 和 kind 共同决定了当前 YAML 配置文件应该由谁来处理,前者表示描述文件使用的 API 组,后者表示一个 API 组中的一个资源类型。这里的 v1 和 Pod 表示的就是核心 API 组 api/v1 中的 Pod 类型对象。
metadata 则是一些关于该对象的元数据,其中主要有 name、namespace、labels、annotations。其中, name 需要在 namespace 下唯一,成为这个对象的唯一标识。label和annotations分别是这个对象的一些标签和一些注解,前者用于筛选,后者主要用来标注提示性的信息。
接下来,我再介绍下 Pod、Deployment、Service 这 3 种对象。
1. Pod
Pod 是 Kubernetes 中运行的最小的、最简单的计算单元,我觉得 Pod 也是 Kubernetes 最核心的对象。Pod 中可以指定运行多个 Containers,可以挂载 volume 来实现部署有状态的服务,这些都在spec中被指定。
对于任意类型的对象,spec都是用来描述开发人员或运维人员对这个对象所期望的状态的,对于不同类型的对象,spec有不同的子属性。
下面是一个 Pod 示例,我们在 YAML 描述文件里指定了期望 Pod 运行的 Docker 镜像和命令。
apiVersion: v1
kind: Pod
metadata:
name: busybox
labels:
app: busybox
spec:
containers:
- image: busybox
command:
- sleep
- "3600"
imagePullPolicy: IfNotPresent
name: busybox
restartPolicy: Always
2. Deployment
一般来说,我们不会直接部署 Pod,而是部署一个 Deployment 或者 StatefulSet 之类的 Kubernetes 对象。Deployment 一般是无状态服务;StatefulSet 一般是有状态服务,会使用 volume 来持久化数据。下面是一个部署两个 Pod 的示例。
apiVersion: apps/v1 # for versions before 1.9.0 use apps/v1beta2
kind: Deployment
metadata:
name: my-nginx
spec:
selector:
matchLabels:
run: my-nginx
replicas: 2
template:
metadata:
labels:
run: my-nginx
spec:
containers:
- name: my-nginx
image: nginx
ports:
- containerPort: 80
3. Service
Service 是 Kubernetes 中另一个常见的对象,它的作用是作为一组 Pod 的负载均衡器,利用 selector 将 Service 和 Pod 关联起来。
下面这个示例里,使用的是 run: my-nginx 这个 label。这个 Service 绑定的就是上面那个 Deployment 部署的 nginx 服务器。
apiVersion: v1
kind: Service
metadata:
name: my-nginx
labels:
run: my-nginx
spec:
ports:
- port: 80
protocol: TCP
selector:
run: my-nginx
Serverless
2014 年,AWS 推出 Lambda 服务,这是全球第一个 Serverless 服务。从此,Serverless 越来越引人注意,成为了这几年最受关注的技术。
Serverless 直译过来就是无服务器。不过无服务器并不代表 Serverless 真的不需要服务器,只不过服务器的管理以及资源的分配部分对用户不可见,而是由平台开发商维护。Serverless 不是具体的一个编程框架、类库或者工具,它是一种软件系统架构思想和方法。它的核心思想是:用户无需关注支撑应用服务运行的底层资源,比如 CPU、内存和数据库等,只需要关注自己的业务开发就行了。
Serverless 具有很多特点,核心特点主要有以下几个:
-
无穷弹性计算能力:根据请求,自动水平扩容实例,拥有近乎无限的扩容能力。
-
“零”运维:不需要申请和运维服务器。
-
极致的伸缩能力:能够根据 CPU、内存、请求量等指标敏感地弹性伸缩,并支持缩容到 0。
-
按量计费:真正按使用量去计费。
在我看来,Serverless 有 4 种技术形态,分别是:云函数、Serverless 容器、BaaS(Backend as a Service)、Serverless 应用,如下图所示:

其中,Serverless 容器是核心,云函数和 BaaS 起辅助作用。
Serverless 容器可以承载业务的核心架构,云函数则可以很好地适配触发器场景,BaaS 则可以满足我们对各种其他 Serverless 组件的需求,例如 Serverless 数据库、Serverless 存储等。而随着 Serverless 化程度的加深,也诞生了一些 Serverless 化的应用,例如腾讯云的云开发、各种低代码平台等。上述所有共同组成了整个 Serverless 生态体系。
课程总结
这节课我们详细介绍了云原生中的部分核心技术栈,包括微服务、容器、容器编排、Serverless。
-
微服务(Microservices):微服务架构是一种将应用程序拆分成小型、独立部署的服务单元的架构风格。每个微服务都可以独立开发、部署和扩展,通过轻量级通信机制相互协作,从而提高灵活性、可维护性和可扩展性。
-
容器(Containers):容器是一种轻量级、可移植的封装形式,用于打包应用程序及其所有依赖项。容器可以在任何环境中运行,提供一致的运行时环境,简化了开发、部署和管理应用程序的过程。
-
容器编排(Kubernetes):容器编排是一种管理容器化应用的自动化方式,负责部署、管理、扩展和网络配置等任务。Kubernetes 是目前最流行的容器编排平台之一。
-
Serverless(无服务器架构):Serverless 是一种云计算模型,在这种模型中,开发者无需管理服务器资源,可以专注于编写和部署业务逻辑。应用程序在需要时才会运行,服务提供商负责底层基础设施的维护和管理。
课后练习
-
在云原生技术栈中,各个技术栈之间的关系是什么?
-
微服务和单体架构的区别是什么?
-
我们为什么要使用微服务?其优缺点是什么?如何解决微服务带来的各种问题?
欢迎你在留言区与我交流讨论,如果今天的内容让你有所收获,也欢迎转发给有需要的朋友,我们下节课再见!
精选留言
2025-04-16 15:22:10
kubernetes 在 1.24 版本后好像是用containerd作为默认运行时?
问下老师,在选择containerd或Docker 作为 kubernetes 运行时时,在使用上有什么影响吗?
2025-04-16 09:31:48
1、容器化应该是整个云原生的基石,k8s是负责对容器编排的上层建筑,微服务是一种软件架构,而这种架构能够在云原生中发挥出最大的优势,服务网格增强或者隔离容器间的通信,CICD支撑微服务无缝上云,prometheus提供线上监控,对于开发人员来说只需要关注整个流程中的两个端点即业务代码开发和prometheus的监控极可
2、微服务的提出是为了能够敏捷开发,技术上的异构,独立模块的快速迭代、容错、水平扩展等。但是微服务又引入的其他的问题,比如分布式事务,数据一致性,微服务间的通信!所谓天下分久必合 合久必分,最近又有一些声音是合单体,所以软件工程没有银弹,只有取舍,也没有谁好谁不好,只有谁更合适
3、选择微服务要看现在的团队能否驾驭以及目前的一个发展阶段。如果是项目初期单体先甩起来,快速验证市场!至于微服务带来的问题也要看各自的业务,没有解决问题的标准答案,适合自己业务的才是最好的