# 《云计算那些事儿:从IaaS到PaaS进阶》知识点全解 > AI生成|2026年10月29日|codebuddy|原书:陈晓宇《云计算那些事儿:从IaaS到PaaS进阶》,电子工业出版社,2020-01-01 > **我的阅读**:进度 100%|累计 5小时23分钟|开始 2023-07-09|最近 2023-07-29|读完 2023-07-25 **一句话总结**:把"一台物理机怎么变成很多台可交付的虚拟机,再变成一堆可编排的容器"这条技术链路讲通——从虚拟化的三大件(CPU/内存/IO)到 OpenStack 的资源编排,再到 Docker 的隔离原理与 Kubernetes 的声明式调度,最终落到 PaaS 平台与云原生应用。 **适合谁 / 前置知识**:适合有 Linux 基础、想从"会用云主机"进阶到"懂云平台内部"的开发、运维、架构师,也适合准备云平台面试的人做体系化串联。不适合零基础——书中大量出现内核参数、网络协议、源码片段和命令,缺 Linux 与 TCP/IP 底子会读成名词表。前置:Linux 进程与权限模型、网络分层与路由交换基础、一门语言的动手能力(书中涉及 Go)。 ## 一、全书地图 全书是一条单向递进的技术栈,前半段解决"资源怎么切",后半段解决"应用怎么跑"。 | 部分 | 章节 | 主题 | 在全书中的位置 | |---|---|---|---| | 引子 | 第1章 云计算概览 | 定义、发展、分类(IaaS/PaaS/SaaS)、架构、关键技术、优势与风险、AWS、相关概念 | 建立坐标系,后面所有技术都挂在这张图上 | | IaaS 基础 | 第2章 虚拟化与IaaS | 虚拟化优势、IaaS 的服务边界 | 从"云"落到"虚拟化"这一实现手段 | | IaaS 三大件 | 第3章 计算虚拟化 | CPU 虚拟化、内存虚拟化、主流软件、Libvirt、KVM、镜像格式转换、cloud-init | 算力的抽象 | | | 第4章 存储虚拟化 | 演进、存储基础、分类、分布式存储架构、开源存储、华为 FusionStorage | 存储的抽象 | | | 第5章 网络虚拟化 | 网络基础、数据中心网络架构、隧道技术、虚拟网络设备、SDN | 网络的抽象,也是三者中最难的一块 | | IaaS 编排 | 第6章 OpenStack | DevStack 启动、整体架构、CloudStack 对比 | 把三大件组装成可运营的云平台 | | PaaS 起点 | 第7章 Docker容器 | 容器定义、与虚拟机区别、镜像、安装、命令、Dockerfile、进阶、架构与源码、Pouch、Kata | 从"机器级隔离"切到"进程级隔离" | | PaaS 原理 | 第8章 Docker实现原理 | cgroup、namespace、Union Filesystem、chroot/pivot_root、50 行代码造容器 | 回答"容器为什么轻" | | PaaS 编排 | 第9章 Kubernetes基础 | Yaml 与声明式 API、资源定义、物理资源抽象、资源限制、编译、安装、运维 | 单机容器走向集群 | | | 第10章 Kubernetes进阶 | 数据注入、Pod 生命周期、CNI、CRI、CSI、高级特性 | 集群走向可生产 | 三条主线可以这样记:**隔离线**(虚拟机 → 容器 → Pod)、**抽象线**(物理资源 → 虚拟资源 → 声明式资源对象)、**接口线**(Libvirt → CNI/CRI/CSI,都是"上层不关心下层怎么做")。 ## 二、核心知识点 ### 1. 云计算的三种服务模型与五个基本特征 **是什么**:IaaS 交付计算/存储/网络等基础资源,用户管操作系统以上;PaaS 交付运行环境与中间件,用户只管应用;SaaS 交付可直接使用的软件。公认的五个特征是按需自服务、广泛网络访问、资源池化、快速弹性、可计量服务。 **为什么重要**:这三种模型不是厂商话术,而是**责任分界线**。你选 IaaS,打补丁、扩缩容、高可用都得自己扛;选 PaaS,平台替你扛运行时,代价是技术栈被约束。 **怎么用**:评估一个云产品时先问"它替我管到哪一层",再看这层之上我还剩多少工作量。自建机房 vs 云主机 vs 容器平台 vs 托管数据库,本质是责任线在移动。 **常见误区**:把"虚拟化"等同于"云"。虚拟化只是资源池化的技术手段,缺了自服务门户、计量计费、多租户隔离和自动化编排,只是"一堆虚拟机"。 ### 2. 虚拟化的本质:Hypervisor 截获特权操作 **是什么**:Hypervisor(VMM)在硬件与 Guest OS 之间加一层,让 Guest 以为自己独占硬件。Type 1 裸金属型(ESXi、Xen、KVM 寄宿在 Linux 内核中但形态接近 Type 1)直接跑在硬件上;Type 2 寄宿型(VirtualBox、VMware Workstation)跑在宿主 OS 上。 **为什么重要**:所有"虚拟化难题"都来自同一个矛盾——Guest 内核执行特权指令时,硬件真正的主人是谁。CPU、内存、IO 的虚拟化都是这个矛盾的三种解法。 **怎么用**:生产环境优先 Type 1 或 KVM 这类内核态方案,减少一层调度损耗;桌面调试用 Type 2 图方便。 **常见误区**:以为虚拟机性能损耗主要来自"多了一层软件"。实际损耗集中在意外的 VM Exit、内存地址转换(TLB)和 IO 路径上,CPU 计算本身接近原生。 ### 3. CPU 虚拟化:从"陷入-模拟"到硬件辅助 **是什么**:x86 早期特权指令在 Guest 中执行不会自动陷入,于是有三条路:全虚拟化的**二进制翻译**(运行时改写敏感指令)、**半虚拟化**(改 Guest 内核,用 hypercall 主动让渡,如 Xen PV)、**硬件辅助**(Intel VT-x 引入 VMX 根/非根模式,AMD-V 类似,敏感指令自动触发 VM Exit)。 **为什么重要**:这是理解"虚拟化开销从哪来"的起点——每次 VM Exit 都是一次上下文切换,频繁 IO 会放大成本。 **怎么用**:`lscpu | grep -i vmx`(或 svm)确认硬件支持;KVM 场景下在 XML 里配 CPU model 与拓扑(vCPU 绑核、NUMA 亲和)来降低跨 NUMA 访问。 **常见误区**:给虚拟机分配的 vCPU 总数超过物理核数还期待性能线性叠加。超分适合 CPU 利用率低的场景,遇到计算密集负载会互相抢。 ### 4. 内存虚拟化:影子页表与 EPT/NPT **是什么**:Guest 里是虚拟地址→Guest 物理地址,硬件要的是虚拟地址→机器地址,中间差一层。软件方案是**影子页表**(Hypervisor 为每个 Guest 维护一份合并页表,Guest 改页表时要同步,开销大);硬件方案是 **Intel EPT / AMD NPT**,用二级页表让 MMU 直接完成两级转换。 **为什么重要**:内存虚拟化直接决定数据库、缓存类负载的表现;EPT 还引出"脏页跟踪"和迁移时的内存拷贝问题。 **怎么用**:关注 ballooning(气球驱动回收空闲内存)、KSM(同页合并,省内存但吃 CPU)、大页(HugePages,减少 TLB miss)。 **常见误区**:把 KSM 当成免费的省内存神器。它在内存富余时收益低、在 CPU 紧张时是负担,且存在侧信道风险,多租户环境要谨慎。 ### 5. 存储虚拟化:块、文件、对象与分布式底座 **是什么**:块存储给裸设备(云硬盘),文件存储给共享目录(NFS/CephFS),对象存储给 HTTP 键值访问(S3 风格、Swift、RGW)。分布式存储把多节点本地盘聚合成一个池,靠**多副本**或**纠删码**保证可靠。 **为什么重要**:云的弹性很大程度上是存储的弹性。副本数决定可用性与成本,纠删码用算力换容量,选型就是在这两者间做交易。 **怎么用**:三副本适合热数据与低延迟场景(恢复快、写放大可控);纠删码适合冷数据、大容量归档(空间利用率高,但重建时网络与 CPU 压力大)。Ceph 一类系统通常把 RADOS 作底座,上面对外提供 RBD(块)、CephFS(文件)、RGW(对象)三种接口。 **常见误区**:把"分布式"当成"高可靠"。没有合理的故障域划分(机架、可用区),三副本也可能一起挂。 ### 6. 网络虚拟化:Overlay 隧道 + 虚拟交换 + SDN **是什么**:Underlay 是物理网络,Overlay 在它之上用隧道封装出隔离的虚拟网络。VXLAN 把二层帧封进 UDP,用 24 位 VNI 标识租户,突破 VLAN 仅 12 位(约四千个)的限制;GRE 是另一种封装选择。虚拟交换机(如 Open vSwitch)在主机内连接 vNIC、隧道和物理网卡。SDN 的核心是**控制平面与数据平面分离**,由集中控制器下发流表,而不是每台设备各跑各的协议。 **为什么重要**:云的"网络即服务"——安全组、弹性 IP、负载均衡、VPC 互通——全都建立在可编程的虚拟网络上。 **怎么用**:排查虚机不通时按层走:Guest 网卡与路由 → 虚拟交换机流表/端口 → 隧道端点连通性(VNI、MTU)→ 物理 Underlay。MTU 是最常见的隐形杀手,封装头会吃掉几十字节。 **常见误区**:以为 VXLAN 自带加密。它只做隔离与封装,跨不可信链路仍需 IPsec 等加密手段。 ### 7. OpenStack:无共享、消息队列驱动的资源编排 **是什么**:一组松耦合服务通过 REST API 与消息队列协作。Keystone 管认证与目录,Nova 管计算生命周期,Neutron 管网络,Cinder 管块存储,Glance 管镜像,Swift 管对象存储,Horizon 是门户。各服务无共享状态,可独立部署与横向扩展。 **为什么重要**:它是"如何把虚拟化三大件组织成一个云"的经典答案,也是理解后来 K8s 架构的对照物——两者都是"API + 控制器 + 消息/事件"的分布式协作。 **怎么用**:用 DevStack 一键拉起单机环境做实验;理解一次创建虚机的链路:Keystone 鉴权 → Nova API 落库 → Scheduler 选主机 → Compute 调 Libvirt 起域 → Neutron 配端口 → Cinder 挂卷。 **常见误区**:把 OpenStack 当成一个"软件"来装。它是十几个服务的组合,版本兼容矩阵、消息队列、数据库才是运维的主要痛点。 ### 8. 容器与虚拟机:共享内核带来的轻与险 **是什么**:虚拟机虚拟化硬件,每个 Guest 有自己的内核;容器共享宿主内核,用 namespace 做视图隔离、cgroup 做资源限制、UnionFS 做分层文件系统。因此容器启动是毫秒到秒级,虚拟机是秒到分钟级。 **为什么重要**:这个差别决定了两者的适用边界——容器密度高、交付快,但隔离强度弱于虚拟机;内核漏洞与 noisy neighbor 的暴露面更大。 **怎么用**:多租户强隔离用虚拟机或 Kata Containers(轻量虚拟机 + 容器接口,兼顾隔离与镜像生态);内部微服务用普通容器;需要内核定制或多 OS 的场景必须用虚拟机。 **常见误区**:"容器是轻量级虚拟机"。它不是缩小版虚拟机,而是一个被限制了视野和资源的普通进程。`ps` 在宿主机上一看便知。 ### 9. 容器的三大基石:namespace / cgroup / UnionFS **是什么**:namespace 负责"看不见"——PID、NET、MNT、UTS、IPC、USER 等,让进程有独立的视图;cgroup 负责"用多少"——CPU、内存、IO、PID 数的配额与统计,v2 把层级统一为单一树;UnionFS(如 overlay2)负责"叠起来"——镜像的只读层加上容器可写层,写时复制。 **为什么重要**:三条腿缺一不可。只有 namespace 是沙箱不是容器,只有 cgroup 是限流不是隔离,只有 UnionFS 是打包不是运行。 **怎么用**:`unshare`、`nsenter` 手动体验隔离;看 `cat /proc//cgroup` 确认配额;`docker history` 看镜像分层,理解为什么把易变内容放最后一层。 **常见误区**:以为容器里的 root 就是宿主 root。默认不是——用户 namespace 未开启时,容器内 UID 0 映射到宿主 UID 0,这是真实的提权风险。 ### 10. 镜像与 Dockerfile:分层缓存是性能也是债 **是什么**:镜像由一系列只读层组成,每层对应 Dockerfile 的一条指令;容器启动时在顶部加一个可写层,删除文件只是在上层打白障(whiteout)。 **为什么重要**:分层让分发与构建都变快(复用缓存、只传增量),但也带来"镜像越滚越大"和"删了文件体积不降"的困惑。 **怎么用**:把不常变的指令放前面(基础镜像、依赖安装),把 COPY 源码放后面;多阶段构建(multi-stage)把编译环境留在构建阶段,产物拷进精简运行镜像;用 `.dockerignore` 控制上下文大小。 **常见误区**:在一条 RUN 里 `apt install` 后又 `rm` 缓存,却分成两条 RUN——分层已固化,删不掉上一层的体积,必须同层清理。 ### 11. 声明式 API 与控制器循环 **是什么**:Yaml 描述"期望状态",API Server 落盘到 etcd,各控制器持续比对"期望"与"实际"并驱动收敛(reconcile)。与之相对的命令式是"执行一步步操作"。 **为什么重要**:声明式带来幂等与自愈——重复 apply 结果一致,节点挂了控制器会重新拉起副本。这也是 GitOps、IaC 的思想基础。 **怎么用**:所有变更走 `kubectl apply -f`,把 Yaml 纳入版本控制;排查时先看 `kubectl get` 的实际状态与 `describe` 的 Events,再反推哪个控制器没收敛。 **常见误区**:手工 `kubectl edit` 改线上对象。下次 apply 会被覆盖,且变更无审计。临时排障可以,长期必须回写清单。 ### 12. 资源模型:Pod、工作负载与 Service **是什么**:Pod 是最小调度单元,可含多个共享网络与存储的容器(边车模式的基础);Deployment 管无状态副本与滚动更新,StatefulSet 管有状态与稳定标识,DaemonSet 保证每节点一份;Service 用标签选择器 + 虚拟 IP 给一组 Pod 提供稳定入口。 **为什么重要**:Pod 会被频繁重建、IP 会变,所以必须有一层稳定抽象。理解了"Pod 是一次性的、Service 是稳定的",才算入门。 **怎么用**:给容器配 requests(调度依据)和 limits(上限);区分 CPU 可压缩与内存不可压缩——内存超 limit 会被 OOMKilled,CPU 超了只是被节流。配置就绪探针(readiness)避免流量打到未启动完的实例,存活探针(liveness)触发重启。 **常见误区**:不设 requests 就上线,调度器只能按"零需求"摆放,节点超卖后互相踩踏;探针配得过激,导致正常启动被反复杀死。 ### 13. 三大接口:CNI / CRI / CSI 的解耦哲学 **是什么**:CNI 规定容器网络如何插拔(Calico、Flannel 等实现),CRI 规定 kubelet 如何调用容器运行时(containerd、CRI-O),CSI 规定存储如何挂载(各厂商驱动)。 **为什么重要**:三个"接口标准"把 K8s 从"绑定 Docker + 特定网络 + 特定存储"解放出来,形成生态。这也是为什么 Docker 被从运行时链路中移除(dockershim 废弃)而 K8s 不受影响。 **怎么用**:选型时把三者当独立维度评估——网络看是否需要 NetworkPolicy 与 BGP 性能,运行时看隔离与镜像生态,存储看访问模式(RWO/ROX/RWX)与延迟要求。 **常见误区**:以为换了 CNI 就能随便改 Pod CIDR。地址段与底层路由、云厂商 VPC 路由表要对齐,改错直接全网不通。 ### 14. Pod 生命周期与数据注入 **是什么**:Pod 从 Pending → ContainerCreating → Running → Succeeded/Failed,中间经历调度、拉镜像、初始化容器(initContainers)、启动后钩子。配置通过环境变量、ConfigMap、Secret、volume 挂载注入。 **为什么重要**:大部分"起不来"的问题都发生在这条链路的某一环,按阶段定位比盲查日志快得多。 **怎么用**:initContainer 做依赖等待与初始化(如等数据库就绪、改目录权限);ConfigMap 存非敏感配置,Secret 存凭据(注意默认只是 base64 编码,不是加密,需要开启静态加密);需要热更新用 volume 挂载,环境变量方式不会自动更新。 **常见误区**:把 Secret 当保险箱。能读 etcd 或能 `get secret` 的人就能拿到明文,RBAC 与加密配置才是关键。 ### 15. 云原生与 PaaS:平台该替用户承担什么 **是什么**:云原生不是"上云",而是一组实践:容器化封装、声明式编排、不可变基础设施、微服务与持续交付。PaaS 平台把这些能力产品化,让开发者只提交代码或镜像。 **为什么重要**:平台的价值等于"替用户消除的重复劳动"。判断一个 PaaS 好不好,就看它把构建、发布、扩缩、可观测、灰度这些环节自动化到了什么程度。 **怎么用**:构建内部 PaaS 时先划边界——是只做 CI/CD 流水线 + K8s 部署,还是连中间件、服务治理、监控一起托管;前者轻、落地快,后者体验好、耦合深。不可变基础设施意味着改配置就重建,而不是登录机器改文件。 **常见误区**:以为买了 K8s 就是有了 PaaS。K8s 是编排内核,缺少发布策略、多租户、配额、审计、可观测性,它离"开发者自助"还有一段产品化距离。 ## 三、关键概念速查表 | 概念 | 一句话解释 | 用在哪儿 | |---|---|---| | Hypervisor | 介于硬件与 Guest OS 之间的虚拟化层 | 虚拟机创建与运行 | | VT-x / AMD-V | CPU 硬件辅助虚拟化指令集 | 降低 VM Exit 开销 | | EPT / NPT | 二级页表,硬件完成 Guest 物理地址到机器地址转换 | 内存虚拟化性能 | | 影子页表 | 软件维护的合并页表 | 无硬件辅助时的内存虚拟化 | | Libvirt | 统一管理虚拟化后端的 API 与守护进程 | OpenStack Nova 调 KVM | | QEMU | 提供设备模拟与 IO 处理的虚拟机监视器 | 与 KVM 配合形成完整虚机 | | cloud-init | 虚机首次启动时的初始化框架 | 注入主机名、密钥、网络配置 | | VLAN / VXLAN | 二层隔离标识,12 位 / 24 位 VNI 封装于 UDP | 租户网络隔离,突破 4094 上限 | | OVS | 开源虚拟交换机,支持流表与隧道 | 主机内虚拟网络接入 | | SDN | 控制平面与数据平面分离,集中式下发策略 | 云网络自动化与安全组 | | Ceph | 统一分布式存储,提供块/文件/对象三种接口 | 云平台后端存储池 | | 纠删码 | 用校验分片替代整副本,省空间费算力 | 冷数据、大容量存储 | | Namespace | 内核级的视图隔离机制 | 容器进程/网络/挂载隔离 | | Cgroup | 内核级的资源配额与统计机制 | 容器 CPU/内存限制 | | UnionFS / overlay2 | 分层叠加的联合文件系统 | 镜像分层与写时复制 | | Dockerfile | 镜像构建脚本,一条指令一层 | 应用打包与 CI 构建 | | 声明式 API | 提交期望状态,由控制器收敛 | K8s 全部资源对象 | | Pod | 最小调度单元,共享网络与存储的容器组 | 应用部署的基本单位 | | Service | 为 Pod 组提供稳定虚拟 IP 与负载均衡 | 服务发现与东西向流量 | | CNI / CRI / CSI | 网络 / 运行时 / 存储的插件接口标准 | K8s 生态解耦 | | Kata Containers | 用轻量虚拟机承载容器,兼顾隔离与镜像生态 | 多租户强隔离场景 | ## 四、可复用的方法/框架 **A. 云技术选型四问** 1. 责任边界在哪:这部分运维我是否愿意长期承担? 2. 隔离强度够不够:多租户、不可信代码、合规要求分别需要什么级别的隔离? 3. 弹性粒度对不对:分钟级(虚机)还是秒级(容器)能满足业务波峰? 4. 退出成本有多高:数据格式、API、编排描述是否可迁移? **B. 虚拟化/容器排障的分层法** 自下而上五层:物理与内核(dmesg、资源水位)→ 虚拟化层(Libvirt/运行时日志)→ 网络(端口、流表、隧道、MTU)→ 存储(挂载、IO 延迟、配额)→ 应用(进程、配置、探针)。每层先确认"这一层是否正常"再往上,避免在应用日志里找网络问题。 **C. 镜像瘦身与构建的检查清单** 基础镜像是否最小(alpine/distroless)→ 是否多阶段构建 → 依赖安装与清理是否同层 → 是否用 .dockerignore 缩小上下文 → 是否固定基础镜像 tag/digest → 是否以非 root 运行。 **D. 从 IaaS 到 PaaS 的能力成熟度阶梯** 手工装机 → 脚本化 → 虚拟化池化 → 自助门户与计量 → 容器化交付 → 声明式编排 → 平台化自助(含灰度、可观测、多租户)。判断团队该走到哪一级,看的是"重复劳动最多的环节在哪",而不是追最新技术。 **E. 读源码的方法(书中对 KVM、Docker、K8s 都用了这招)** 先跑通最小可用示例 → 找到入口函数/命令 → 顺调用链画时序 → 只深挖一条主路径(如"创建容器")→ 用日志或断点验证假设。不要试图通读全部代码。 ## 五、我的阅读轨迹 | 项目 | 数据 | |---|---| | 进度 | 100% | | 累计阅读 | 5小时23分钟 | | 开始阅读 | 2023-07-09 | | 最近阅读 | 2023-07-29 | | 读完时间 | 2023-07-25 | **复习建议**:本书已读完,且阅读跨度集中(约三周、5 小时出头),属于"快速通读"而非精读——按 40 万字体量估算,这个时长意味着当时主要建立了框架,细节留存有限。建议按以下顺序做二次精读: - **第一优先(原理,最易遗忘)**:第8章 cgroup 与 namespace、第3章 CPU/内存虚拟化。这两块是面试与排障的高频区,建议配合动手实验重读。 - **第二优先(工程量大、易混淆)**:第10章 CNI/CRI/CSI 与第5章隧道技术。概念多、名字像,建议画图整理。 - **第三优先(查阅型)**:第7章 Docker 命令、第9章资源定义。不必背,做成速查卡即可。 - **可略读**:第1章概览、第6章 CloudStack 对比,属于背景信息。 ## 六、行动清单 1. 用 `unshare` + `chroot` 手写一个最小容器,跑通"隔离一个 shell"再退出,验证 namespace 的实际效果。 2. 用 DevStack 或单机 KVM 起一台虚机,完整走一遍 cloud-init 注入主机名与 SSH 密钥的流程。 3. 为现有项目写一个多阶段构建的 Dockerfile,把镜像体积与构建时间各记录一次前后对比。 4. 在本地集群部署一个 Deployment + Service,故意把内存 limit 调低,观察 OOMKilled 与 Events 的表现。 5. 画一张图:一个跨节点 Pod 访问另一个 Pod,数据包依次经过哪些设备、哪些封装与解封装。 6. 把第 10 章的 CNI/CRI/CSI 各选一个具体实现(如 Calico / containerd / 某 CSI 驱动),写清它解决的那一个问题。 7. 整理一份个人"云平台责任边界表",列出当前项目里哪些环节是自建、哪些交给云厂商,标出风险点。 8. 读一遍 Kubernetes 官方文档中 Pod 生命周期与探针章节,与本书第 10 章对照,补齐版本差异(如 dockershim 已移除)。 ## 七、延伸阅读 1. **《深入理解计算机系统》(CS:APP)** — 关联:本书第 3、8 章的虚拟内存、异常控制流、链接与进程,底层答案都在这里。**先读**,作为地基;不必通读,重点看虚拟内存与异常两章。 2. **《Docker 技术入门与实战》** — 关联:本书第 7 章的命令与 Dockerfile 部分偏速览,这本可补齐实战细节与镜像仓库、编排基础。**第二本读**,配合动手。 3. **《Kubernetes 权威指南:从 Docker 到 Kubernetes 实践全接触》** — 关联:接续本书第 9、10 章,把资源对象、调度、网络存储讲得更细,并覆盖版本演进。**最后读**,作为长期案头参考。 顺序建议:CS:APP(补底层)→ Docker 实战(补手感)→ K8s 权威指南(补广度)。本书本身适合作为这三者之间的"路线图",隔几个月回看目录,检查自己哪一段还是空白。