云原生-07-OpenNebula在虚机资源管理里怎么做模板存储和故障处理

第一次用 OpenNebula 管理测试虚机时,最先完成的是:

  • 从面板里建模板
  • 直接按模板发虚机
  • 挂载一个数据盘
  • 需要时手动删掉实例

这套方式在规模小的时候还能勉强维持,但环境一旦多起来,很快会出现这些问题:

  • 模板版本越来越多,没人知道哪份才是当前可用基线
  • 同一种模板,在不同存储池和宿主机上表现不一致
  • 数据盘越挂越多,实例删了,卷和残留目录还在
  • 宿主机抖动后,实例状态和实际运行状态对不上
  • 测试团队以为资源够用,实际已经被孤儿卷和历史模板吃掉

这说明 OpenNebula 在测试环境里的难点,并不是会不会点页面,而是:

怎么把模板、存储、配额、生命周期和故障处理收成一套长期稳定的资源治理方式。

这篇文章只讨论一个核心问题:

OpenNebula 在虚机资源管理里,模板怎么做、存储怎么规划、故障怎么处理,才能让测试环境长期可用。

一、先把资源治理对象拆清

OpenNebula 场景里最容易混在一起的对象有四类:

  • 模板:决定实例创建时的镜像、CPU、内存、网卡、磁盘和上下文
  • 存储:系统盘、数据盘、镜像仓库、备份卷
  • 运行对象:虚机实例、宿主机、数据存储、网络
  • 生命周期动作:创建、扩容、冻结、回收、迁移、故障恢复

如果这些对象不先拆清,后面最容易出现两种失真:

  • 以为在治理模板,实际上只是复制出更多模板
  • 以为在治理存储,实际上只是把残留资源越堆越多

二、模板治理要先解决“谁是基线”

模板越多越不是能力,真正有价值的是能不能沉淀出稳定基线。

1. 更适合长期维护的模板分层

一套更稳的分层通常包括:

  • 基础模板:操作系统、初始化方式、基础工具
  • 场景模板:数据库节点、测试执行机、跳板机、服务节点
  • 临时发布模板:只承载单次实验差异,不作为长期基线

如果把每一次改动都另存为新模板,几个月之后往往会出现:

  • 名称相近的模板堆满面板
  • 同一场景存在多个“看上去都能用”的版本
  • 故障出现时无法确认实例到底源自哪份模板

2. 模板里哪些东西应该固定,哪些不该固定

更适合固定在模板里的通常是:

  • 基础镜像
  • CPU / 内存基线
  • 系统盘大小
  • 基础网络接口结构

更适合放在实例化时注入的通常是:

  • 主机名
  • 环境标识
  • 项目组标签
  • 一次性脚本和密钥

如果把环境差异直接写死进模板,后面模板就会变成“环境快照”,而不是“可复用基线”。

三、存储治理不只是够不够用,更重要的是干不干净

OpenNebula 测试环境最容易被低估的,通常不是 CPU 和内存,而是存储。

1. 至少区分三类存储对象

  • 镜像仓库:承载基础镜像和模板源
  • 系统盘存储:承载实例运行时系统盘
  • 数据盘存储:承载业务数据、日志、临时文件、挂载卷

如果这三类不分开,后面最容易发生:

  • 镜像仓库被历史实验卷挤满
  • 系统盘和数据盘混在一起,无法评估真正容量
  • 回收动作只删虚机,不删卷,存储长期被残留资源吃掉

2. 存储规划至少回答三个问题

  • 哪类盘允许长期保留
  • 哪类盘必须随实例回收
  • 哪类目录必须做容量告警

3. 回收链路必须落到卷和目录

的“回收”只做到删实例,真正的问题却留在:

  • 孤儿卷
  • 失联模板
  • 历史快照
  • 宿主机本地残留目录

所以回收完成的标准不该只是“实例没了”,而要进一步确认:

  • 卷是否同步清理
  • 快照是否清理
  • 存储目录是否归还空间
  • 模板引用链是否仍然正确

