Veeam Kasten 数据保护平台
恢复演练看起来已经成功:Kasten 的策略是绿色,Restore Points 页面也能找到刚生成的时间点。值班人员把它恢复到备用集群后,PVC 一直 Pending,另一个卷虽然挂载成功,里面却只有元数据没有可移植的数据副本。再往前追才发现,源集群只保留了存储快照引用;目标集群看不见源端存储系统。目录里“有恢复点”与目标环境“拿得到数据”是两件事。
更糟的情况是直接在原 namespace 覆盖恢复。GitOps 控制器同时把 Deployment 拉回当前版本,旧、新华应用共用外部队列凭证,备用实例启动后开始消费真实消息。恢复动作本身没有报错,业务状态却被第二个写入者继续改变。Kasten 解决的是应用发现、策略、恢复点目录、卷与资源保护、导出和恢复编排;它不能替团队决定哪一端拥有写权,也不能用绿色状态替代业务断言。
先把四类 Kasten 对象摆正
Policy 回答“保护谁、多久执行一次、保留多久、是否导出”。它是长期意图,不是某次备份。Policy 被执行后会出现 RunAction,再派生 BackupAction、ExportAction、ImportAction、RestoreAction 或 RetireAction 等运行对象。一次任务是否完成,应看对应 Action 的阶段、状态和错误,而不是只看 Policy 校验通过。
Profile 回答“外部位置在哪里、用什么基础设施身份访问”。Location Profile 可承载对象存储、NFS/SMB 或受支持仓库的连接配置。它不是备份历史,也不是恢复点;Profile 可访问只说明路径和凭证成立,不说明某个应用已经导出。
RestorePoint 是应用或虚拟机某个时间点的聚合入口,RestorePointContent 承载与之绑定的底层内容和回收关系。一个 RestorePoint 可以关联 Kubernetes 资源、多个卷快照和已导出的数据。它不等同于 CSI VolumeSnapshot:某个卷快照 ReadyToUse,仍可能缺少另一个卷、应用资源或外部依赖。
这条状态链值得在故障现场一直保留:
Kasten 文章和日常运维中只用这些 Kasten 对象表达平台链路。应用专用逻辑若需要另一套扩展机制,应在它自己的对象与责任边界中治理,不能把外部工作流对象改名塞进 Kasten 的 Policy 或 RestorePoint 模型。
安装前先证明集群能被保护
Kasten 运行在 Kubernetes 中,不适合用单机二进制、Docker 单容器或 Compose 模拟。最小实验也应使用可丢弃的本地或测试集群,并具备默认 StorageClass、动态 PVC、可用 CSI 路径和足够资源。生产集群还要先核对目标 Kasten 发行线与 Kubernetes/OpenShift、CSI、云平台、FIPS、镜像架构的官方支持矩阵。
先固定变量,不把浮动 latest 写进安装记录:
export KASTEN_VERSION='<target-kasten-release>'
helm repo add kasten https://charts.kasten.io/
helm repo update
helm search repo kasten/k10 --versions | head
kubectl version
kubectl get nodes -o wide
kubectl get storageclass版本应从 Kasten 版本化文档与发行说明选择,并与 安装要求逐项比对。许可、平台支持和预览能力会随发行线变化;部署审批保存所选版本页面和合同权利,不把某次节点上限或支持窗口当成永久事实。
官方 primer 可以检查 API、权限、CSI 和快照能力。生产环境不要直接执行未审阅的远程脚本:先下载、校验来源、代码评审,再用与安装身份相同的 kubeconfig 运行。预期证据不是一句 pass,而是目标 StorageClass 的快照/克隆能力、失败项和修复后的重跑结果。
安装使用 Helm,并把渲染后的 values 纳入变更评审:
kubectl create namespace kasten-io
helm show values kasten/k10 --version "$KASTEN_VERSION" > k10-values.reference.yaml
helm upgrade --install k10 kasten/k10 \
--namespace kasten-io \
--version "$KASTEN_VERSION" \
--wait --timeout 20m
kubectl -n kasten-io get pods
kubectl -n kasten-io get deploy
kubectl api-resources | grep -E 'policies|profiles|restorepoints|actions'生产安装还应验证 chart provenance、镜像签名或企业镜像仓库准入。Kasten 官方安装模型需要其服务身份获得广泛集群权限;简单删掉部分 cluster-admin 绑定并不是受支持的“最小权限版”。真正的收敛方式是隔离平台 namespace、限制谁能修改 Kasten RBAC、用 NetworkPolicy 控制出口、让租户只获得经过设计的 Kasten 资源权限,并审计每次恢复和删除动作。
Dashboard 仅在实验时用本地转发:
kubectl -n kasten-io port-forward service/gateway 8080:8000外部暴露前必须配置认证。Direct Access 或 Basic Auth 不能提供细粒度 Kasten 授权;需要按 namespace 或资源授权时,应采用 Kubernetes 可验证的 token/OIDC 路径并配置相应 RBAC。ServiceAccount token 使用短期、可撤销形式,不能把永久 token 写进浏览器书签、脚本或工单。
建立一个能被业务断言的测试应用
创建隔离 namespace、PVC 和持续写入序号的 Pod。镜像 tag 仅表示示例结构,团队实验应固定已审镜像 digest。
apiVersion: v1
kind: Namespace
metadata:
name: k10-lab
labels:
protection.example.com/tier: demo
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: ledger
namespace: k10-lab
spec:
accessModes: [ReadWriteOnce]
resources:
requests:
storage: 1Gi
---
apiVersion: v1
kind: Pod
metadata:
name: ledger-writer
namespace: k10-lab
spec:
containers:
- name: writer
image: busybox:1.37
command: ["sh", "-c", "i=0; while true; do i=$((i+1)); printf '%s\\n' \"$i\" >> /data/sequence; sleep 2; done"]
volumeMounts:
- name: data
mountPath: /data
volumes:
- name: data
persistentVolumeClaim:
claimName: ledgerkubectl apply -f k10-lab.yaml
kubectl -n k10-lab wait pod/ledger-writer --for=condition=Ready --timeout=180s
kubectl -n k10-lab exec ledger-writer -- tail -n 3 /data/sequence最后一行是业务水位。备份前记录它,恢复后验证文件可读、每行是递增整数、恢复水位不超过备份后继续增长的源端水位。这个例子只有单文件 crash consistency;数据库、多卷和消息系统必须换成产品自己的 quiesce、checkpoint 与业务不变量。
从 Policy 走到 RestorePoint
先在 Dashboard 的 Policies 创建 namespace-based Policy,选择 k10-lab,频率设为手工或实验周期,保留数量保持很小。也可以按 Policy API生成清单;提交前用服务器端校验确认目标发行线接受字段:
apiVersion: config.kio.kasten.io/v1alpha1
kind: Policy
metadata:
name: k10-lab-policy
namespace: kasten-io
spec:
frequency: "@onDemand"
retention:
hourly: 2
actions:
- action: backup
selector:
matchLabels:
k10.kasten.io/appNamespace: k10-labkubectl apply --server-side --dry-run=server -f k10-lab-policy.yaml
kubectl apply -f k10-lab-policy.yaml
kubectl -n kasten-io get policy k10-lab-policy -o yamlstatus.validation 应表明策略可执行。然后在 Dashboard 对该 Policy 执行 Run Once,同时从 API 观察真实运行链:
kubectl -n kasten-io get runactions.actions.kio.kasten.io --sort-by=.metadata.creationTimestamp
kubectl -n kasten-io get backupactions.actions.kio.kasten.io --sort-by=.metadata.creationTimestamp
kubectl -n k10-lab get restorepoints.apps.kio.kasten.io
kubectl -n k10-lab get restorepointcontents.apps.kio.kasten.io资源简称可能因发行线变化,先用 kubectl api-resources | grep kio.kasten.io 取得准确名称。预期证据包括:Policy 校验通过;最新 RunAction 与 BackupAction 完成;k10-lab 出现 RestorePoint;RestorePoint 能关联源 Policy、应用资源和卷内容。任何一个 Action 失败都应保留 describe、Event 和 kasten-io 中相关 Pod 日志,不要只截 Dashboard 的绿色卡片。
反向实验:有 RestorePoint,恢复仍然不能接管
先制造一个稳定错误:在没有外部 Location Profile 的情况下只保留本地快照,然后尝试把该恢复点用于看不见源存储的另一个集群。目标集群可能能导入部分目录信息,却无法重建卷;典型证据是 RestoreAction 失败、PVC Pending、StorageClass 不存在、快照 handle 不可访问或目标 CSI 无法解析来源。
即使同集群恢复也可能失败。保持 GitOps 调谐开启,把 RestorePoint clone 到新 namespace,再观察对象是否被 GitOps 删除、覆盖或拉回另一 revision:
kubectl get events -A --sort-by=.lastTimestamp | tail -n 80
kubectl get pvc -A
kubectl -n kasten-io get restoreactions.actions.kio.kasten.io \
--sort-by=.metadata.creationTimestamp这个反例证明三层证据必须分开:RestorePoint 存在;数据在目标故障域可达;恢复出的应用通过业务校验。修复不是重试按钮,而是选择真正导出数据的 Profile、准备兼容 StorageClass/转换规则、暂停会争写的调谐器,并把外部队列、DNS、云身份和写入权放进切换清单。
正向实验:外部 Profile、导出、导入、隔离恢复
在 Profiles -> Location 为专用测试前缀创建 Location Profile。不同对象存储、NFS/SMB 或 Veeam Repository 的字段和身份方式不同,应使用目标发行线的 Location Configuration生成,随后导出对象留档:
kubectl -n kasten-io get profiles.config.kio.kasten.io
kubectl -n kasten-io get profile <lab-location-profile> -o yamlProfile 应使用独立 bucket/prefix、最小读写权限和可撤销身份。repository 密钥与 Kasten 集群 passphrase 分开保管;集群 passphrase 保护平台加密材料,丢失可能使平台灾难恢复无法解密,不能直接修改或删除相关 Secret 来“轮换”。按官方 passkey 流程操作,并在集群外保存受控恢复副本。
编辑 Policy,增加 export action,显式选择 Export Snapshot Data。只导出 snapshot reference 仅适合目标环境仍能访问同一存储快照的情况;跨云、跨基础设施或源存储可能消失时,必须移动卷数据。先用 --dry-run=server 验证,再执行一次 Run Once。预期 Action 链中同时出现成功的 BackupAction 与 ExportAction,外部位置有该 Policy 对应的元数据和数据增长。
目标集群安装兼容发行线的 Kasten,创建只读/列举权限的匹配 Location Profile,使用源策略提供的 receive string 建立 Import Policy。receive string 是敏感关系材料,不放进 Git、聊天或日志。ImportAction 成功只说明目录同步;它不应自动获得生产写权。
在目标集群选择明确 RestorePoint,clone 到 k10-restore-lab,先阻断对真实外部服务的出口。恢复完成后执行:
kubectl -n k10-restore-lab get pods,pvc
kubectl -n k10-restore-lab get events --sort-by=.lastTimestamp
kubectl -n k10-restore-lab exec <restored-ledger-pod> -- sh -c \
"test -s /data/sequence && awk 'NR==1{p=\$1; next} \$1<=p{exit 1} {p=\$1}' /data/sequence"再比较恢复水位、源 RestorePoint、目标 imported RestorePoint 和 RestoreAction UID。只有卷可读、序号递增、对象版本符合预期、外部副作用仍被隔离,才允许进入业务接管评审。
多租户不是“每人一个 namespace”
Kasten 的发现与执行需要集群级能力,Dashboard 入口也可能放大权限。租户自助时至少分开四种角色:平台安装与升级者;Profile/凭证管理员;只能在授权 namespace 创建或运行 Policy 的应用 owner;只能查看状态和恢复报告的审计者。恢复、导出、删除 RestorePointContent 和修改 Profile 都应是显式高风险动作。
Profile 的对象存储身份按租户或保护域拆分 bucket/prefix,禁止一个共享 access key 覆盖所有备份。目标导入身份通常只需读取和列举,不应沿用源端删除权限。Dashboard 身份、Kubernetes RBAC、云 IAM、KMS 和网络出口共同决定真实边界;其中任一层过宽,namespace 都不能提供数据隔离。
审计至少关联操作者、Policy、Action UID、RestorePoint、Profile、源/目标 namespace 和业务变更单。不要把 token、receive string、passphrase、license 文件或云密钥写入 Action 注释和日志。凭证轮换后要实际跑一次 export/import,而不是只验证 Secret 已更新。
容量、性能和费用从恢复路径反推
本地 CSI 快照通常创建快,但仍占用源存储故障域和增量链;portable export 会消耗读取 IOPS、临时卷、网络、对象请求、跨区域流量和外部容量;恢复又会产生下载、重水化和校验副本。容量模型至少记录被保护逻辑数据、每日变化量、保留层级、压缩/去重效果、并发导出数、临时空间、对象数量和演练副本寿命。
不要按“平均备份耗时”定并发。多个 namespace 同时快照和导出会争抢 CSI、API Server、节点带宽与对象存储限流。用 Action 排队年龄、阶段耗时、失败/重试、仓库增长、恢复吞吐和业务 I/O 长尾建立基线;阈值来自 RPO/RTO 与存储实测。云价格、许可计量和企业功能从目标版本的官方定价、许可政策与合同核算,不在模板里写死单价。
Kasten 更适合需要应用级目录、策略治理、跨集群迁移、集中可视化和商业支持的团队。若只需少量 namespace 的文件级 PVC 备份,平台权限和许可成本可能过重;若主要问题是数据库逻辑备份,应优先采用数据库 Operator/原生链路,再决定是否由 Kasten 编排。选型标准是恢复证据覆盖与长期责任,而不是 Dashboard 功能数量。
删除、升级和安全退出
删除 Policy 只是停止该策略后续调度,不等于删除已生成恢复点。删除 RestorePoint 也不能推断底层数据已回收;对 RestorePointContent 的退休会触发 RetireAction,并可能永久影响关联卷与外部数据。操作前先导出对象、确认 retention 和不可变策略,再观察 RetireAction 与外部仓库趋势。去重、共享引用、对象锁和聚合数据会让空间延迟释放。
升级顺序是先读目标 release notes、支持矩阵、CRD/API/Helm values 变化和许可边界,再在隔离集群执行 primer、安装、备份、导出、导入和恢复回归。预览能力不能直接成为生产基线;Policy 或 repository 升级可能需要独占访问,升级窗口内不能假定导入导出照常运行。回滚要保留旧 chart、values、CRD 兼容判断、镜像和至少一个由旧版本验证过的恢复点。
退出平台时按下面顺序收口:停止新调度;等待或终止并核对运行中 Action;导出 Policy、Profile 脱敏结构、RestorePoint 目录、版本与 passphrase 恢复材料;用不依赖原集群的路径恢复最后一个保留点;迁移或依法删除外部数据;撤销 receive string、云 IAM、KMS、Dashboard 身份和 license;最后卸载 Helm release 与 CRD。直接 helm uninstall 不会替你核销 bucket、快照、恢复副本、负载均衡器和外部凭证。
实验清理也遵循同一依赖顺序:先删除隔离恢复的工作负载和 PVC,确认不再需要测试 RestorePoint,再通过 Kasten 的退休流程回收内容,最后删除 Policy、Profile、测试 namespace 和 Helm release。每一步都重新检查集群对象与外部位置,直到没有孤立 RestorePointContent、Action、快照、对象前缀和有效凭证。
真正可交付的 Kasten 证据不是一张绿色页面,而是一条可追溯链:Policy 选中了正确应用,Action 完整结束,RestorePoint 聚合了所需内容,Profile 把数据带出源故障域,目标集群能在隔离条件下恢复,业务断言通过,权限与外部费用也能在退出时被核销。
