尧图网络科技YAOTU DIGITAL 获取报价
获取报价
首页 / 资讯中心 / 文章详情

OpenStack Cinder 备份实战:cinderback 脚本化与增量备份避坑指南

发布时间:2026/9/29 19:00:17

资讯中心
01
ARTICLE

OpenStack Cinder 备份实战:cinderback 脚本化与增量备份避坑指南

OpenStack Cinder 备份实战:cinderback 脚本化与增量备份避坑指南
简介cinderback 是一份面向 OpenStack 运维与云平台开发者的 Python 脚本工具用于简化 Cinder 卷备份与还原工作流并针对 Cinder Backup Service 的现有局限提供变通方案。它支持按租户或全部租户批量备份、还原卷管理员可在完成备份后对属主租户隐藏备份也能灵活恢复并控制原始租户的可见性同时提供备份轮换、按原始卷 ID 或备份 ID 还原、保留卷名称与描述、借助临时快照处理使用中卷以及自动备份元数据的一键导出与导入。资源包共 4 个文件以 py 主脚本为核心辅以 requirements.txt 依赖清单、README.md 说明文档和 .gitignore 忽略配置整体约 11KB轻量易读。运行仅需 Python 2.7 与 cinderclient v1.1.1 及以上版本旧版本将缺失部分依赖多租户选项的功能。目前已有 312 人学习适合需要参考备份脚本实现或排查 Cinder 备份限制的读者。1. 从一次 Cinder 卷误删说起cinderback 到底解决什么问题凌晨两点一个刚上线的业务集群报障某台虚机挂载的数据盘空了。排查下来不是存储后端故障而是有人执行清理脚本时把openstack volume delete打到了生产卷上。Cinder 默认只保证块设备的高可用不保证你误删之后还能找回来——卷一旦被删元数据进了数据库的删除队列后端存储上的实际数据很快被回收这时候再想恢复基本只能靠备份。问题就在这儿OpenStack 原生给了cinder backup-create也给了快照但真到生产环境多数团队的备份是「想起来跑一次」的状态。没有统一入口、没有保留策略、没有失败重试备份文件散落在各个后端恢复的时候连哪个卷对应哪个备份都要翻数据库。cinderback 这个方向要解决的就是把 Cinder 备份这件事从「手动敲命令」变成「脚本化、可调度、可校验」的一套助手工具。它适合正在用 OpenStack尤其是 kolla 部署的集群做私有云、又不想上重型备份平台比如直接堆 Velero、Commvault的运维和平台工程师。读完你能拿到一套可复现的备份脚本骨架、参数怎么设、以及几个我踩过的坑。2. cinderback 的定位与 Cinder 备份机制先搞懂 backup 和 snapshot 的区别2.1 为什么不能只靠 snapshot 当备份很多人第一反应是「我有快照啊要备份脚本干嘛」。这是最常见的认知翻车点。Cinder 的 snapshot 和 backup 在实现层面完全是两回事snapshot依赖卷所在的后端驱动。它记录的是「某个时间点卷的状态」但底层往往还是同一份存储。如果后端存储池损坏、或者卷和快照在同一个故障域快照跟着一起没。而且 snapshot 通常不能跨后端迁移删了源卷快照的可用性也要看驱动实现。backup是把卷数据真正读出来写到另一个位置——可以是 Cinder 的 backup 后端Swift、Ceph、NFS 等。它是独立的一份数据副本能跨后端恢复也能恢复到新卷。所以 cinderback 这类脚本助手的核心价值是围绕cinder backup这条链路做工程化而不是去包装 snapshot。选型上先明确你要的是「快速回滚」snapshot 够用还是「灾难恢复」必须 backup。生产环境我一般两个都留但备份脚本只管 backup。2.2 Cinder backup 的三种模式与增量逻辑cinder backup-create支持几种模式直接决定脚本怎么写、存储怎么规划模式参数数据量适用场景全量默认整个卷首次备份、关键卷增量--incremental仅变化块频繁备份、大卷快照式--snapshot基于临时快照减少对在线业务 IO 影响增量备份依赖上一次备份作为父备份parent所以脚本里必须维护「卷 → 备份链」的映射关系。如果你把父备份删了后面的增量就断了恢复会失败。这是脚本设计里最容易忽略的一点保留策略不能简单按时间删要按备份链删。底层上Cinder backup 服务cinder-backup通过驱动把卷数据搬运到 backup 后端。用 Ceph 做后端时走的是 rbd 的 export/diff用 Swift 时是分块上传对象。理解这一点你才知道为什么备份速度受 backup 节点网络和 backup 后端吞吐双重制约。2.3 用一条命令看清备份链路是否健康动手写脚本前先确认你的集群 backup 服务是活的。这是所有后续操作的前提# 确认 cinder-backup 服务在线且 backup 后端已配置 openstack volume service list | grep cinder-backup # 查看当前 backup 后端能力是否支持增量等 cinder service-list --binary cinder-backup # 列出已有备份确认能正常读到 openstack volume backup list --all-projects --long逻辑说明第一条命令确认服务注册状态如果State不是up后面所有backup-create都会卡在creating。第二条看 backup 节点的能力上报。第三条验证 API 和数据库链路通畅。参数上--all-projects在管理员视角下必须加否则只能看到自己项目的备份做全局备份脚本时会漏卷。提示如果cinder-backup服务显示down先别急着写脚本去 backup 节点看cinder-backup日志八成是 backup 后端比如 Ceph 池或 Swift 容器连不上。3. 写一个能用的 cinderback 备份脚本从取卷到落备份3.1 脚本骨架遍历卷、过滤、逐个备份一个能上生产的备份脚本结构应该是「取卷列表 → 过滤规则 → 逐个备份 → 记录结果」。下面是我常用的骨架用 Python 调 OpenStack SDK比纯 shell 解析输出稳得多import openstack import logging from datetime import datetime logging.basicConfig(levellogging.INFO, format%(asctime)s %(levelname)s %(message)s) # 连接集群认证信息从 clouds.yaml 或环境变量读取 conn openstack.connect(cloudmycloud) def should_backup(volume): # 过滤跳过 bootable 系统盘按需、跳过已挂载到临时测试项目的卷 if volume.name and volume.name.startswith(ephemeral-): return False # 只备份大于 1G 的卷避免备份一堆空盘 if volume.size 1: return False return True def backup_volume(volume, incrementalTrue): name fbk-{volume.name}-{datetime.now():%Y%m%d%H%M} try: bk conn.block_storage.create_backup( volume_idvolume.id, namename, incrementalincremental, forceTrue, # 卷处于 in-use 时也允许备份 containercinder-backup # 指定 backup 后端容器/池 ) logging.info(backup started: %s - %s, volume.id, bk.id) return bk except Exception as e: logging.error(backup failed for %s: %s, volume.id, e) return None for vol in conn.block_storage.volumes(): if should_backup(vol): backup_volume(vol)逻辑说明create_backup的forceTrue是关键参数——不加它卷处于in-use被虚机挂载状态时备份会直接报错而生产卷几乎都是 in-use。incrementalTrue让第二次之后的备份只传变化块但前提是同一卷已有全量备份。container参数对应 backup 后端的容器名Ceph 后端下通常填池名Swift 下填容器名填错会报Backup driver not found。参数上还要注意name的命名规范把卷名和时间戳拼进去恢复时一眼能认出。别用 UUID 当名字翻起来要命。3.2 调度与并发别让备份把生产 IO 打满脚本能跑通只是第一步真正上线要考虑调度和并发。我一般用 systemd timer 或 cron 触发但绝不允许所有卷同时备份。原因很简单backup 是读操作会占用后端存储的 IO 带宽几十个卷并发备份业务侧延迟立刻飙升。控制并发的做法是加一个信号量或分批# 用 flock 保证同一时间只有一个备份脚本实例在跑 flock -n /var/lock/cinderback.lock /usr/bin/python3 /opt/cinderback/backup.py # 或者脚本内部按批次 sleep每批 5 个卷逻辑说明flock -n的-n表示拿不到锁就立即退出避免任务堆积。如果上一轮备份还没跑完这一轮直接跳过比排队更安全。脚本内部再配合time.sleep()做批次间隔给存储留喘息时间。调度频率上我的经验是核心业务卷每天一次全量 每 4 小时一次增量普通卷每天一次增量、每周一次全量。这个节奏不是拍脑袋是权衡了 RPO恢复点目标和存储成本。增量链太长会拖慢恢复速度所以每周做一次全量「重置」备份链。3.3 备份结果校验别等恢复时才发现备份是坏的备份脚本最坑的地方是「看起来成功了其实不能用」。backup-create返回成功只代表任务提交成功不代表数据完整。必须做校验# 检查备份状态restoring 之外的异常状态要告警 openstack volume backup list --long -f value -c ID -c Status -c Size # 抽查把最近一个备份恢复到临时卷验证可读 openstack volume backup restore backup-id逻辑说明备份状态正常应该是available。如果长期停在creating多半是 backup 服务卡住或后端写不进去。定期做恢复演练是唯一可靠的验证手段——我一般每月抽一个非核心卷做一次真实恢复确认数据能挂载、能读。这一步很多人省掉结果真出事时才发现备份链断了。注意恢复演练要恢复到独立的临时卷别覆盖生产卷。恢复操作本身也会占用后端资源安排在业务低峰期。4. 避坑与排查cinderback 脚本上线后最容易翻车的 5 个点4.1 备份一直卡在 creating日志报 backend 超时现象openstack volume backup list里备份状态长时间creating最后变error。原因backup 后端Ceph/Swift/NFS容量满、网络不通或cinder-backup服务与后端认证失败。解决先看 backup 节点/var/log/cinder/cinder-backup.log搜ERROR。Ceph 后端重点查池配额rbd duSwift 后端查容器配额。认证问题多半是cinder.conf里 backup 后端的账号密钥过期。4.2 增量备份报「parent backup not found」现象执行增量备份时报错提示找不到父备份。原因上一次的父备份被保留策略删掉了或者父备份本身是error状态。解决脚本里维护备份链映射删除时从最老的增量往全量方向删绝不先删全量。更稳妥的做法是保留策略按「链」为单位一条链要么整体保留要么整体清理。4.3 卷 in-use 时备份直接失败现象对挂载中的卷执行备份报Volume is in use。原因没加force参数或者加了但后端驱动不支持在线备份。解决确认forceTrue如果驱动仍不支持只能先对卷打快照再备份快照或者接受短暂停业务。Ceph 后端一般支持在线备份NFS 后端要看版本。4.4 备份把存储 IO 打满业务抖动现象备份任务一跑虚机磁盘延迟从几毫秒涨到几百毫秒。原因并发备份太多或备份时段撞上业务高峰。解决用 flock 限制单实例脚本内分批 sleep把备份窗口挪到凌晨。Ceph 后端还可以给 backup 流量设 QoS 限速。4.5 恢复时发现备份大小对不上现象恢复出来的卷比原卷小或数据缺块。原因增量链中间有断裂或备份时卷正在被大量写入导致一致性差。解决恢复前先openstack volume backup show看size和链关系对一致性要求高的卷备份前先fsfreeze冻结文件系统或对数据库类卷用应用层一致性备份。5. 把 cinderback 做成可运维的备份体系保留策略与恢复演练脚本能跑、坑也避了最后一步是让它「可持续」。我见过太多团队备份脚本写完就扔那半年后没人敢动因为不知道哪条链能删、哪条不能。这里给两个具体做法。保留策略用「代数」而不是「天数」。按时间删备份在增量场景下必然出事。我的做法是给每条备份链打标签用 backup 的metadata记录chain_id和generation。保留规则是保留最近 7 代增量 每周一个全量锚点超过的按链整体清理。这样恢复时永远有一条完整链可用。# 给备份打链标签方便后续按链管理 conn.block_storage.create_backup( volume_idvol.id, namename, incrementalTrue, metadata{chain_id: chain_id, generation: str(gen)} )逻辑说明metadata是 Cinder backup 自带的键值对字段不占额外存储查询时用openstack volume backup set或 API 过滤。有了chain_id清理脚本就能按链分组避免误删父备份。恢复演练要自动化。手动演练坚持不了几个月。我一般写一个restore_drill.py每周随机挑一个卷把它的最新备份恢复成临时卷挂到一个测试虚机上跑fsck或读几个关键文件然后删掉临时卷。整个过程无人值守结果写进监控。这样备份到底能不能用是系统在告诉你而不是靠人猜。最后一个习惯备份脚本的每一次变更都要在测试集群先跑一遍完整「备份 → 恢复」闭环再上生产。我有次改了个过滤条件把系统盘也纳入了备份结果备份量翻了三倍存储池差点写满——血泪经验就是备份脚本的改动比业务代码更该谨慎因为它动的是数据安全的底线。希望帮到你。本文还有配套的精品资源点击获取
02
RELATED NEWS

相关资讯

更多网站建设与数字化升级内容

03
WHY YAOTU

想打造同款高转化官网?

懂行业、懂生意,从建站到增长一站式陪跑

◈

场景化定制

不做模板站,围绕你的业务场景量身设计,小众不撞款。

◐

营销型架构

以转化目标组织内容与路径,让官网真正带来询盘。

▲

全周期服务

设计、开发、运营、运维一体,上线只是开始。

免费获取你的建站方案

留下需求,专属顾问 24 小时内为你输出方案建议。