四、故障处理要按对象分,不要只盯虚机状态

OpenNebula 里的故障,如果只盯实例状态,通常很容易误判。

更合适的拆法是:

  • 模板故障:模板本身参数错、上下文注入错、引用镜像失效
  • 存储故障:卷挂载失败、空间不足、I/O 退化、残留目录
  • 宿主机故障:节点失联、资源不足、迁移失败
  • 实例故障:系统起不来、网络不通、服务异常

1. 模板故障

典型现象:

  • 同类型实例集体启动失败
  • 上下文脚本不生效
  • 实例启动后环境标识错乱

2. 存储故障

典型现象:

  • 虚机能创建但磁盘挂载失败
  • 创建耗时越来越长
  • 实例删除了,空间没有回来

3. 宿主机故障

典型现象:

  • 部分实例状态正常,但控制台无响应
  • 迁移后实例不可用
  • 宿主机负载高,批量实例变慢

五、最小可执行骨架

1. 模板侧

  • 建立基础模板、场景模板、临时模板三级目录
  • 每个模板都标记版本、用途、适用环境、责任人
  • 模板变更前先做最小启动校验

2. 存储侧

  • 明确系统盘、数据盘、镜像仓库三类容量口径
  • 给数据盘和镜像仓库分别做告警阈值
  • 实例回收时同步校验卷和快照

3. 故障侧

  • 按模板、存储、宿主机、实例四类分流
  • 每次故障保留实例信息、宿主机信息、卷信息和控制台截图
  • 不把“状态正常”当成“资源可用”

六、最小记录表

对象 当前状态 关键证据 影响范围 已做动作 是否恢复
模板 版本变更 模板 diff、上下文配置 新建实例 回退模板
数据盘 空间高水位 卷列表、宿主机目录 多个项目组 清理孤儿卷 部分
宿主机 负载异常 CPU、I/O、迁移记录 某批实例 迁移实例

七、常见坑

1. 模板只增不减

最后没人知道哪个模板是真正可用基线。

2. 存储只看总容量,不看残留对象

空间不够时才发现大量孤儿卷和历史快照一直没清。

3. 把实例删除当成资源回收完成

卷、快照、宿主机残留目录如果不查,资源会长期被吃掉。

4. 只看面板状态,不看宿主机和存储证据

很多状态同步问题会让面板看起来正常,实际已经不一致。

5. 用临时模板替代长期模板

一次实验有效,不代表适合沉淀成全局基线。

八、真实案例:虚机删掉了,但存储还是持续告警

1. 场景

某套 OpenNebula 测试环境在一次批量回归结束后,实例都已经清理,面板里也看不到明显残留对象,但存储池空间仍持续告警,后续新实例创建越来越慢。

2. 执行

现场先查实例列表,确认没有大批量运行中的虚机;随后检查模板列表,也没有异常暴涨。表面上看,资源应该已经释放。

3. 现象

实例层面很“干净”,但存储层仍在快速逼近高水位,说明问题不在前台实例,而在后端卷和目录。

4. 排查

继续往下查卷和快照,发现一批历史数据盘没有随着实例回收,部分宿主机上还残留旧目录;同时某个临时模板被多次复制,引用链混乱,导致清理脚本没有正确匹配到对应卷。

5. 修复

现场先暂停新建大批量实例,随后集中清理孤儿卷和宿主机残留目录,并把临时模板合并回基础模板链。复盘时补了三项动作:

  • 回收流程增加卷和快照核对
  • 模板版本统一纳入命名规范
  • 存储告警改成按对象拆分,而不是只报总容量

九、结论

OpenNebula 在测试环境里的稳定性,很多时候不取决于会不会建虚机,而取决于模板基线、存储治理和故障分流是不是清楚。

更适合长期使用的方式通常是:

  • 先沉淀模板基线
  • 再拆清存储对象和回收边界
  • 最后把模板、存储、宿主机、实例四类故障分流处理

这样资源管理才不会越用越乱。