- 文档/教程
【免费下载链接】90DaysOfDevOps
This repository started out as a learning in public project for myself and has now become a structured learning map for many in the community. We have 3 years under our belt covering all things DevOps, including Principles, Processes, Tooling and Use Cases surrounding this vast topic.
本文是 #90DaysOfDevOps 挑战第 90 天的技术复盘,聚焦于一个真实场景:在把 Kubernetes 工作负载从主集群迁移到灾备(Disaster Recovery)集群的过程中,如何在恢复的同时改造目标端应用——更换存储类(StorageClass)与调整副本数。阅读完本文,你将掌握 Kasten K10 的"恢复时转换(Restore-time Transformations)"完整操作流程、其背后的 Kubernetes 资源机制,以及如何通过 Kubernetes API 将迁移任务自动化。
为什么需要"数据与应用移动性"
"数据与应用移动性"(Data & Application Mobility)指的是把工作负载、应用及其数据从一个位置移动到另一个位置的能力。这个需求在 Kubernetes 生态中正变得越来越普遍,它既存在于同一平台内部,也存在于不同平台之间。驱动这种移动的原因多种多样:成本优化、风险规避,或者为业务提供更好的服务。
本文讨论的场景正是如此:我们不只要把一套 Kubernetes 工作负载从 A 集群搬到 B 集群,还要在搬到目标位置的过程中改变应用在目标端的形态——这正是 Kasten K10 恢复时转换能力的核心价值,也是它与普通"备份-恢复"的本质区别。
这套流程大量复用了第 89 天(灾难恢复(Recuperación de desastres))所建立的基础设施与机制:对象存储中的备份数据、待命(standby)集群上的 K10 部署、导入策略(Import Policy)等。可以说,移动性是灾备能力的自然延伸——灾备保证"数据在别处可恢复",移动性则进一步保证"恢复的同时还能按需重塑应用"。
迁移场景需求拆解
业务动机
假设我们面临如下业务决策:
- 当前 Kubernetes 集群已经无法应对业务需求(容量瓶颈),且成本快速攀升;
- 企业决定把生产 Kubernetes 集群迁移到位于另一朵公有云上的灾备位置——那里既能提供扩展空间,成本也更低,还能利用目标云的原生服务。
应用拓扑与迁移目标
当前的关键业务应用是Pac-Man,其技术栈在仓库中可见于 pacman-stateful-demo.yaml:
- 前端:NodeJS 编写的 Pac-Man Web 界面,由
Deployment管理(replicas: 1),镜像为quay.io/ifont/pacman-nodejs-app:latest,通过 Service(type: LoadBalancer,port: 80 -> targetPort: 8080)对外暴露; - 后端数据库:MongoDB(
bitnami/mongodb:4.4.8),由StatefulSet管理(replicas: 1),数据落在mongo-storage这个PersistentVolumeClaim(1Gi、ReadWriteOnce)上; - 敏感配置:数据库账号密码通过
mongodb-users-secret(Opaque Secret)注入环境变量,前端通过MONGO_SERVICE_HOST=mongo等环境变量访问数据库。
基于此,迁移有两个明确诉求:
- 存储升级:当前应用运行在较慢的存储层(主集群使用
csi-hostpath-sc存储类),希望迁到目标集群后使用更快、更新的存储层级(standard存储类); - 前端扩容:当前 Pac-Man 前端(NodeJS)扩展性不佳,希望在目标位置把 Pod 数量从 1 提升到 5。
在原文(2022/es/Days/day90.md)中,这两条需求通过 Kasten K10 的"恢复时转换"在一次恢复操作中同时完成。
前置条件:一套可用的备份与待命集群
要执行带转换的恢复,首先需要具备两个前提(详细过程在 Día 89 中已完整演练):
- 主集群上的备份策略已导出到对象存储:在 K10 中创建策略(Policy),启用"通过快照导出进行备份(Export via Snapshot)",将 Pac-Man 应用的备份(含 MongoDB 数据)推送到 S3 兼容的对象存储,并记录下"导入详情(Import Details)"字符串,供待命集群使用;
- 待命集群已就绪:使用不同名称创建第二个 minikube 集群,并同样安装 K10:
minikube start --addons volumesnapshots,csi-hostpath-driver --apiserver-port=6443 --container-runtime=containerd -p standby --kubernetes-version=1.21.2 helm install k10 kasten/k10 --namespace=kasten-io --set auth.tokenAuth.enabled=true --set injectKanisterSidecar.enabled=true --set-string injectKanisterSidecar.namespaceSelector.matchLabels.k10/injectKanisterSidecar=true --create-namespace安装完成后,在待命集群中创建"导入策略(Import Policy)",把对象存储中的备份导入进来,即可在 Applications 面板中看到 Pac-Man 的恢复点(Restore Point)。
第一步:清理待命集群上的灾备恢复现场
在 Día 89 中,我们曾把 Pac-Man 恢复到待命集群以验证灾备能力。现在要正式迁移,首先需要移除上一次灾备测试的恢复结果,为新的迁移恢复腾出命名空间:
kubectl delete ns pacman在名为standby的 minikube 集群中执行上述命令,pacman命名空间及其中的 Pod、PVC 等资源会被整体删除——但对象存储中的备份数据不受影响,这正是"外部备份"的价值所在。
第二步:从 Kasten K10 选择恢复点
清理完成后,进入 Kasten K10 控制台(Dashboard):
- 点击Applications(应用)卡片;
- 在应用列表右上方的下拉菜单中,选择Removed(已删除)——这是 K10 用来标识"已被删除、但仍有恢复点可用"的应用状态的筛选项;
- 此时会列出该应用可用的恢复点(Restore Points)。选择包含我们关键数据的那一个(本示例中只有一个恢复点,因为它来自一次备份作业的导出)。
选中恢复点后,K10 会进入恢复向导,展示各类恢复选项。在 Día 89 的灾备演示中,我们全部使用默认值直接恢复;而这次,我们需要利用恢复向导中的额外选项来完成应用的"变身"。
第三步:理解并配置"恢复时转换"
启用转换选项
在恢复向导中,勾选"Apply transforms to restored resources"(对恢复的资源应用转换)。这一选项的意义在于:K10 在把备份数据恢复到目标集群时,不再原样重建资源,而是允许在恢复前改写被恢复资源的 spec——例如修改 StorageClass、调整副本数、更换容器镜像名等,非常适合"环境迁移"这类需要适配目标环境的场景。
内置转换示例
K10 控制台在"新建转换(New Transform)"中内置了两个高频示例(见下图),恰好覆盖我们本次的全部需求:
- Change storageClass:修改存储类——用于切换存储层级或可用区;
- Scale Deployment:扩缩 Deployment 的副本数量。
转换一:更换 StorageClass(csi-hostpath-sc → standard)
第一个需求是存储升级。在主集群上,Pac-Man 的 PVC 绑定的是 CSI hostpath 驱动提供的csi-hostpath-sc存储类(这正是 Día 55/Día 87 中 minikube 集群默认配置的存储类)。在目标集群上,我们希望使用standard存储类。
在转换配置界面中选择 "Change storageClass" 示例,将源存储类设置为csi-hostpath-sc、目标存储类设置为standard,确认无误后点击底部的Create Transform(创建转换)按钮。
从实现原理上看,这条转换会在恢复时改写被恢复 PVC 的spec.storageClassName字段。Kubernetes 的StorageClass是动态供给(Dynamic Provisioning)的抽象层:每个存储后端都有一个 provisioner(如 CSI driver),PVC 通过storageClassName声明自己需要哪类存储,调度器据此创建对应后端类型的 PV。因此,把csi-hostpath-sc换成standard,本质上是把数据卷重新供给到另一类存储后端上——这也解释了为什么目标集群需要提前具备名为standard的存储类(minikube 默认即提供)。
转换二:扩缩 Deployment(1 → 5)
第二个需求是前端扩容。在 pacman-stateful-demo.yaml 中,Pac-Man 前端 Deployment 的spec.replicas初始为 1;我们希望恢复后目标集群上运行 5 个前端 Pod。
在转换配置界面中选择 "Scale Deployment" 示例,指定目标 Deployment(Pac-Man 前端)并将其副本数设为5,创建该转换。
完成两个转换后,恢复向导中应能看到两条转换记录:changeStorageClass与scaleDeployment,如 Día 90 截图 所示,每条记录都支持复制、编辑与删除:
第四步:执行带转换的恢复
转换配置完成后,恢复向导会列出本次将恢复的所有工件(Artefacts)——包括命名空间、Deployment、StatefulSet、Service、PVC、Secret 等。K10 默认恢复应用的全部资源;如果希望更精细化,也可以只勾选部分工件。
点击Restore(恢复)按钮后,K10 会弹出确认对话框,要求再次确认恢复动作(这是一个防误操作的二次确认机制,同样出现在 Día 89 的恢复流程中)。确认后,K10 将按以下逻辑执行:
- 从对象存储拉取备份数据(含 MongoDB 数据);
- 重建应用的全部 Kubernetes 资源;
- 在重建过程中应用两条转换:为新 PVC 绑定
standard存储类、将前端 Deployment 扩容到 5 个副本。
第五步:验证目标集群
恢复完成后,回到终端查看待命集群的状态:
kubectl get pods -n pacman kubectl get pvc -n pacman从 Día 90 的终端截图 可以看到迁移结果:
pacman命名空间下,MongoDB 的mongo-0Pod(StatefulSet)运行正常;- Pac-Man 前端 Pod 已从 1 个扩展为5 个,且全部处于 Running/Ready 状态;
- PVC
mongo-storage状态为 Bound,其 StorageClass 已显示为standard,不再是源端的csi-hostpath-sc。
两条需求在一次恢复操作中同时达成:数据完好(MongoDB 卷已重建并绑定新存储类),应用拓扑按目标环境重塑(前端 5 副本)。
转换能力的更多应用场景
"恢复时转换"的价值远不止本次迁移演示。同一机制还可以覆盖:
- 灾难恢复:在待命站点恢复时按待命环境调整资源配置(如降副本数、换存储类以节省成本);
- 测试与开发:从生产备份恢复出开发/测试环境时,自动注入不同的镜像 Tag、不同的配置或更小的资源规格;
- 多环境漂移治理:同一份备份在不同环境(本地、云、OpenShift)恢复时,自动适配各自的基础设施差异(存储类、Ingress 类、镜像仓库地址等);
- 业务连续性的其他形态:克隆、环境拆分、合规性演练等。
从仓库中 Día 55(Kubernetes 状态与 Ingress)对 StorageClass/StatefulSet 的讲解可以看出,这些转换点(存储类、副本数)恰恰是 Kubernetes 应用在不同环境间差异最大的部分——csi-hostpath-sc是本地 minikube 环境特有的存储类,而standard是云环境常见的默认存储类。转换机制正是针对这些差异点做"恢复即适配"。
通过 Kubernetes API 自动化
K10 的移动性流程同样可以自动化。关于这一点,原文明确指出:
Kasten K10 的一个重要特性是:部署时它运行在 Kubernetes 集群内部(
kasten-io命名空间),因此可以通过 Kubernetes API 直接调用。
这意味着:
- 备份策略、导入策略、恢复、转换等操作都可以通过 K10 暴露的 Kubernetes API 资源(如 Policy、Restore、Transform 等 CRD)以声明式方式驱动;
- K10 控制台(Dashboard)的界面中,许多操作会提供对应的命令片段(breadcrumb / 命令集),可以直接复制用于脚本与 CI/CD 流水线;
- 结合 GitOps 实践,可以把"创建备份策略""在待命集群导入备份""带转换恢复"等步骤写成清单文件,随集群一起版本化。
这也与 Día 88 中 Kanister(应用级一致性备份) 的设计哲学一脉相承:备份与恢复动作均由 Kubernetes 自定义资源(Blueprint、ActionSet 等)描述,天然可审计、可版本化、可自动化。
延伸阅读与仓库证据
本次迁移演示依赖的完整链条都可以在仓库中逐篇追溯:
- Día 87:Kubernetes 备份与恢复实战——minikube 集群的
volumesnapshots、csi-hostpath-driver插件启用,csi-hostpath-sc与standard存储类的默认类切换命令,以及 K10 的 Helm 部署与 Token 认证方式; - Día 88:应用级一致性备份(Kanister)——Blueprint/ActionSet/Profile 三类自定义资源,以及"备份-破坏-恢复"的完整演练,对应 K10 中"应用一致备份"的高级选项;
- Día 89:灾难恢复——对象存储 Profile 配置、备份策略创建、待命集群(
standby)创建、导入策略与恢复,是本文的直接前置; - Pac-Man 有状态应用清单——本次被迁移的 Deployment(Pac-Man 前端)、StatefulSet(MongoDB)、PVC(mongo-storage)与 Secret 的完整定义;
- Día 55:Kubernetes 状态与 Ingress——StorageClass、PersistentVolumeClaim、StatefulSet 与 Deployment 差异的基础概念。
小结
数据与应用移动性(Data & Application Mobility)是 Kubernetes 备份/灾备能力的自然延伸:备份解决"数据还在不在",灾备解决"能不能在别处起来",而移动性解决"起来之后长什么样"。本文通过 90DaysOfDevOps 第 90 天的真实演练,展示了 Kasten K10 如何让"迁移 + 转换"在一次恢复操作中原子完成——把 Pac-Man 从csi-hostpath-sc慢存储迁到standard快存储,同时把前端从 1 副本扩展到 5 副本,全程无需手工改 YAML、无需停机式的人工重建。
这套机制的适用范围远不止集群迁移:灾难恢复、测试环境搭建、多云适配都可以复用同一条"备份 → 导入 → 转换 → 恢复"流水线,并通过 Kubernetes API 与既有自动化体系(CI/CD、GitOps)无缝集成。
- 文档/教程
【免费下载链接】90DaysOfDevOps
This repository started out as a learning in public project for myself and has now become a structured learning map for many in the community. We have 3 years under our belt covering all things DevOps, including Principles, Processes, Tooling and Use Cases surrounding this vast topic.
相关推荐
90DaysOfDevOps 第 90 天:使用 Kasten K10 实现 Kubernetes 应用与数据迁移(Data & Application Mobility)
90DaysOfDevOps 第 90 天:使用 Kasten K10 实现 Kubernetes 应用与数据迁移(Data & Application Mob
文档/教程90DaysOfDevOps 实战:基于 Kasten K10 与 minikube 的 Kubernetes 跨集群灾难恢复(DR)
90DaysOfDevOps 实战:基于 Kasten K10 与 minikube 的 Kubernetes 跨集群灾难恢复(DR) 本篇技术指南是 90Da
文档/教程90DaysOfDevOps 实战:使用 Kasten K10 在 Kubernetes 中完成有状态应用的备份与恢复
90DaysOfDevOps 实战:使用 Kasten K10 在 Kubernetes 中完成有状态应用的备份与恢复 本篇技术指南来自 90DaysOfDev
文档/教程
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考