gitbook/Go 语言项目开发实战/docs/414159.md
2022-09-03 22:05:03 +08:00

358 lines
30 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 43技术演进虚拟化技术演进之路
你好,我是孔令飞。
在前面的三讲中我介绍了传统应用的部署方式。但是随着软件架构进入云原生时代我们越来越多地使用云原生架构来构建和部署我们的应用。为了给你演示如何使用云原生化的方式来部署IAM应用接下来我会介绍如何基于Kubernetes来部署IAM应用。
在Kubernetes集群中部署IAM应用会涉及到一些重要的云原生技术例如Docker、Kubernetes、微服务等。另外云原生架构中还包含了很多其他的技术。为了让你提前了解后面部署需要的相关技术同时比较通透地了解当前最火热的云原生架构这一讲我就采用技术演进的思路来详细讲解下云原生技术栈的演进中的虚拟化技术演进部分。
因为这一讲涉及的技术栈很多,所以我会把重点放在演进过程上,不会详细介绍每种技术的具体实现原理和使用方法。如果你感兴趣,可以自行学习,也可以参考我为你整理的这个资料:[awesome-books](https://github.com/marmotedu/awesome-books#%E4%BA%91%E8%AE%A1%E7%AE%97)。
在讲这个演进过程之前,我们先来看下这个问题:我们为什么使用云?
## 我们为什么使用云?
使用云的原因其实很简单,我们只是想在云上部署一个能够对外稳定输出业务能力的服务,这个服务以应用的形态部署在云上。为了启动一个应用,我们还需要申请系统资源。此外,我们还需要确保应用能够快速迭代和发布,出故障后能够快速恢复等,这就需要我们对应用进行生命周期管理。
应用、系统资源、应用生命周期管理这3个维度就构成了我们对云的所有诉求如下图所示
![图片](https://static001.geekbang.org/resource/image/yy/eb/yyea295d642681444a004d55e8d73eeb.png?wh=1920x1010)
接下来的两讲我就围绕着这3个维度来给你详细介绍下每个维度的技术演进。这一讲我会先介绍下系统资源维度的技术演进。在44讲我会再介绍下应用维度和应用生命周期管理维度的技术演进。
当前有3种系统资源形态分别是物理机、虚拟机和容器这3种系统资源形态都是围绕着虚拟化来演进的。所以介绍系统资源技术的演进其实就是介绍虚拟化技术的演进。
接下来,我们就来看下虚拟化技术是如何演进的。
## 虚拟化技术的演进
虚拟化这个概念其实在20世纪60年代就已经出现了。但因为技术、场景等限制虚拟化技术曾沉寂过一段时间直到21世纪虚拟机出现虚拟化技术又迎来了一波爆发期并逐渐走向成熟。
那么,什么是虚拟化技术呢?简单来讲,就是把计算机上的硬件、系统资源划分为逻辑组的技术,由此生成的仅仅是一个逻辑角度的视图。通过虚拟化技术,我们可以在一台计算机上运行多个虚拟机进程,进而发挥计算机硬件的最大利用率。
虚拟化分为很多种例如操作系统虚拟化、存储虚拟化、网络虚拟化、桌面虚拟化等。其中最重要的是操作系统虚拟化支撑操作系统虚拟化的是底层CPU、内存、存储、网络等的虚拟化这些资源我们统称为计算资源。
因为计算资源的虚拟化在虚拟化领域占主导地位,所以很多时候我们说虚拟化技术演进,其实就是在说计算资源技术的演进。在我看来,虚拟化技术的演进过程如下:物理机阶段 -> 虚拟机阶段 -> 容器阶段Docker + Kubernetes -> Serverless阶段。
### 物理机阶段
上面我提到虚拟化技术包含很多方面但是整个虚拟化技术是围绕着CPU虚拟化技术来演进的。这是因为内存虚拟化、I/O虚拟化的正确实现都依赖于对内存、I/O中一些敏感指令的正确处理这就涉及到CPU虚拟化所以CPU虚拟化是虚拟化技术的核心。因此这一讲我会围绕着CPU虚拟化的演进来讲解虚拟化技术的演进。这里我先来介绍一下物理机阶段CPU的相关知识。
CPU是由一系列指令集构成的这些指令集主要分为两种分别是特权指令集和非特权指令集。特权指令集是指那些可以改变系统状态的指令集非特权指令集是指那些不会影响系统状态的指令集。我举个例子你就明白了写内存是特权指令集因为它可以改变系统的状态读内存是非特权指令集因为它不会影响系统的状态。
因为非特权指令集可能会影响整个系统所以芯片厂商在x86架构上又设计了一种新模式保护模式这个模式可以避免非特权指令集非法访问系统资源。
保护模式是通过Ring来实现的。在x86架构上一共有4个Ring不同的Ring有不同的权限级别Ring 0有最高的权限可以操作所有的系统资源Ring 3的权限级别最低。Kernel运行在Ring 0上Application运行在Ring 3上。Ring 3的Application如果想请求系统资源需要通过system call调用Ring 0的内核功能来申请系统资源。
这种方式有个好处可以避免Applicaiton直接请求系统资源影响系统稳定性。通过具有更高权限级的Kernel统一调度、统一分配资源可以使整个系统更高效更安全。
x86架构的Ring和调用关系如下图所示
![图片](https://static001.geekbang.org/resource/image/7e/8d/7e2868cd62baae3154bc4e8957e9b48d.png?wh=1920x708)
在物理机阶段,对外提供物理资源,这种资源提供方式面临很多问题,例如成本高,维护麻烦、需要建机房、安装制冷设备、服务器不方便创建、销毁等等。所以在云时代,和物理机相比,我们用得更多的是虚拟机。下面我们就来看虚拟机阶段。
### 虚拟机阶段
这里在讲虚拟化技术之前我想先介绍下x86的虚拟化漏洞CPU虚拟化技术的演进也主要是围绕着解决这个漏洞来演进的。
#### 虚拟化漏洞
一个虚拟化环境分为三个部分分别是硬件、虚拟机监控器又叫VMMVirtual Machine Manager还有虚拟机。
你可以把虚拟机看作物理机的一种高效隔离的复制它具有三个特性同质、高效、资源受控。这三个特点决定了不是所有体系都可以虚拟化比如目前我们用得最多的x86架构就不是一个可虚拟化的架构我们称之为虚拟化漏洞。
在虚拟化技术产生后,诞生了一个新的概念:敏感指令。敏感指令是指可以操作特权资源的指令,比如修改虚拟机运行模式、物理机状态,读写敏感寄存器/内存等。显然,所有的特权指令都是敏感指令,但不是所有的敏感指令都是特权指令。特权指令和敏感指令的关系,可以简单地用这张图来表示:
![图片](https://static001.geekbang.org/resource/image/30/6a/30da714fc8341600f558817789a9096a.png?wh=1920x1942)
在一个可虚拟化的架构中所有的敏感指令应该都是特权指令。x86架构中有些敏感指令不是特权指令最简单的例子是企图访问或修改虚拟机模式的指令。所以x86架构是有虚拟化漏洞的。
#### Hypervisor技术的演进
为了解决x86架构的虚拟化漏洞衍生出了一系列的虚拟化技术这些虚拟化技术中最核心的是Hypervisor技术。所以接下来我就介绍下Hypervisor技术的演进。
Hypervisor也称为虚拟机监控器 VMM可用于创建和运行虚拟机 VM。它是一种中间软件层运行在基础物理服务器和操作系统之间可允许多个操作系统和应用共享硬件。通过让Hypervisor以虚拟化的方式共享系统资源如内存、CPU资源一台主机计算机可以支持多台客户机虚拟机。
Hypervisor、物理机和虚拟机的关系如下图
![图片](https://static001.geekbang.org/resource/image/2d/7f/2d471ca14d50b80ffcd421c8719cf17f.png?wh=1920x1080)
按时间顺序Hypervisor技术的发展依次经历了下面3个阶段
1. 软件辅助的完全虚拟化Software-assisted full virtualization该虚拟化技术在1999年出现里面又包含了解释执行如Bochs、扫描与修补如VirtualBox、二进制代码翻译如Vmware、Qemu三种技术。
2. 半虚拟化Para-virtualization该虚拟化技术在2003年出现也叫类虚拟化技术典型的Hypervisor代表是Xen。
3. 硬件辅助的完全虚拟化Hardware-assistant full virtualization 该虚拟化技术在2006年出现典型的Hypervisor代表是KVM。当前普遍使用的主流虚拟化技术就是以KVM为代表的硬件辅助的完全虚拟化。
下面,我就来简单介绍下这三个阶段。
**先来看第一个阶段,软件辅助的完全虚拟化**,它又分为解释执行、扫描与修补、二进制代码翻译三个演进阶段。
1. 解释执行
简单地说解释执行的过程就是取一条指令模拟出这条指令的执行效果再取下一条指令。这种技术因为思路比较简单所以容易实现复杂度低。执行时编译好的二进制代码是不会被载入到物理CPU直接运行的而是由解释器逐条解码再调入对应的函数来模拟指令的功能。解释过程如下图所示
![图片](https://static001.geekbang.org/resource/image/9d/c7/9d6c29e788e62ec16115d02a7f0807c7.png?wh=1920x1180)
因为每一条指令都要模拟所以就解决了虚拟化漏洞同时也可以模拟出一个异构的CPU结构比如在x86架构上模拟出一个ARM架构的虚拟机。也正是因为每一条指令都需要模拟不区别对待导致这种技术的性能很低。
2. 扫描与修补
由于解释执行性能损失很大再加上虚拟机中模拟的虚拟CPU和物理CPU的体系结构相同同质这样大多数指令可以直接在物理CPU上运行。因此CPU虚拟化过程中可以采用更优化的模拟技术来弥补虚拟化漏洞。
扫描与修补技术就是通过这种方式让大多数指令直接在物理CPU上运行而把操作系统中的敏感指令替换为跳转指令或者会陷入到VMM中去的指令。这样VMM一旦运行到敏感指令控制流就会进入VMM中由VMM代为模拟执行。过程如下图所示
![图片](https://static001.geekbang.org/resource/image/f0/4e/f0fdb92c7c1fedc3bbedc90d411d314e.png?wh=1920x1460)
使用这种方式因为大部分指令不需要模拟可以直接在CPU上运行所以性能损失相对较小实现起来比较简单。
3. 二进制代码翻译
这个算是软件辅助的完全虚拟化的主流方式了早期的VMware用的就是这个技术。二进制代码翻译会在VMM中开辟一段缓存将翻译好的代码放在缓存中。在执行到某条指令的时候直接从内存中找到这条指令对应的翻译后的指令然后在CPU上执行。
在性能上,二进制代码翻译跟扫描与修补技术各有长短,但是实现方式最为复杂。它的过程如下图所示:
![图片](https://static001.geekbang.org/resource/image/ba/1a/ba3962c283c567d6f20c8d780930d41a.jpg?wh=1920x1698)
看到这里你可能会对模拟和翻译这两个概念有疑惑我在这里解释下模拟和翻译的区别模拟是将A动作模拟成B动作而翻译是将A指令翻译成B指令二者是有本质不同的。
**然后我们来看Hypervisor技术发展的第二个阶段Para-virtualization。**
软件辅助的完全虚拟化对x86的指令做了翻译或者模拟在性能上多多少少都会有些损失而这些性能损失在一些生产级的场景是不可接受的。所以在2003年出现了Para-virtualization技术也叫半虚拟化/类虚拟化。和之前的虚拟化技术相比Para-virtualization在性能上有了大幅度的提升甚至接近于原生的物理机。
Para-virtualization的大概原理是这样的Hypervisor运行在Ring 0中修改客户机操作系统内核将其中的敏感指令换成hypercall。hypercall是一个可以直接跟VMM通信的函数这样就绕过了虚拟化的漏洞相当于所有敏感指令都被VMM捕获了同时不存在模拟和翻译的过程所以性能是最高的。这个过程如下图所示
![图片](https://static001.geekbang.org/resource/image/6e/77/6ea013e621c58fb78d444449fb55f977.png?wh=1920x902)
因为要修改操作系统所以不能模拟一些闭源的操作系统比如Windows系列。另外修改客户机操作系统内核还是有些开发和维护工作量的。所以随着硬件辅助完全虚拟化技术的成熟Para-virtualization也逐渐被替换掉了。
**然后我们来看Hypervisor技术发展的第三个阶段****硬件辅助的完全虚拟化****。**
在2006年Intel和AMD分别在硬件层面支持了虚拟化比如Intel的VT-X技术和AMD的SVM。它们的核心思想都是引入新运行模式可以理解为增加了一个新的CPU Ring -1权限比Ring 0 还高使VMM运行在Ring -1下客户机内核运行在Ring 0下。
通常情况下客户机的核心指令可以直接下达到计算机系统硬件执行不需要经过VMM。当客户机执行到敏感指令的时候CPU会从硬件层面截获这部分敏感指令并切换到VMM让VMM来处理这部分敏感指令从而绕开虚拟化漏洞。具体如下图所示
![图片](https://static001.geekbang.org/resource/image/e6/91/e60585ea58107b48af2815a3fd552591.png?wh=1920x929)
因为CPU是从硬件层面支持虚拟化的性能要比软件模拟更高同时硬件虚拟化可以不用去修改操作系统。所以即使是现在硬件辅助的完全虚拟化也是主流的虚拟化方式。
接下来我们来看虚拟化技术演进的第三阶段,容器阶段。
### 容器阶段
2005年诞生了一种新的虚拟化技术容器技术。容器是一种轻量级的虚拟化技术能够在单一主机上提供多个隔离的操作系统环境通过一系列的命名空间隔离进程每个容器都有唯一的可写文件系统和资源配额。
#### 容器引擎Docker
容器技术的的代表项目就是DockerDocker是Docker公司在2013年推出的容器项目因为轻量、易用的特点迅速得到了大规模的使用。Docker的大规模应用使得系统资源的形态由虚拟机阶段进入到了容器阶段。
基于Docker容器化技术开发者可以打包他们的应用以及依赖和配置到一个可移植的容器中然后发布到任何流行的 Linux/Windows 机器上。开发者无需关注底层系统、环境依赖,这使得容器成为部署单个微服务的最理想的工具。
Docker通过Linux Namespace技术来进行资源隔离通过Cgroup技术来进行资源分配具有更高的资源利用率。Docker跟宿主机共用一个内核不需要模拟整个操作系统所以具有更快的启动时间。在Docker镜像中已经打包了所有的依赖和配置这样就可以在不同环境有一个一致的运行环境所以能够支持更快速的迁移。另外Docker的这些特性也促进了DevOps技术的发展。
我这里拿Docker和虚拟机来做个对比让你感受下Docker的强大。二者的架构对比如下图所示
![图片](https://static001.geekbang.org/resource/image/7e/98/7e24d5667f4d41724c9cc0ab6fee5398.png?wh=1920x822)
可以看到Container相比于虚拟机不用模拟出一个完整的操作系统非常轻量。因此和虚拟机相比容器具有下面这些优势
![图片](https://static001.geekbang.org/resource/image/65/5c/65049ffd61b12de9fcd5ccf8f684385c.png?wh=1920x1209)
从这张表格里你可以看到在启动时间、硬盘占用量、性能、系统支持量、资源使用率、环境配置这些方面Docker和虚拟机相比具有巨大的优势。这些优势使得Docker成为比虚拟机更流行的应用部署媒介。
也许这时你想问了Docker就这么好一点缺点都没有吗显然不是的Docker也有自己的局限性。
我们先来看一下生产环境的Docker容器是什么样的一个生产环境的容器数量可能极其庞大关系错综复杂并且生产环境的应用可能天生就是集群化的具备高可用、负载均衡等能力。Docker更多是用来解决单个服务的部署问题无法解决生产环境中的这些问题。并且不同节点间的Docker容器无法相互通信。
不过这些问题都可以通过容器编排技术来解决。业界目前也有很多优秀的容器编排技术比较受欢迎的有Kubernetes、Mesos、Docker Swarm、Rancher等。这两年随着Kubernetes的发展壮大Kubernetes已经成为容器编排的事实标准。
#### 容器编排技术Kubernetes
因为我们后面会基于Kubernetes来部署IAM应用所以这里我会详细介绍下Kubernetes服务编排技术。
Kubernetes是Google开源的一个容器编排技术编排也可以简单理解为调度、管理用于容器化应用的自动化部署、扩展和管理。它的前身是Google内部的Borg项目。Kubernetes的主要特性有网络通信、服务发现与负载均衡、滚动更新 & 回滚、自愈、安全配置管理、资源管理、自动伸缩、监控、服务健康检查等。
Kubernetes通过这些特性解决了生产环境中Docker存在的问题。Kubernetes和Docker相辅相成Kubernetes的成功也使Docker有了更大规模的使用最终使得 Docker 成为比虚拟机更流行的计算资源提供方式。
接下来我围绕着下面这张架构图来介绍K8SKubernetes的基本概念
![图片](https://static001.geekbang.org/resource/image/ee/7c/ee25460fdbc4b257440dd4f6b109237c.jpg?wh=1920x1149)
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**负责维持容器的生命周期,同时也负责 volumeCVI和网络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界面如下图所示
![图片](https://static001.geekbang.org/resource/image/5c/49/5c6acce4e90048e63426b9e896be8b49.png?wh=1920x1148)
* kubectl是Kubernetes的客户端工具提供了非常多的命令、子命令、命令行选项支持开发或运维人员在命令行快速操作Kubernetes集群例如对各类Kubernetes资源进行增删改查操作给资源打标签等等。下面是执行`kubectl describe service iam-pump`命令获取`iam-pump`详细信息的命令行截图:
![图片](https://static001.geekbang.org/resource/image/60/38/6046e3586eefce16b923aebbf0de2538.png?wh=1269x721)
Kubernetes有多种多样的Objects如果要查看所有Objects的Kind可以使用命令`kubectl api-resources`。我们通过这些Objects来完成Kubernetes各类资源的创建、删除等操作。因为我们这一讲的核心目的是介绍云原生技术的演进所以不会详细介绍Kubernetes资源对象的使用方式。你如果感兴趣可以查看[Kubernetes官方文档](https://kubernetes.io/zh/docs/concepts/overview/working-with-objects/kubernetes-objects/)。
我这里简单介绍一下**Kubernetes对象**的一些基本信息以及在架构图中出现的Deployment、Pod、Service三种对象。
下面是一个典型的Kubernetes对象YAML描述文件
```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镜像和命令
```yaml
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的示例
```yaml
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服务器
```yaml
apiVersion: v1
kind: Service
metadata:
name: my-nginx
labels:
run: my-nginx
spec:
ports:
- port: 80
protocol: TCP
selector:
run: my-nginx
```
最后我还想介绍下**基于Kubernetes的容器云平台**。各大公有云厂商都有基于Kubernetes的容器管理平台目前国内容器服务平台做得比较好的有[腾讯云容器服务TKE](https://cloud.tencent.com/document/product/457/6759)、[阿里云容器服务ACK](https://help.aliyun.com/product/85222.html)。
TKE基于原生 Kubernetes ,提供以容器为核心的解决方案,解决用户开发、测试及运维过程的环境问题,帮助用户降低成本、提高效率。腾讯云容器服务 TKE 完全兼容原生 Kubernetes API并扩展了腾讯云的云硬盘、负载均衡等 Kubernetes 插件,同时以腾讯云私有网络为基础,实现了高可靠、高性能的网络方案。
### Serverless阶段
容器阶段之后虚拟化技术的演进方向是什么呢我们接着来看下Serverless阶段。
在2014年的时候AWS推出了Lambda服务这是一个Serverless服务。从此Serverless越来越引人注意成为了这几年最受关注的技术。我先介绍下什么是Serverless。
Serverless直译过来就是无服务器无服务器并不代表Serverless真的不需要服务器只不过服务器的管理以及资源的分配部分对用户不可见而是由平台开发商维护。Serverless不是具体的一个编程框架、类库或者工具它是一种软件系统架构思想和方法。它的核心思想是用户无需关注支撑应用服务运行的底层资源比如CPU、内存和数据库等只需要关注自己的业务开发就行了。
Serverless具有很多特点核心特点主要有下面这几个。
* 无穷弹性计算能力:根据请求,自动水平扩容实例,拥有近乎无限的扩容能力。
* “零”运维:不需要申请和运维服务器。
* 极致的伸缩能力能够根据CPU、内存、请求量等指标敏感地弹性伸缩并支持缩容到 0。
* 按量计费:真正按使用量去计费。
在我看来Serverless有3种技术形态分别是云函数、Serverless容器、BaaSBackend as a Service如下图
![图片](https://static001.geekbang.org/resource/image/cb/19/cba931763a846ab8008e5600cd6e5419.jpg?wh=1920x641)
这3种Serverless技术形态中Serverless容器是核心云函数和BaaS起辅助作用。Serverless容器可以承载业务的核心架构云函数则可以很好地适配触发器场景BaaS则可以满足我们对各种其他Serverless组件的需求例如Serverless数据库、Serverless存储等。
这3种技术形态各大公用云厂商都早已有相应的产品其中比较优秀的产品是腾讯云推出的Serverless产品SCF、EKS和TDSQL-C。下面我分别介绍下。
* [EKS](https://cloud.tencent.com/document/product/457/39804)弹性容器服务Elastic Kubernetes Service是腾讯云容器服务推出的无需用户购买节点即可部署工作负载的服务模式。EKS 完全兼容原生 Kubernetes支持使用原生方式购买及管理资源按照容器真实使用的资源量计费。
* [SCF](https://cloud.tencent.com/document/product/583)云函数Serverless Cloud Function是腾讯云为企业和开发者们提供的无服务器执行环境帮助你在无需购买和管理服务器的情况下运行代码。你只需使用平台支持的语言编写核心代码并设置代码运行的条件就能在腾讯云基础设施上弹性、安全地运行代码。
* [TDSQL-C](https://cloud.tencent.com/document/product/1003/30488)云原生数据库Cloud Native Database TDSQL-C是腾讯云自研的新一代高性能高可用的企业级分布式云数据库具有高吞吐量、高可靠性等优点。
我们开始的时候提到应用、系统资源、应用生命周期管理这3个维度构成了我们对云的所有诉求。那么到这里系统资源维度的技术演进我就介绍完了。下一讲我会介绍应用维度和应用生命周期管理维度的技术演进。
## 总结
这一讲,我主要通过虚拟化技术的演进,介绍了系统资源维度的技术演进。
虚拟化技术的演进流程为:物理机阶段 -> 虚拟机阶段 -> 容器阶段 -> Serverless阶段。其中物理机到虚拟机阶段的演进技术主要是为了解决x86架构的虚拟化漏洞。要虚拟CPU、内存和I/O就需要捕获其中的敏感指令防止这些敏感指令修改系统状态影响系统的稳定性。x86架构有些敏感指令不是特权指令导致这些指令可以从客户机中直接在物理CPU上执行从而可能会影响系统状态。所以我们说x86架构是有虚拟化漏洞的。
在虚拟机阶段又诞生了3种不同的虚拟化技术分别是软件辅助的完全虚拟化、半虚拟化和硬件辅助的完全虚拟化。因为硬件辅助的完全虚拟化技术不需要修改客户机内核并且有着接近物理机的性能所以成为当前的虚拟化主流技术并以KVM为事实技术标准。
因为容器技术比虚拟机更加轻量再加上Docker、Kubernetes项目的诞生使得大规模使用容器技术变得可行所以这几年系统资源的提供形态已经由虚拟机转变成了容器。
系统资源的最终形态我认为会是Serverless。Serverless技术中又分为3种技术形态云函数、Serverless容器和BaaS。在业务架构Serverless化的过程中整个部署架构会以Serverless容器为主云函数为辅。
## 课后练习
1. Docker的隔离性比虚拟机弱一些思考下有没有一种更好的方式既可以快速启动一个轻量级的容器又拥有比Docker更好的隔离性
2. 思考下如何将一个普通的Kubernetes集群转变为Serverless化的Kubernetes集群。
欢迎你在留言区与我交流讨论,我们下一讲见。