深入浅出KVM内存管理——Ansible安全基线配置(一)

简介: 本文介绍了KVM的内存管理机制设计,用于帮助大家更深入理解KVM的内存管理

深入浅出KVM内存管理

概括:KVM、QEMU 和 CPU 的“铁三角”

KVM (Kernel-based Virtual Machine) 本身是 Linux 内核的一个模块,它很“懒”——它自己不模拟硬件,而是利用 CPU 的硬件虚拟化扩展。它真正“干活”是和 QEMU 一起

你可以这样理解:QEMU 负责“模拟”一个完整的PC(主板、磁盘、网卡等),而 KVM 负责“插手”最关键的 CPU 和内存访问,把 QEMU 的模拟操作“抢过来”交给真实的硬件去执行

所以,KVM 的内存机制,本质上是 KVM-QEMU 联手,并深度依赖 CPU 硬件的一套精妙体系

我们详细拆解一下这个机制:


基本框架:Guest 内存 = QEMU 进程的内存

这是理解一切的起点

当你启动一个 KVM 虚拟机时,在你的 Host 主机上,你会看到一个 QEMU 进程(例如 qemu-system-x86_64

你为虚拟机分配 8GB 内存,QEMU 进程就会在 Host 主机上申请 8GB 的虚拟内存(通过 mmap 系统调用,说人话就是内存映射)

  • 从 Host 主机看来: 这 8GB 内存就是 QEMU 进程的普通内存空间。它是受 Host 主机的 Linux 内核管理,可以被 swap(交换)到磁盘,也可以被 KSM 合并(后面会讲)
  • 从 Guest 虚拟机看来: 这 8GB 的内存是它的“物理内存”

核心魔法:二级地址转换 (EPT / NPT)

Guest 虚拟机里的一个程序(比如 Nginx)要访问内存。它走的是:

  1. Guest 虚拟地址 (GVA): 程序用的地址。
  2. Guest 物理地址 (GPA): Guest 操作系统的内核把它转换成的“物理地址”

但是,CPU 真正要访问的是 Host 物理地址 (HPA)(你服务器内存条上的真实地址)

在没有硬件辅助的时代,虚拟机需要“捕获”Guest 的每一次内存访问,用软件模拟(比如“影子页表”),这非常非常慢。

现在,KVM 依赖 CPU 的二级地址转换(SLAT)技术来零开销完成这个转换:

  • Intel 称之为:EPT (Extended Page Tables)
  • AMD 称之为:NPT (Nested Page Tables) 或 RVI (Rapid Virtualization Indexing)

KVM 会为每个虚拟机维护一套 EPT/NPT 页表,这套页表直接告诉 CPU 如何将 GPA 映射到 HPA

整个流程是这样的:

当 Guest 里的程序访问内存时,CPU 会自动地、在硬件层面完成两次转换

  1. GVA -> GPA:使用 Guest 自己的页表(由 Guest OS 维护,存在 CR3 寄存器)
  2. GPA -> HPA:使用 KVM 设置的 EPT/NPT 页表

整个过程一步到位,不需要 KVM 介入,没有 VM-Exit,几乎和裸金属一样快

只有当 Guest 访问的 GPA 在 EPT/NPT 表里不存在(比如缺页)时,才会触发一次 VM-Exit,KVM 这才“醒来”处理,比如给它分配一块新的 Host 内存,并更新 EPT 表


高级内存特性

光有 EPT/NPT 还不够,为了让内存使用更高效、更灵活,KVM (QEMU) 还提供了一系列高级功能

1. 内存超售:KSM (Kernel Same-page Merging)

如果你在 Host 上开了 10 个一模一样的虚拟机,每个 4GB,难道你需要 40GB 物理内存吗?

不需要。这 10 个虚拟机的内存里,有大量页面是完全一样的(比如系统核心文件)

Host 上的 Linux 内核可以开启 KSM 功能。KSM 会在后台扫描所有 QEMU 进程的内存,如果发现两个或多个内容完全相同的内存页,它会:

  1. 合并它们,只在 Host 物理内存中保留一个副本
  2. 让所有原来指向不同副本的页表(EPT 表),都指向这个唯一的副本
  3. 将这个副本标记为写时复刻 (Copy-on-Write, COW)

当任何一个 VM 试图写入这个共享页面时,CPU 会触发保护异常,内核会立刻为这个 VM 复制一个新的私有页面副本,让它去写,而其他 VM 不受影响。这就是内存超售的主要技术之一

2. 动态内存:Virtio Balloon (内存气球)

如果一个 VM 启动时用了 8GB,但是现在只用了 2GB,而另一个 VM 内存又不够了,怎么办?

Virtio Balloon 登场。它主要包含两部分:

  • Host 上的 QEMU: 管理“气球”的充/放气
  • Guest 里的 virtio_balloon 驱动: 必须在 VM 里安装这个驱动

回收内存(气球充气):
QEMU 通知 Guest 里的 virtio_balloon 驱动:“我需要 2GB 内存”。Guest 驱动收到后,就会向 Guest OS 申请 2GB 内存(作为一个普通程序去申请)。Guest OS 以为这个“气球”程序要用,就把它不常用的内存(比如 cache)分配给它。virtio_balloon 拿到这 2GB 内存的“物理地址 (GPA)”后,就告诉 Host:“这 2GB 你拿走吧,别让 Guest OS 碰它们了”。Host 随后就可以把这 2GB 对应的 HPA 分配给其他 VM

归还内存(气球放气):
反之,Host 释放对这 2GB 内存的占用,并通知 Guest 驱动:“你可以把那 2GB 还给你对应的 Guset OS 了”

3. 性能优化:Huge Pages (大页)

CPU 访问内存快,是因为有 TLB (Translation Lookaside Buffer) 这个高速缓存,它缓存了 GVA -> HPA 的映射关系

但是 TLB 的容量有限。如果都用 4KB 的小页面,一个 8GB 的 VM 需要 2,097,152 个页表项。TLB 根本存不下,就会造成 TLB Miss(说人话就是“缓存未命中”),CPU 就得去内存里重新查询页表(Page Walk),性能下降

Huge Pages(大页)允许使用 2MB 甚至 1GB 的大页面

对比:

  • 4KB 小页: 8GB / 4KB = 2,097,152 个页表项 (TLB 存不下)
  • 2MB 大页: 8GB / 2MB = 4,096 个页表项 (TLB 妥妥存下)

KVM/QEMU 可以配置使用 Host 上的“透明大页 (THP)”或“静态大页 (Hugetlbfs)”,极大地减少 TLB Miss,提升内存密集型应用的性能

4. NUMA 架构支持 (vNUMA)

在大型多 CPU 插槽的服务器上,内存是分布在不同 CPU 节点(Node)上的。CPU 访问”本地“内存(在自己的 Node 上)非常快,访问”远程“内存(在其他 CPU Node 上)就慢很多,这就是 NUMA

KVM/QEMU 支持 vNUMA,它可以把 Host 上的 NUMA 拓扑映射给 Guest

这样,Guest OS 也能”感知“到 NUMA 架构,它会智能地调度,尽量让运行在 vCPU 0 上的程序,去使用 vNode 0 上的内存。而 KVM 会确保 vCPU 0 真的跑在 CPU 0 上,vNode 0 的内存也真的分配在 Node 0 的物理内存上。这避免了昂贵的跨节点内存访问


影响KVM内存效率的因素

天下没有免费的午餐,虚拟化也会引入一些开销

1. 开销:EPT/NPT 页表本身的开销

  • 体现: KVM 需要在 Host 的内存里为每一个 VM 维护一套 EPT/NPT 页表(用来做 GPA -> HPA 映射)。这个页表本身也要占用内存。如果 VM 内存很大,这套页表也会不小
  • 效率影响: 这是空间开销(Overhead)。你开了 VM,哪怕它啥也不干,这部分内存也必须被 KVM 占用

2. 开销:TLB Miss 的“加倍惩罚”

  • 体现: 就像我们聊 TLB Miss 时说的,一旦 Miss 了,CPU 必须去“漫游 (Page Walk)”页表
  • 效率影响: 在 KVM 环境下,这个“漫游”更复杂!CPU 不仅要查 Guest 的页表(GVA->GPA),还要查 KVM 的 EPT 表(GPA->HPA)。这个过程比裸金属更耗时,对 CPU L1/L2 缓存的压力也更大。

    (这就是为什么“大页”在虚拟化中如此重要的原因,它用“空间”(2MB)换“时间”(TLB Miss 次数))

3. 开销:KSM 和 Balloon 的性能抖动

  • 体现:
    • KSM 在扫描内存时,会消耗 CPU
    • 当一个 VM 试图写入一个被 KSM 共享的页面时,会触发“写时复制 (COW)”,这是一个 VM-Exit,会造成一次轻微的性能抖动(Latency Spike)
    • Balloon 充气(回收内存)太猛,可能导致 Guest OS 开始错误地将内存 Swap 到磁盘,造成灾难性的“双重交换”(Guest 往虚拟磁盘写,Host 又把这个“磁盘文件”的数据换出到物理 Swap
  • 效率影响: “省钱”(密度)的代价是牺牲了一点点 CPU 性能和潜在的延迟稳定性

总结:一个(有点复杂的)公寓比喻

  • Host 主机: 公寓大楼的物业
  • QEMU 进程: 一间公寓(一个 VM)
  • Guest OS: 公寓的租户
  • Guest "物理"内存 (GPA): 租户脑子里的“公寓平面图”(比如“我的卧室”、“我的客厅”)
  • Host "物理"内存 (HPA): 物业持有的大楼真实设计图(比如“503室的卧室”在“大楼 5 楼 A 区”)
  • EPT/NPT (SLAT): 一个超级翻译器。租户说“我要去卧室”,翻译器(CPU 硬件)瞬间查询 EPT 表,直接把租户“传送”到了“大楼 5 楼 A 区”
  • KSM: 物业发现 A 户和 B 户都买了一模一样的宜家桌子,于是物业把两张桌子都收了,换成一张桌子放在公共区域,并告诉 A 和 B:“你们都来这用吧”。如果 A 要在桌上刻字(写入),物业立刻把桌子(COW)复制一份新的给 A
  • Balloon: 物业(Host)想把 A 户的“客房”租给别人,于是派了个气球(virtio_balloon 驱动)进 A 户,把客房充(占)满。A 户(Guest OS)一看客房被占了,就没法用了。物业就把这个客房(内存)租给了 C 户

KVM 的内存机制就是这样一套结合了 QEMU 进程管理、CPU 硬件加速和 Linux 内核高级特性的复杂系统

目录
相关文章
|
1月前
|
存储 调度 KVM
深入浅出KVM虚拟化技术原理——Ansible安全基线配置(一)
本文深入解析KVM虚拟化核心机制,涵盖内核如何调度QEMU进程与KVM模块协同工作、CPU虚拟化扩展(VT-x/AMD-V)的硬件加速原理,以及存储池的管理与优势,助你全面掌握KVM底层运行逻辑。
248 11
|
1月前
|
Java 数据库 微服务
Java 学习路线可按「基础→进阶→实战→架构」四阶段推进
Java学习路线分四阶段:基础→进阶→实战→架构。涵盖语法、多线程、框架、微服务等核心内容,搭配项目实战与学习技巧,助你系统掌握Java开发技能,逐步成长为高级工程师。(238字)
209 4
|
1月前
|
安全 Ubuntu 应用服务中间件
基于code-server的云端编程环境部署
本文档描述如何在 Ubuntu 主机上部署 code-server(即“网页版 VS Code”),并通过 autossh 将服务反向隧道到跳板机、使用 Nginx 反向代理域名访问、以及使用 certbot 配置 HTTPS。适合在多设备间共享同一开发环境、并解决个人主机动态公网 IP 的访问问题。
488 5
|
26天前
|
存储 Kubernetes 数据库
K3S ——轻量化K8S 入门指南
本文介绍轻量级Kubernetes发行版K3s,适用于边缘计算、IoT等场景。涵盖其架构、安装部署(单节点/高可用/离线)、核心组件、网络存储配置及生产建议,助力快速构建轻量化容器平台。
297 4
|
1月前
|
安全 网络安全 KVM
Ansible多机部署KVM虚拟机——Ansible安全基线配置(二)
本教程介绍如何使用Ansible在多台宿主机上批量部署KVM虚拟机,结合Tailscale与NFS实现安全镜像共享和网络互联。涵盖用户配置、KVM环境初始化、动态创建/删除VM及自动化网络设置,助力构建高效、安全的虚拟化基础设施。(239字)
133 4
|
27天前
|
小程序 JavaScript 关系型数据库
基于微信小程序的民宿预定系统
本项目设计并实现基于微信小程序的民宿预订管理系统,结合MySQL、Vue、Django等技术,整合民宿资源,优化预订流程,提升用户与经营者效率,推动民宿行业信息化发展。
|
24天前
|
人工智能 自然语言处理 安全
Serverless AI 原生架构破局「三高」困境
在 AI 大模型浪潮席卷全球的今天,企业纷纷加速拥抱 AI,推动智能客服、内容生成、流程自动化等场景快速落地。然而,许多企业在实践中却遭遇了“三高困境”——成本高、复杂度高、风险高。Serverless AI 原生架构不仅是技术演进,更是企业智能化转型的关键基础设施。它让开发者聚焦业务逻辑,让企业告别“基建焦虑”,让 AI 真正“飞入寻常百姓家”。
|
1月前
|
监控 安全 Linux
Linux如何部署服务并设置为开机自启
系统ctl命令用于管理Linux服务,包括启动、停止、重启和重载配置等操作。journalctl命令可查看特定服务日志。编写服务文件时需定义[Unit]、[Service]和[Install]部分,通过systemctl管理新服务并设置开机自启。
213 14
|
26天前
|
Kubernetes API 开发工具
深入浅出K8S技术原理,搞懂K8S?这一篇就够了!
本文以“K8S帝国”为喻,系统解析Kubernetes核心技术原理。从声明式API、架构设计到网络、存储、安全、运维生态,深入浅出揭示其自动化编排本质,展现K8S如何成为云时代分布式操作系统的基石。(239字)
566 4
|
10天前
|
人工智能 Java API
【Azure AI Search】如何通过Entra ID RBAC认证连接中国区 Azure AI Search
本文介绍如何在Java SDK中配置中国区AI Search资源访问。由于默认认证地址为全球环境(https://search.azure.com),在中国区需修改为https://search.azure.cn,并通过设置SearchAudience.AZURE_CHINA解决认证失败问题,确保资源正常获取。
100 18