⌨️ 第六章 Web技术与安全
📄 本篇一句话

虚拟机=软件装出来的整台电脑(带内核,重而隔离);Docker 容器=共享内核的轻量隔离盒(秒开、省资源);Vagrant=给虚拟机写「开机剧本」的自动化工具——三者都在回答同一问题:怎么把一台机器变成可复制、可丢弃的。

📝 在本章的位置

上游:6-12 的 VPS 靠虚拟机切分、树莓派课 9-1 的「有没有操作系统」分水岭在这里重逢(虚拟机有、容器与 Pico 都借宿主的)。下游:6-15 的系统调用解释容器「共享内核」的物理含义。

一、虚拟机:软件造的整台电脑

VM(Virtual Machine)=用虚拟机监视器(Hypervisor,如 VirtualBox/VMware/KVM)在真硬件上模拟出多台完整电脑,每台有自己的操作系统:

物理机 ── Hypervisor ──┬── VM1(完整 Linux,10GB)
                       └── VM2(完整 Windows,20GB)

二、Docker:共享内核的轻量盒

Docker 容器不装操作系统——所有容器共享宿主机内核,只打包应用+依赖(MB 级、秒开):

物理机 ── 宿主 Linux 内核 ──┬── 容器1(Python 应用,50MB)
                            ├── 容器2(Nginx,20MB)
                            └── 容器3(MySQL,150MB)

三、Vagrant:虚拟机的开机剧本

Vagrant 管 VM 层的自动化:一个 Vagrantfile 描述「用哪个镜像、配什么网络、装什么」,一条 vagrant up 全部就绪——解决「虚拟机装一半环境对不上」的重复劳动(定位类似 Dockerfile 之于容器)。如今云上多用 Terraform/Ansible,但「环境即代码」的思想是它推广的。

动手 Demo:虚拟机 vs 容器,重量差多少(概念实测)

# 没装 Docker 也能体会「共享 vs 独立」:用进程隔离类比
import subprocess, os, sys

# ① 子进程 = 类似容器:共享当前 Python 解释器(内核),轻
code_light = 'print("轻量单元:复用宿主环境,启动开销极小")'
r = subprocess.run([sys.executable, "-c", code_light], capture_output=True, text=True)
print(r.stdout.strip())

# ② 模拟虚拟机的「完整环境」:一个全新解释器要完整初始化
code_heavy = '''
import sys, json, encodings, encodings.utf_8, encodings.cp1252
print("完整单元:自带全套初始化(类比 VM 自带内核),开销大")
'''
r = subprocess.run([sys.executable, "-c", code_heavy], capture_output=True, text=True)
print(r.stdout.strip())

# ③ 容器隔离的内核依据:同一台机器只有一个内核
print("宿主内核:", os.name, "| 所有容器共享它")

看到什么算成功:两段子进程都成功打印;最后一行说明操作系统只有一个——容器(子进程类比)借宿主环境轻装上阵,VM(完整初始化类比)自成体系开销大。

读结果:类比的准确处=开销差异源于「复用还是自带」;不准确处=真容器的隔离(namespace)远强于进程,这正是它比普通进程安全的原因。

30 秒实验

Windows 上若装过 Docker Desktop,跑 docker run hello-world:观察输出——它从远端拉了几 MB 的镜像、跑完即删。再跑 docker images 看这个镜像多大(约 13KB~几 MB),对比任何一个 VM 镜像(GB 级)——轻重的数量级差距亲眼所见。没装 Docker 也没关系:VirtualBox 里装一次系统的时间就是最好的对照组。

常见误区

自测三问(点击展开) 1. **VM 与容器最本质的差别?** 答:VM 自带完整内核(重、隔离强);容器共享宿主内核(轻、秒开、隔离弱于 VM)。 2. **容器隔离靠什么机制?** 答:Linux namespace(视野隔离)+ cgroups(资源限额),内核提供的机制。 3. **「环境即代码」指什么?** 答:环境定义写成文件(Vagrantfile/Dockerfile),一条命令可重建——环境可版本化可复制。

相关笔记