1. 轻量级虚拟化与超融合为什么会互相看对眼
这几年做基础设施的人应该都有同感:虚拟化和容器原本是两条赛道,一边是传统虚拟化平台加集中式存储,一边是容器编排加对象存储,两边各自玩得风生水起。但最近一年,情况明显变了——轻量级虚拟化开始往云原生技术栈里钻,超融合架构也开始主动拥抱容器编排,两边像是突然找到了共同话题。我所在的团队在评估内部私有云下一阶段方案时,正好撞上了这个趋势,索性在测试环境里做了一次完整的 POC。
先说清楚一个概念:轻量级虚拟化,并不是单纯把传统虚拟机做得更小、更省资源。它更像是在容器和虚拟机之间重新划了一条边界。容器的优势是启动快、镜像分层、编排生态成熟,劣势是隔离性依赖内核能力,一旦内核出问题,同宿主上的容器一起遭殃。传统虚拟机隔离性没得说,但启动慢、镜像重、网络存储链条太长,运维习惯也和 DevOps 脱节。轻量级虚拟化的思路,是用内核提供的高效虚拟化机制,把虚拟机的启动时间压到接近容器水平,同时保留完整的 OS 隔离边界。再叠加容器编排的数据面能力,就能让虚拟机像容器一样被调度、被声明、被滚动更新。
超融合这边的情况也很有意思。传统超融合卖点是“计算+存储+网络一体化”,靠的是分布式存储把多台物理主机的本地磁盘汇成一个统一资源池。问题是它的管理面往往还是传统的 Web 管理平台,API 做得再开放,和云原生工具链之间总隔着一层。业务方想用声明式的方式申请一台带 SSD 存储的数据库虚拟机,超融合平台也能给,但流程上要先去管理界面创建模板、配置网络、分配存储,然后再等克隆完成。这套东西跟容器环境下“一条 YAML 搞定一切”的体验相比,落差确实明显。于是不少超融合厂商开始做适配层,让平台可以直接作为容器编排的存储后端,甚至把虚拟机生命周期也暴露成资源对象。
我做的 POC 目标很直接:在一个三节点的超融合集群上,用云原生技术栈统一管理传统数据库虚拟机和容器应用,让虚拟机具备容器一样的使用体验,同时让容器应用能访问超融合提供给虚拟机的那种高性能持久化存储。以下内容全部来自这次实践,基于我个人的操作记录和复盘,不涉及具体品牌。需要说明的是,POC 环境的硬件资源有限,结果仅供思路参考,不代表任何厂商的官方指标。
2. 方案解剖:控制面走云原生,数据面走超融合,计算面走轻量级虚拟化
2.1 三层架构到底长什么样
整个方案可以拆成三块:控制面、数据面、计算面。控制面用容器编排平台承载,通过自定义资源来描述“虚拟机”这种负载;计算面在每台物理机上跑轻量级虚拟化运行时,负责把自定义资源转成实际的 QEMU 进程或内核虚拟化实例;数据面由超融合的分布式存储承担,以 CSI 或平台自定义接口的形式,把存储卷挂载给容器或虚拟机。
POC 里我们选了最朴素的三节点架构:每台物理机既是超融合存储节点,又是容器编排工作节点。这样做的原因很简单——模拟真实超融合产品常见的“计算存储同节点部署”模式。存储副本数设置为 2 份,容忍单节点故障,同时把虚拟机都配置成反亲和调度,尽量保证同一对业务主备不会落在同一台物理机上。
这里有个设计取舍值得多说一句:为什么不把存储单独拆出来做独立节点?因为超融合的核心优势本来就是省掉共享存储交换机,用本地盘加分布式复制来替代传统集中存储。如果单独拆存储节点,等于又走回三副本集中存储的老路,失去了超融合在成本和部署密度上的意义。但代价是计算和存储会争抢同一份物理资源,尤其是 CPU 和内存。POC 中每个节点只有 64GB 内存,既要跑虚拟机的内存开销,又要吃掉存储缓存的一部分,很快就能感受到容量规划的压力。
2.2 为什么不让容器直接跑在裸机或者普通虚拟机上
这是整个技术选型里被问最多的问题。一拨人建议:既然都用了容器编排,为什么不直接容器化数据库,把超融合纯粹当成持久化存储后端?另一拨人建议:既然有超融合,为什么不干脆用传统虚拟化平台,把容器都跑在虚拟机里?
两个建议都有道理,但都不完全符合实际需求。容器化数据库在 POC 里有几个过不去的坎:首先是内核共享问题,跑在容器里的数据库,如果遇到需要修改内核参数或加载特定内核模块的版本,处理起来非常别扭;其次是安全问题,第三方提供的数据库镜像我们没法完全信任,在等保和内部合规审查下,共享宿主内核意味着攻击面扩大。反过来,全部用传统虚拟机,又会让上层的 DevOps 工具链失去用武之地——业务方习惯用 Helm 和流水线驱动应用部署,虚拟机模板和克隆机制没法无缝接进这套流程。
轻量级虚拟化正好卡在两者之间。它可以被容器编排平台当作一个“特殊的容器”来调度,有独立的操作系统内核,镜像可以在远端仓库里存放和分发,启动时加载到本地缓存;同时又天然具备硬件虚拟化隔离,逃逸风险比单纯 Linux 容器低。对于业务方来说,申请一台数据库虚拟机,体验上跟申请一个 StatefulSet 差不多,但内部又可以像传统虚拟机一样登录、调整参数、做快照。
2.3 网络怎么打通:桥接、Overlay 和多网卡共存
网络是这次 POC 里最费神的部分。虚拟机和容器对网络的预期完全不同:容器默认走 Overlay,好处是跨宿主机迁移不用改 IP,坏处是性能和排障直觉差一点;数据库虚拟机通常要求保留固定 IP,最好还能跟原有物理网络直接互通,避免改造数据库连接字符串。
最后的做法是双网络平面并行。容器应用全部跑在第二层 Overlay 网络上,用云原生网络插件的标准模式管理,这部分和平时没什么区别。虚拟机则走桥接模式,每个虚拟机的虚拟网卡都桥接到物理机的管理网桥上,由物理网络直接分配固定 IP,甚至可以保留原有业务网段的地址。这样数据库团队完全不需要感知 Overlay 的存在,网络策略也能沿用现有防火墙规则。
要注意的是,桥接模式会让宿主机网络承担转发压力。POC 中发现,单台物理机上如果同时跑 4 台流量较大的数据库虚拟机,物理网卡的中断处理会明显吃 CPU。建议把虚拟机的跨节点流量优先调度到网卡多队列,或者在硬件条件允许时用两张万兆网卡分别承载存储和业务流量。我们当时只用了双千兆绑定,性能上只能说“够用”,并没有跑出特别亮眼的数据。
2.4 存储挂载:CSI 驱动和超融合卷的结合方式
存储是超融合最核心的部分,也是这次 POC 里最接近“生产可用”的模块。超融合平台对外提供分布式块存储,可以动态创建卷。为了让容器编排平台能够直接使用这些卷,平台提供了一套 CSI 驱动,把“创建持久化卷声明”的请求翻译成超融合平台的卷创建指令。
在 POC 里,我测试了两种挂载路径。第一种是容器应用直接用 CSI 驱动申请卷,完全走云原生标准流程;第二种是虚拟机先创建一块数据盘,再将数据盘以块设备方式直接挂载给虚拟机内部的数据库。两种路径对比下来,容器应用走 CSI 明显更顺畅,因为它天然支持快照、扩容、克隆;虚拟机挂数据盘则需要额外关注块设备的文件系统锁问题——如果两台虚拟机共享同一块卷,数据一致性会非常危险,必须靠数据库集群自己的机制去管理。
这里分享一个实操细节:超融合存储的卷,在创建时可以指定副本数和条带宽度。POC 里数据库卷我统一设置了 2 副本,测试卷则用了 1 副本,因为临时数据允许丢失。生产环境如果对 IOPS 极度敏感,可以考虑加大条带宽度来并行读写更多磁盘,但同时也会放大单盘故障的影响面,需要仔细权衡。
3. 落地过程中最痛的三件事:镜像、调度、热迁移
3.1 虚拟机镜像的体积和分发问题
容器镜像动辄几十 MB 到几百 MB,通过镜像仓库分发已经很成熟。虚拟机镜像则完全不是这个量级,一个云镜像压缩后也要 600MB 到 1GB,如果还装了数据库、中间件和补丁,体积随便上 2GB。在 POC 阶段,三台机器之间拷贝镜像还能忍,但如果扩展到几十台物理机,每个节点都拉取一份完整镜像,网络和本地磁盘都会被拖垮。
我们的缓解办法是用分层缓存机制。一开始的三台机器全部通过本地镜像仓库分发,第一台拉取完整镜像后,后续节点尝试从本地缓存命中已有层,避免重复下载。实际效果还不错,第二次部署同一镜像时几乎不需要跨节点传输,因为公共层已经在各节点上命中了。
但分层缓存只在“同一个镜像多个虚拟机”的场景有效。如果虚拟机镜像差异很大——比如一台跑 MySQL,一台跑 Kafka,还有一台跑内部办公系统——每台机器都要重新准备环境。最合理的方式还是尽量按照“最小底座 + 启动时配置”的思路来构造虚拟机:底座镜像只包含通用的操作系统内核和基础工具,在容器编排资源定义里通过启动脚本挂载配置、安装数据库、拉取应用包。这样镜像数量会收敛,分发压力也会小很多。
3.2 调度器不认识“虚拟机”这种负载
这是整个 POC 里和预期差距最大的地方。容器编排平台的调度器擅长的是判断 CPU、内存、端口、Affinity 关系,但对虚拟机有几个特有需求完全没概念。
第一个是大页内存。数据库虚拟机为了性能通常会开启大页内存,但标准调度器统计内存时并不会区分大页和普通页,导致调度器觉得主机内存充足,实际大页内存已经不够分配,虚拟机启动直接失败。解决办法是在自定义资源里自带节点选择器,提前把启用了大页内存的物理机打上专用标签,只有带对应标签的虚拟机才允许调度到这批节点上。
第二个是设备映射。虚拟机的虚拟块设备在宿主机上对应一个原始文件或块设备,调度时如果不检查目标节点的磁盘空间和存储归属,很可能把虚拟机调度到存储卷不匹配的节点上。超融合里虽然存储是共享的,但副本放置策略会和物理节点绑定,调度到错误节点会让读路径绕远,延迟明显增加。
第三个是迁移时的调度冲突。虚拟机热迁移有一个 CPU 特性兼容性问题,源节点和目标节点的 CPU 型号必须至少满足迁移掩码要求。如果集群里混用了不同代际的 CPU,必须提前在资源定义里指定最低 CPU 特性模型,否则迁移后会直接遇到非法指令错误。
这些需求标准调度器全都不知道。最后我是在自定义控制器的调度逻辑里加了得分函数,把“大页内存剩余量”“存储卷本地命中率”“CPU 兼容模型”变成加分项,强行让调度有了优先级。方法比较笨,但至少跑通了。
3.3 热迁移在存储和网络上的连环坑
热迁移一直是最能检验方案成熟度的功能。容器时代的“迁移”本质是重新调度一个新实例,停机时间几十秒都算正常;但数据库虚拟机要求的是无感知迁移,业务不能断。
第一次做热迁移测试就踩了坑。业务虚拟机绑定了一块超融合数据盘,我开始迁移以后,源节点上的虚拟机和目标节点上的虚拟机都要访问同一块存储卷。超融合存储对同一块卷的并发操作是允许的,但在迁移过程中,两个节点同时注册块设备映射,一度出现了 IO 锁冲突,数据库日志里冒出一堆延迟告警。后来调整了迁移策略,先把数据盘从虚拟机上分离,只迁移系统盘,完成后再重新挂载数据盘,问题才消失。
网络侧同样有坑。桥接模式下,虚拟机跨节点迁移之后,MAC 地址会带着走,物理交换机的 MAC 表项需要重新学习。如果交换机端口安全策略比较严格,迁移完成后可能直接就断网。解决方法是迁移前提前在目标节点上用虚拟机的 MAC 地址发起一次 ARP 广播或依赖虚拟网络模块的自动通告,让网络设备把端口映射更新过来。POC 里就因为这个丢了一个小时排查,最后在目标节点手动 ping 网关才把 MAC 表项刷新掉。
4. 验收指标与复盘中总结的硬经验
4.1 性能损耗到底在什么量级
所有新方案都要拿数据说话。我在 POC 里对同一套业务负载做了三组对比:纯物理机、轻量级虚拟机上运行、普通容器里运行。结果也符合大多数类似的公开结论:轻量级虚拟化的 CPU 和内存性能损耗在 5% 左右,内存带宽几乎没有明显下降;唯一差距明显的是 IO,如果网络和存储路径没有专门优化,IOPS 会比容器的内核虚拟化存储路径低 10% 到 15%。
| 场景 | CPU 性能损耗 | 内存带宽损耗 | 存储读 IOPS 损耗 | 启动时间 |
|---|---|---|---|---|
| 物理机 | 基准 | 基准 | 基准 | 数十秒(按系统裁剪) |
| 轻量级虚拟机 | 约 5% | 几乎无感 | 约 10% | 5 秒内可完成实例创建 |
| 普通容器 | 约 2% | 几乎无感 | 约 8% | 秒级 |
需要说明的是,这个数值是测试环境的小样本数据,不是硬指标。让我更在意的其实是另一个角度:轻量级虚拟机的运维体验和生产可靠性,是否值得这 5% 到 10% 的额外损耗。在数据库这类需要稳定内核环境和高隔离级别的负载里,我认为完全值得。
4.2 故障域模拟:单节点宕机后的恢复速度
总不能让 POC 只在风平浪静时好看。我在测试里直接断掉了其中一台物理机的电源,模拟最坏情况。超融合存储层的 2 副本策略立刻开始补副本,但补副本的过程占用了大量带宽,同节点上的业务虚拟机 IO 延迟瞬间上升了 30% 以上。这是超融合架构的通病——故障恢复和在线业务争抢磁盘资源,尤其在 SSD 容量不富裕的小规模集群上特别明显。
容器编排平台这边,控制器在几十秒后重新调度了受影响的无状态容器,恢复速度很快;但虚拟机因为涉及热迁移判定和存储再挂载,花了接近两分钟才在其他节点上完成恢复。这个速度对大部分内部业务可以接受,但如果要求 RTO 在 30 秒以内,不能依赖自动恢复,必须在架构里预留主备切换机制,提前把备节点启动好,主节点宕机时由业务层的 VIP 或负载均衡快速切换流量。
4.3 团队分工与工作模式的改变
方案跑通之后,对运维和开发之间的边界影响挺深。以前超融合平台的虚拟机申请、网络配置、存储扩容全都要找基础设施工程师人工处理;新的模式下,这些动作都可以沉淀成模板,业务方直接提交包含资源定义的清单,基础设施团队只需要维护模板和存储池的健康状态。
过程中也有阻力。数据库管理员最反对的是“数据库配置也要写进资源清单里”这件事,他们更习惯登录虚拟机以后手动调参数。折中方案是资源清单里只定义硬件规格和镜像版本,数据库内部配置仍然保留登录后手工修改的方式,但要求数据库管理员把改动脚本化并放入配置管理库,这样至少能保证虚拟机重建之后可以恢复到接近原状态的水平。
还有一个必须强调的教训:凡是涉及虚拟机的云原生管理,一定要提前定义好“什么可以被控制器重建,什么不允许动”。POC 期间有位同事在调试自动化流程时误删了一个测试虚拟机的资源定义,平台立刻把整台机器销毁了。如果里面有未持久化的临时数据,那损失就不是测试环境能兜住的了。我们在控制器里加了一条保护规则:带有特定标签的虚拟机默认禁止删除,必须额外手动清理标签后才允许销毁。
4.4 超融合和云原生结合之后,什么场景我不推荐用
不是所有负载都适合搬到这套体系里。我自己总结下来有三类不适合:一是超大规模的高性能计算,这类负载往往需要最极致的线程调度和低延迟网络,虚拟化层无论如何都是负担;二是对网络性能要求苛刻且不接受 Overlay 损失的微服务集群,最好让它们继续跑在裸金属加标准容器网络里;三是已经有成熟容灾体系的传统虚拟机生产环境,如果管理团队对虚拟化平台极为熟悉,强行切换到云原生管虚拟机等于把简单问题复杂化,收益有限。
反过来,适合这套体系的是:需要固定 IP 和完整内核隔离的数据库、消息中间件,以及形态介于“应用”和“基础设施”之间的负载。这类负载既享受容器化的快速交付,又需要虚拟机级的稳定边界,轻量级虚拟化加超融合的组合正好接得住。
5. 结尾:最后分享一个从 POC 带出来的技巧
如果现在有人想复现这个方案,我会建议别一上来就管理大批虚拟机,而是先用一套极小的冒烟负载跑通链路。具体来说,可以只在存储节点上创建一台最小规格的轻量级虚拟机,挂载一个超融合数据卷,在虚拟机上跑一个 Nginx 再加一个带持久化目录的数据库容器,然后把整个资源定义提交到容器编排平台,观察从声明到分配存储、到虚拟机启动、再到数据库容器读取挂载卷的全过程。只要这条链路能稳定跑满 48 小时不出告警,再逐步扩大到主备、迁移、扩缩容。
还有一个我反复踩到的细节:存储卷的快照功能一定要在测试第一天就验证,不要等上线后才第一次用。超融合卷快照在界面里点起来很快,但通过 CSI 触发时是否和虚拟机内部的文件系统保持一致,各个方案的行为差异非常大。数据库类负载做快照前最好先让应用进入一致性状态,否则恢复之后的库文件是否完整只能靠运气。先跑通快照恢复演练,比性能调优更值得优先投入时间。
这次 POC 之后,我对轻量级虚拟化和超融合的组合有了更实际的判断。它确实解决了容器隔离性不足和传统虚拟化交付效率低的两头痛点,但它并不是银弹,最大的成本在于控制器的成熟度和团队对云原生思维的理解。只要这两点能补上,这个方向迟早会从测试环境走进真正的生产环境。