Skip to content

Docker以及虚拟化技术


每个事物发展的早期都会比较混乱,没有统一规格,比如在不断完善中逐渐熵减,计算机也是这样。计算机发展初期,各类计算机平台涌现,使得硬件资源提供的接口与调用方式每个平台之间甚至每个平台的子产品之间都截然不同,十分杂乱,这就是早期出现的跨平台与兼容性的问题。我们知道,程序通过OS提供的API得以调度硬件资源,程序才得以运行。解决程序的跨平台与兼容性问题,实质上是解决API统一的问题,只要起点调用的API统一,终点连接的接口可以对上,那么这个问题就能解决,这就是虚拟化技术。它如同一个多兼容规格的插排,程序可以理解为国内统一的三口插座,通过插排上不同的规格的转换器连接用电器,也就是连接不同的硬件资源,这样,我们从程序的角度,可以忽略掉我的计算机平台是什么,因为我调用的规格已经统一了,在程序的层面上来说,我已经顺利完成我的任务了,接下来的适配不同规格的用电器的工作就交给插排了,也就是虚拟化技术。

image-20231028100009098

资源管理与虚拟化

本质上是对资源管理,更细一点来说,是提高资源的利用率。一般来说资源管理有两种大的方向,一是减少资源占用率,二是提高资源利用率。

高资源占用率未必有高资源利用率,举个简单的例子:一段1w行的屎山代码,跑出来的效果依旧是屎一样。而高资源利用率一般会有较高的资源占用。

虚拟化技术能够提高计算机资源的利用率,也就是将计算机硬件资源拿出来分给另外的程序,使得计算机资源尽量不被浪费。举个例子,我们知道AI炼丹的资源消耗几乎都是GPU,CPU可以说几乎是空闲。合理使用虚拟化技术可以让CPU多多兼职,与GPU一同发光发热,达到更高效的资源利用:

虚拟化前:

CPU:🥶

GPU:🥵

虚拟化后:

CPU:🥵

GPU:🥵

当你理解了如何把硬件资源当牛马用,咳咳,是高效使用,你就理解了虚拟化技术的意义。其实虚拟化技术也是一个工具,既然是工具就一定是来减少人类劳动的,仅此而已。计算机本身就是拿来用的,节约出来的时间更有意义。

资源共享与隔离。在同一个OS下,比如我们的PC主环境,同时可以运行多个程序,但这里的多个程序实际上是打引号的,最简单的例子就是我们开启后端服务不能同时用多个不同的服务监听一个端口,因为端口在同一环境下只能有一个进行占用。这就是资源冲突。虚拟化技术解决的问题之一就是资源冲突,即使用vitural-env进行隔离。

虚拟化的分类

虚拟化的分类,有硬件虚拟化和软件虚拟化两个大方向,而针对实际场景也有更为细化的分类。

  • 硬件虚拟化

    硬件本身有虚拟化支持。比如CPU可以将其它平台的指令集转换为自身的指令集,实现了一台计算机上可以同时运行两种不同平台规格适配的软件,达到一种影分身的效果
  • 软件虚拟化

    通过软件的方式来虚拟化。夹在程序和硬件之间的一个Pipeline,程序通过这条pipeline后,指令就能够被硬件支持
  • 其它

    • 平台虚拟化

      比如Vmware,在OS和硬件之间搭建的虚拟化设施,其运行的单位是操作系统(CentOS, Ubuntu, Kali...)
    • 程序虚拟化

      比如Python VirualEnv,在OS和程序之间搭建的虚拟化设施,其运行的单位是程序/文件
    • 内存虚拟化, 桌面虚拟化

      内存虚拟化:将不相邻的内存区虚拟统一成连续的内存地址,也就是虚拟内存
      桌面虚拟化:比如向日葵、QQ或者windows自带的远程协助,利用了远程资源运行

虚拟机

基于解释执行的虚拟机监视器(Hypervisor)

PHP的HHVM,Java的JVM,本质上都是虚拟机,而虚拟机就是通过虚拟化技术,即“统一’入‘,联通’出‘”这么一套逻辑来实现的跨平台的解决思路,都是通过虚拟机来不断转换最终转换为机器码。但虚拟机在虚拟化过程中带来了很多性能缺失,运行它们要占更多的资源的嘛。就像薯片这种重加工食品,处理的工序多了,自身往往就没什么营养价值了。

容器

程序的运行被隔离在独立的环境中,与虚拟机不同的是,容器技术的效率更高,甚至接近真实环境下的运行效率;而且运行在容器中的应用程序必须支持在真实操作系统上运行,也就是必须遵循硬件平台的指令规则。反应过来的同学好像已经反应过来了,这不是又倒回去了嘛。但正是因为这种限制,性能更高。

虚拟机:
	物理硬件与原操作系统->虚拟机监视器(Hypervisor)
                            ->操作系统1 -> 依赖环境与程序
                            ->操作系统2 -> 依赖环境与程序
                            ->操作系统3	-> 依赖环境与程序
                            ...

容器:
	物理硬件与原操作系统->依赖环境与程序

少了两个维度,直击要害,效率也就更高了。运行在容器里的程序与运行在原操作系统的程序,在指令层面是完全一致的。