Onyx Helm Chart 升级迁移指南:0.4.x → 0.5.x 破坏性变更详解与安全操作手册
【免费下载链接】danswerOpen Source AI Platform - AI Chat with advanced features that works with every LLM项目地址: https://gitcode.com/GitHub_Trending/da/danswer
Onyx(本仓库当前维护的开源 AI 平台,Helm Chart 位于 deployment/helm)在 Chart 0.5.0 版本引入了两项影响升级的破坏性变更:移除内嵌的 Vespa 子图表,以及新增celery-worker-scheduled-tasks部署。本文以官方迁移文档 deployment/helm/MIGRATION.md 为主线,结合 Chart 模板与后端 Celery 源码,逐项说明变更原因、失败症状、安全升级步骤与可验证的规避手段,帮助你避免“一次helm upgrade删掉索引数据”的事故。
背景:Chart 0.5.0 之前的架构形态
在 0.5.0 之前,Onyx Chart 将 Vespa 作为内嵌子图表(charts/vespa/)随 Chart 一起安装:集群中会出现一个名为da-vespa的 StatefulSet,Onyx 的 api-server 直接连接localhost:19071(Vespa 应用部署端口)向其下发应用包,Chart 托管的 PV 中保存着被索引的语料数据。
Chart 0.5.x 系列则彻底改变了这一假设——Vespa 不再由 Chart 托管,而是假定你运行的是 Chart 外部的 Vespa 集群,包括:
- 托管式 Vespa(Vespa Cloud);
- 自建、独立于本 Chart 管理的 Vespa 部署(例如部署在另一个 namespace 中)。
这一架构变化与当前 Chart 的依赖结构一致:在 deployment/helm/charts/onyx/Chart.yaml 的dependencies列表中已经看不到任何 Vespa 子图表,取而代之的是 CloudNativePG(PostgreSQL)、OpenSearch、Redis、MinIO、ingress-nginx 等基础设施组件。
破坏性变更一:移除内嵌 Vespa 子图表
为什么这是破坏性的
如果从 0.4.x 直接执行一次“天真”的helm upgrade到 0.5.x,由于 0.5.x 的模板中不再渲染任何 Vespa 相关内容,Helm 会删除da-vespaStatefulSet。其 PVC 底下的 PV 虽然会被孤立(orphaned),但其中的数据在手动重新挂载之前是不可访问的。更糟的是,api-server 会陷入 crash-loop,不断尝试向本地端口下发 Vespa 应用包,典型报错为:
ConnectionRefusedError: [Errno 111] Connection refused HTTPConnection(host='localhost', port=19071): Failed to establish a new connection也就是说:数据不可达 + 服务无法启动,双重故障同时发生。
Chart 自带的“防呆”守卫
为避免用户静默踩坑,Chart 0.5.x 在 deployment/helm/charts/onyx/templates/legacy-vespa-check.yaml 中内置了一个迁移守卫。其实现要点(可直接阅读模板源码验证):
- 使用 Helm 的
lookup函数实时查询集群中当前 namespace 是否存在da-vespaStatefulSet,因此只在helm install/helm upgrade时触发,本地helm template渲染不会命中; - 若检测到旧的 StatefulSet 且未显式确认迁移,直接调用
fail中止安装/升级,输出一段包含错误说明、处置步骤和文档链接的清晰提示,而不是静默删除数据; - 模板中对
legacyVespaCheck的enabled/acknowledged两个键都做了hasKey守卫——这专门保护helm upgrade --reuse-values场景:如果历史 release 中存储的 values 早于legacyVespaCheck键被引入的时间,直接嵌套访问会 nil-deref 并静默绕过整个防呆路径;而缺失时按“安全默认值”(启用、未确认)处理,保证保护机制默认生效。
如何安全升级
迁移文档给出了标准五步流程,每一步都值得在执行前确认:
- 搭建外部 Vespa 集群:选择 Vespa Cloud 或自建、位于本 Chart 之外的部署,取决于你的运维模型;
- 无需手动重建索引:Vespa 数据无法在不同 release 之间直接往返迁移(chunk schema 本身也随版本多次变化)。升级完成后,只要 api-server 能连通新端点,Onyx 连接器会自动重新索引——文档明确标注这是自动行为,不需要人工干预;
- 更新 values 指向外部端点:api-server 通过
VESPA_HOST/VESPA_PORT环境变量连接 Vespa,把它们配置在configMap:块中即可。注意 Chart 在 deployment/helm/charts/onyx/templates/configmap.yaml 中通过range .Values.configMap把所有非空键值渲染成 ConfigMap 的 data 项,configMap:块内的任何自定义键(包括VESPA_HOST/VESPA_PORT)都会被原样注入所有后端工作负载; - 确认无误后删除旧 StatefulSet:删除前务必核对 PV 的 reclaim policy,它决定底层磁盘是否随 PV 一起被回收——数据在 PV 被回收的那一刻就彻底消失了;
- 执行
helm upgrade到 0.5.x:如果旧 StatefulSet 已经不存在,守卫检查会自动通过,升级顺利继续。
绕过守卫的两个开关
如果你已经完成了迁移、只剩下一个残留的 PV 卡在 namespace 里,可以在 values 中显式确认:
legacyVespaCheck: acknowledged: true或者彻底关闭检查:
legacyVespaCheck: enabled: false这两个键在 deployment/helm/charts/onyx/values.yaml 中的默认值为enabled: true、acknowledged: false,即默认开启、默认不豁免。对应模板实现见 deployment/helm/charts/onyx/templates/legacy-vespa-check.yaml(第 31-36 行:if $checkEnabled且lookup命中且未 acknowledged 时fail)。
注意:
acknowledged只应在你确定旧 StatefulSet 已删除或有意保留时才设置;否则它只是把事故从“升级时失败”推迟到“升级后数据丢失”。
破坏性变更二:新增celery-worker-scheduled-tasks部署
它是什么
Chart 0.5.x 新增了一个名为celery-worker-scheduled-tasks的 Deployment,专门运行onyx.background.celery.versioned_apps.scheduled_tasks这个 Celery 应用。从后端源码看,这个应用的职责链条非常清晰:
- backend/onyx/background/celery/versioned_apps/scheduled_tasks.py 是一个工厂桩(factory stub),通过
fetch_versioned_implementation解析出真正的应用; - 真正实现位于 backend/onyx/background/celery/apps/scheduled_tasks.py,它从独立的配置模块加载 Celery 配置并启动指标服务器;
- 具体任务在 backend/onyx/background/celery/tasks/scheduled_tasks/tasks.py:
dispatch_due_scheduled_tasks(跑在 primary 队列,按租户周期性认领到期任务并把执行器分发到scheduled_tasks队列)和run_scheduled_task(跑在scheduled_tasks队列,执行具体任务)。
升级失败的典型症状
这个应用只存在于onyxdotapp/onyx-backend镜像中“scheduled tasks v1”变更之后构建的版本。如果你只升级 Chart 而没有同步升级后端镜像,新 Deployment 会 crash-loop,报错:
Error: Unable to load celery application. The module onyx.background.celery.versioned_apps.scheduled_tasks was not found.它何时被渲染
从 deployment/helm/charts/onyx/templates/celery-worker-scheduled-tasks.yaml 的模板条件(第 1 行)可以精确还原渲染逻辑,需要同时满足:
vectorDB.enabled为真(向量库功能开启);celery_worker_scheduled_tasks.replicaCount > 0;configMap.ENABLE_CRAFT为"true"(即启用了 Onyx 的 craft / sandbox 功能)。
模板中的启动命令为celery -A onyx.background.celery.versioned_apps.scheduled_tasks worker --hostname=scheduled_tasks@%n -Q scheduled_tasks,并配置了 readiness / liveness 探针(通过python onyx/background/celery/celery_k8s_probe.py检查就绪文件),以及基于celery_worker_scheduled_tasks的 HPA / KEDA ScaledObject 支持。
镜像太旧时的处理
文档明确说明:该 Deployment 已受其replicaCount门控。如果你的镜像太旧,直接在 values 中显式禁用:
celery_worker_scheduled_tasks: replicaCount: 0scheduled-tasks worker 仅在启用 craft / sandbox 功能时才需要;否则保持禁用是安全的。
该 worker 的完整配置项
deployment/helm/charts/onyx/values.yaml 中对该 worker 的注释解释了设计动机:它为 craft 的“调度任务无头执行器”提供专用资源,之所以与heavyworker 隔离,是因为每次调度任务的执行都是长时运行(在沙箱中进行 LLM + 工具调用),若不隔离会挤占 prune(清理)、权限同步、CSV 导出等任务的工作槽位;而轻量的“调度器”和“卡死任务清扫器”只做 DB 协调,跑在 primary 队列上。主要配置项:
| 配置项 | 默认值 | 说明 |
|---|---|---|
celery_worker_scheduled_tasks.replicaCount | 1 | 副本数;设为0可完全禁用 |
celery_worker_scheduled_tasks.logLevel | "" | 每 worker 日志级别覆盖,空值沿用全局LOG_LEVEL;设置后作为--loglevel=<value>传给 celery 命令 |
celery_worker_scheduled_tasks.autoscaling.enabled | false | 是否启用 KEDA 自动伸缩;启用后由minReplicas/maxReplicas/ CPU / 内存阈值驱动 |
celery_worker_scheduled_tasks.resources | requests500m/512Mi,limits2000m/2Gi | 容器资源配额 |
celery_worker_scheduled_tasks.extraEnv | [] | 追加环境变量 |
celery_worker_scheduled_tasks.podLabels | scope: onyx-backend-celery | Pod 标签 |
celery_worker_scheduled_tasks.nodeSelector/tolerations/affinity | 空 | 调度约束 |
这些资源/调度约束会被模板原样渲染进 Deployment 的 pod spec(见 celery-worker-scheduled-tasks.yaml 第 44-55 行),镜像统一来自celery_shared.image。
升级前检查清单(可执行)
综合迁移文档与源码实现,0.4.x → 0.5.x 升级前建议逐项核对:
- 确认 Vespa 归属:
kubectl get sts -n <namespace> da-vespa是否还存在?若存在,先按“安全升级五步”完成外部 Vespa 接入,再删除旧 StatefulSet; - 确认后端镜像版本:镜像是否包含
onyx.background.celery.versioned_apps.scheduled_tasks模块?可在镜像内执行python -c "import onyx.background.celery.versioned_apps.scheduled_tasks"验证;不确定时先按文档建议保留celery_worker_scheduled_tasks.replicaCount: 0; - 确认 craft / sandbox 使用情况:不使用 craft 功能则 scheduled-tasks worker 可以保持禁用;
- 更新 values 中的
configMap:块:设置VESPA_HOST、VESPA_PORT指向外部 Vespa 端点; - 执行升级并观察守卫:
helm upgrade时若触发 legacy-vespa-check 的fail提示,按提示信息处理,不要用--force或删改 values 强行绕过。
这套“模板内置 fail-fast 守卫 + 迁移文档 + 门控式新增工作负载”的组合,是 Helm Chart 演进中处理破坏性变更的典型范式:既保留了向前兼容的灰度空间(replicaCount: 0与acknowledged开关),又通过lookup实时检测防止了最危险的数据删除场景,值得在自定义 Chart 的升级策略中借鉴。
【免费下载链接】danswerOpen Source AI Platform - AI Chat with advanced features that works with every LLM项目地址: https://gitcode.com/GitHub_Trending/da/danswer
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考