JiuwenClaw StatefulSet 持久化存储落地实践
从临时存储到云硬盘:生产级 JiuwenClaw 容器化部署完整指南
一、落地背景与目标
1.1 业务背景
JiuwenClaw 作为 AI Agent 平台核心组件,部署在 Kubernetes 集群中。初期采用容器临时存储(EmptyDir),存在以下痛点:
| 问题 | 影响 |
|---|---|
| Pod 重启数据丢失 | 用户技能、会话记录全部丢失 |
| 无法支持多租户 | 长期使用需求无法满足 |
| 数据可靠性差 | 生产环境稳定性无法保障 |
1.2 落地目标
- ✅ 数据持久化:每个 Pod 独立存储,数据不随容器生命周期消失
- ✅ 路径标准化:统一数据目录为
/app/.JiuwenClaw - ✅ 运维自动化:通过 PVC + StorageClass 实现动态管理
二、架构设计
2.1 StatefulSet + PVC 架构
┌─────────────────────────────────────────────────────────────┐
│ Kubernetes Cluster │
├─────────────────────────────────────────────────────────────┤
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ Pod-0 │ │ Pod-1 │ ... │ Pod-N │ │
│ │ JiuwenClaw │ │ JiuwenClaw │ │ JiuwenClaw │ │
│ └──────┬───────┘ └──────┬───────┘ └──────┬───────┘ │
│ │ │ │ │
│ ▼ ▼ ▼ │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ PVC-0 │ │ PVC-1 │ ... │ PVC-N │ │
│ │ 50Gi SSD │ │ 50Gi SSD │ │ 50Gi SSD │ │
│ └──────────────┘ └──────────────┘ └──────────────┘ │
└─────────────────────────────────────────────────────────────┘
2.2 核心配置
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: jiuwenclaw
namespace: <业务命名空间>
spec:
replicas: <副本数>
serviceName: headless-service
updateStrategy:
type: RollingUpdate
rollingUpdate:
partition: 0
persistentVolumeClaimRetentionPolicy:
whenDeleted: Retain
whenScaled: Retain
volumeClaimTemplates:
- metadata:
name: jiuwenclaw-users-data
spec:
accessModes: [ "ReadWriteOnce" ]
storageClassName: <SSD存储类名称>
resources:
requests:
storage: 50Gi
template:
spec:
containers:
- name: jiuwenclaw
image: <私有镜像仓库地址>/jiuwenclaw:<版本号>
env:
- name: JIUWEN_CLAW_ROOT
value: /app/.JiuwenClaw
- name: JIUWEN_CLAW_LOGS
value: /app/.JiuwenClaw/logs
- name: JIUWEN_CLAW_AGENT
value: /app/.JiuwenClaw/agent
# 其他业务环境变量已脱敏
volumeMounts:
- name: jiuwenclaw-users-data
mountPath: /app/.JiuwenClaw
三、落地实施步骤
3.1 升级前准备
检查清单:
| 检查项 | 命令 | 预期结果 |
|---|---|---|
| 存储类存在 | kubectl get storageclass | 目标存储类可用 |
| 存储配额 | 检查云硬盘配额 | 剩余 > 副本数 × 单盘容量 |
| 节点资源 | kubectl describe nodes | CPU/内存 requests 充足 |
| 备份配置 | 保存 YAML 文件 | 可快速回滚 |
3.2 执行升级
# 1. 备份旧配置
kubectl get statefulset jiuwenclaw -o yaml > jiuwenclaw-backup.yaml
# 2. 删除旧 StatefulSet(保留 Service)
kubectl delete statefulset jiuwenclaw -n <业务命名空间>
# 3. 强制清理卡住的 Pod
kubectl delete pod --force --grace-period=0 -n <业务命名空间> \
$(kubectl get pods -n <业务命名空间> | grep jiuwenclaw | awk '{print $1}')
# 4. 应用新配置
kubectl apply -f jiuwenclaw-statefulset-with-pvc.yaml
# 5. 监控启动状态
kubectl get pods -n <业务命名空间> -w
3.3 验证确认
# 验证 PVC 绑定状态
kubectl get pvc -n <业务命名空间>
# 验证挂载
kubectl exec -it jiuwenclaw-0 -- df -h /app/.JiuwenClaw
# 持久化测试
kubectl exec -it jiuwenclaw-0 -- touch /app/.JiuwenClaw/test.txt
kubectl delete pod jiuwenclaw-0 -n <业务命名空间>
# 重建后验证文件是否存在
四、升级前后对比
| 维度 | 升级前 | 升级后 |
|---|---|---|
| 存储类型 | EmptyDir(临时) | 云硬盘 SSD(持久) |
| 数据生命周期 | Pod 删除即丢失 | 独立于 Pod 生命周期 |
| 数据路径 | /app/jiuwenclaw | /app/.JiuwenClaw |
| PVC 管理 | 无 | 自动创建/绑定 |
| 滚动更新 | 数据全部丢失 | 数据保留 |
五、关键技术要点
5.1 PVC 生命周期策略
persistentVolumeClaimRetentionPolicy:
whenDeleted: Retain # StatefulSet 删除时保留 PVC
whenScaled: Retain # 缩容时保留 PVC
5.2 存储类配置要求
- 类型:SSD 云硬盘,满足 AI 应用 IOPS 需求
- 回收策略:Retain,确保数据安全
- 绑定模式:WaitForFirstConsumer,与 Pod 调度节点匹配
六、风险与回滚
6.1 风险评估
| 风险项 | 等级 | 缓解措施 |
|---|---|---|
| 服务中断 | 中 | 低峰期执行,提前通知 |
| 数据丢失 | 低 | 用户确认可接受,备份验证 |
| PVC 创建失败 | 低 | 预检存储类和配额 |
6.2 回滚方案
# 删除新 StatefulSet
kubectl delete statefulset jiuwenclaw -n <业务命名空间>
# 删除新 PVC
kubectl delete pvc -l app=jiuwenclaw -n <业务命名空间>
# 恢复旧配置
kubectl apply -f jiuwenclaw-backup.yaml
七、后续优化建议
- 镜像标准化:修改 Dockerfile,硬编码环境变量
- 监控告警:配置 PVC 使用率 >80% 告警
- 数据备份:定期使用 Velero 备份 PVC
- 容量规划:预留 20% 冗余空间
- 文档归档:将流程和模板存入知识库
八、落地总结
通过 StatefulSet + PVC 的标准 Kubernetes 机制,JiuwenClaw 成功实现了生产级持久化存储落地:
- ✅ 所有 Pod 均获得独立云硬盘
- ✅ 数据持久化验证通过
- ✅ 服务功能正常,WebSocket 连接稳定
- ✅ 升级中断时间控制在预期范围内
关键经验:容器化落地时,显式声明存储需求、做好预检和备份,是保障升级成功的核心。
技术标签:#JiuwenClaw #Kubernetes #StatefulSet #PVC #存储持久化 #AI Agent