从 Alauda Container Platform Tracing 迁移
本文介绍如何将基于旧版 Alauda Container Platform (ACP) Tracing 堆栈的现有 tracing 部署 — Alauda Build of Jaeger(Jaeger 1.60.0)和 Alauda Build of OpenTelemetry — 迁移到基于 Jaeger v2(2.20.0)和 Alauda Build of OpenTelemetry v2 的 Alauda Distributed Tracing。
迁移分为两个阶段:
-
OpenTelemetry 堆栈迁移。 将旧版
Alauda Build of OpenTelemetryOperator 和 Collector 替换为Alauda Build of OpenTelemetry v2。重新部署应用 pod,以注入 v2 Java agent。完成此阶段后,telemetry 由 v2 Collector 收集,但仍写入旧版 Jaeger 后端。此阶段按照 Migrating from Alauda Build of OpenTelemetry to Alauda Build of OpenTelemetry v2 中的步骤执行。 -
Jaeger 后端迁移。 在旧版 Jaeger 旁部署新的
Jaeger v2实例,将旧版 Elasticsearch 索引关联到新实例的读取别名,将 v2 Collector 的 trace exporter 切换到新后端,并在新管道验证完成后卸载旧版 Jaeger。
旧版 trace 数据不会被复制或重新建立索引。其索引会关联到新 Jaeger 的读取别名,因此切换后,新的 Jaeger UI 会同时提供切换前和切换后的 trace,且只要确认新管道运行可靠,就可以移除旧版堆栈,无需等待完整的保留周期。
目录
概述ACP Tracing 与 Alauda Distributed Tracing 的变化迁移中断窗口迁移流程概览Trace 数据连续性策略前置条件迁移前任务将 Alauda Build of OpenTelemetry 迁移到 v2清点旧版 Jaeger 部署备份旧版 Jaeger 资源验证 Elasticsearch 容量迁移操作步骤验证期清理回滚FAQ概述
ACP Tracing 与 Alauda Distributed Tracing 的变化
有关 OpenTelemetry Operator、Collector 和 Instrumentation 资源的变更(包括现在必需的 spec.java.image 字段、与 Service Mesh v1 的不兼容性以及 Collector 配置架构迁移),请参阅 OpenTelemetry v2 迁移指南中的 What changes between v1 and v2。
旧版 Alauda Build of Jaeger Operator 管理独立的 CRD(jaegertracing.io/v1.Jaeger),不会与 v2 OpenTelemetry Operator 发生冲突。因此,在迁移期间会继续运行它,以便在新管道验证完成之前,旧版 Jaeger 始终可作为回滚目标。
迁移中断窗口
Trace ingestion 会在以下两个时点中断:
-
在 OpenTelemetry v1 → v2 迁移期间,从删除旧版
OpenTelemetryCollector到 v2OpenTelemetryCollector就绪之间。请参阅 OpenTelemetry v2 迁移指南中的 Migration outage window。 -
在 Jaeger 切换期间,将 v2 Collector 的 trace exporter 从旧版 Jaeger 重定向到新版 Jaeger v2 后端时。Collector deployment 会执行滚动更新,因此更新期间可能会出现短暂的 ingestion 间隔。
在这两个窗口期间,应用 pod 都会继续正常运行,但在间隔期间生成的 telemetry 可能会暂时缓冲;如果无法及时导出,也可能被丢弃。请在低流量时段规划每个阶段,并提前通知 telemetry 使用者(开发人员、SRE 和 Kiali 用户)。
在整个迁移期间,旧版 Jaeger 的查询路径仍然可用,因此在新管道启动期间,仍可在旧版 Jaeger UI 中搜索之前存储的 trace。
迁移流程概览
Trace 数据连续性策略
在 OpenTelemetry v2 迁移期间按照 Recreate the OpenTelemetryCollector resources 中的指导操作时,v2 OpenTelemetry Collector 会部署在与旧版 Collector 相同的命名空间中,并使用相同的 Service 名称(otel-collector,位于 cpaas-system 中)。将 OTLP 导出到 otel-collector.cpaas-system 的应用无需更改任何配置即可继续运行。
Trace 数据既不会被复制,也不会被重新建立索引。旧版按日期标记的索引会保留在原处,并在将旧版索引关联到新的读取别名中关联到新 Jaeger 的读取别名。Jaeger v2 通过这些别名解析所有读取请求,因此完成关联后:
- 在切换前摄取的 trace 会保留在旧版索引(
acp-tracing-<cluster>-jaeger-*-YYYY-MM-DD)中,并由位于<platform-url>/clusters/<cluster>/jaeger的新版 Jaeger UI 与新 trace 一起提供服务,直到其自身的保留策略将其删除。只要保留旧版实例,这些 trace 也会继续显示在旧版 Jaeger UI 中。 - 在切换后摄取的 trace 会通过
*-write别名写入新版索引系列(acp-<cluster>-jaeger-*-000001、-000002、……)。旧版索引不会再次被写入。
之所以可行,是因为 Jaeger 2.20.0 会按原样读取 Jaeger 1.60.0 写入的文档:两个版本使用相同的 Elasticsearch 文档模型,其间的映射差异 — 旧版模板声明 tags.tagType,而 v2 模板声明 tags.type,并且 v2 增加了 scopeTags 和 references.traceState — 不会影响 Jaeger 查询所使用的任何字段。
由于从关联别名的那一刻起,新的 Jaeger UI 就已完整可用,用户无需了解不同时间范围由哪个 UI 提供,旧版堆栈也不再需要仅仅为了响应历史查询而持续运行完整的保留周期。
前置条件
- 由具有
cluster-admin角色的集群管理员建立的活动 ACP CLI(kubectl)会话。 - 旧版 ACP Tracing 堆栈(
Alauda Build of JaegerOperator 及其Jaeger实例,以及包含OpenTelemetryCollector和一个或多个Instrumentation资源的Alauda Build of OpenTelemetry)当前已安装。 - 集群可以访问 Elasticsearch 8.x,并且你拥有具有创建 ILM 策略、索引模板和索引别名权限,以及更新索引设置权限的 Elasticsearch 用户。
jq和envsubst命令行工具已安装在运行迁移命令的工作站上。- 已通知 telemetry 使用者(开发人员、Kiali 用户、SRE 仪表板使用者)和应用所有者计划中的中断窗口。
迁移前任务
将 Alauda Build of OpenTelemetry 迁移到 v2
在迁移 Jaeger 后端之前,请按照 从 Alauda Build of OpenTelemetry 迁移到 Alauda Build of OpenTelemetry v2 完成从 Alauda Build of OpenTelemetry 到 Alauda Build of OpenTelemetry v2 的迁移。该指南涵盖:
- 备份并卸载旧版
Alauda Build of OpenTelemetryOperator 及其OpenTelemetryCollector和Instrumentation资源。 - 安装 v2 Operator。
- 准备用于 Java 自动插桩的镜像,并重新创建
OpenTelemetryCollector和Instrumentation资源,包括设置现在必需的spec.java.image字段。 - 滚动更新应用 pod,以便注入新的 Java agent。
在此阶段结束时:
- v2
Alauda Build of OpenTelemetryOperator 已安装,旧版 Operator 已卸载。 cpaas-system中的 v2OpenTelemetryCollector正在运行,其 trace exporter 仍指向旧版 Jaeger(这是从 v1 备份重新创建 Collector 的自然结果)。- 所有
Instrumentation资源均已设置spec.java.image,并且应用 pod 已使用 v2 Java agent 完成滚动更新。
在本指南的将 v2 OpenTelemetry Collector 切换到新 Jaeger之前,Trace 摄取会继续流入旧版 Jaeger。
清点旧版 Jaeger 部署
记录旧版 Jaeger 的当前状态,以便了解迁移范围,并生成用于回滚的备份。
-
列出旧版
Alauda Build of JaegerOperator 和Jaeger实例: -
记录旧版
Jaeger资源中引用的旧版 Elasticsearch 端点、凭据和索引前缀。新 Jaeger v2 实例也会重复使用这些信息。
备份旧版 Jaeger 资源
导出旧版 Jaeger 资源,以便重新构建这些资源(并在需要时执行回滚):
备份文件仅用作配置参考和回滚构件。在 v2 上重新构建 Jaeger 时,请遵循安装 Alauda Distributed Tracing中所述的 v2 约定。
验证 Elasticsearch 容量
新 Jaeger 会写入单独的索引系列(acp-<cluster>-jaeger-*),而旧版索引(acp-tracing-<cluster>-jaeger-*)会在旧版保留期限内逐渐过期。请为 Elasticsearch 规划额外一整个保留期限所需的 trace 存储空间。
迁移操作步骤
部署新的 Jaeger v2 实例
按照 Alauda Distributed Tracing 安装指南中的部署 Alauda Build of Jaeger v2进行操作。新的 Jaeger v2 实例会部署在专用命名空间中(默认为 jaeger-system),因此不会与 cpaas-system 中旧版的 jaeger-prod 实例冲突。
仅按照上面链接的 部署 Alauda Build of Jaeger v2 部分进行操作。不要执行同一安装指南中的 部署 OpenTelemetry Collector 部分 — 面向应用的 v2 OpenTelemetry Collector 已在阶段 1(OpenTelemetry v2 迁移)期间部署到 cpaas-system。执行该部分会在 jaeger-system 中创建一个重复的 otel Collector,而没有任何应用会与其通信。
到达变量设置步骤时,保留默认索引前缀和基础路径。两者都必须与旧版实例使用的值不同:
接管旧版索引的保留期限和禁用旧版功能开关并弃用旧版索引系列会根据 ${LEGACY_ES_INDEX_PREFIX}-jaeger-* 选择索引。如果新系列共享该前缀,则匹配模式也会匹配其编号索引:删除专用策略会应用于这些索引,弃用步骤会将它们与读写别名一起删除。此外,新系列的 rollover 初始化还会覆盖旧版索引模板,因为此时两个系列使用相同的模板名称。
完成安装步骤后,验证以下内容:
jaeger-system中的 Jaeger Pod 为Ready。- Jaeger UI 可通过
<platform-url>/clusters/<cluster>/jaeger访问。此时 UI 为空,因为尚无 exporter 向其写入数据,旧版索引也尚未附加。 - Service
jaeger-collector.jaeger-system.svc.cluster.local在端口4317接受 OTLP gRPC — 这就是 v2 OpenTelemetry Collector 将在将 v2 OpenTelemetry Collector 切换到新的 Jaeger中导出数据的端点。
将旧版索引附加到新的读别名
上一步运行的 jaeger-es-rollover init Job 创建了新索引系列的 <prefix>-jaeger-<type>-read 和 <prefix>-jaeger-<type>-write 别名。Jaeger v2 通过读别名解析所有读取请求,因此只需将旧版日期索引添加到该别名,即可在新的 Jaeger UI 中查询迁移前的 trace。不会复制、重命名或重新索引任何内容,旧版 Jaeger 仍会继续提供相同的索引。
在切换前执行此步骤,以便新的 Jaeger UI 在开始接收 trace 时已经包含完整数据。
操作步骤
-
设置旧版索引前缀。它是在清查旧版 Jaeger 部署中记录的
es.index-prefix值: -
将旧版索引添加到新索引系列的读别名:
-2*模式会匹配带日期的旧版索引,例如-2026-08-27,而不会匹配新系列的编号 rollover 索引。在未启用依赖分析和自适应采样的情况下运行的旧版 Jaeger 不会有dependencies和sampling索引,因此这两次迭代会返回index_not_found_exception。这是预期行为,不会影响另外两个索引。若只需附加部分历史数据,请将模式缩小到所需日期范围,例如
${LEGACY_ES_INDEX_PREFIX}-jaeger-${TYPE}-2026-08-1*。每次查询都会扫描所有已附加的索引,因此只附加仍需要搜索的索引。 -
确认两个索引系列都可通过读别名解析,并且写别名仍仅指向新的编号索引:
示例输出
只有
-000001索引携带is_write_index: true。旧版索引仅附加用于读取,因此新的 Jaeger 无法写入这些索引。 -
在
<platform-url>/clusters/<cluster>/jaeger打开新的 Jaeger UI,确认切换前上报过数据的服务已列出,并且可以打开其中一个服务的 trace。NOTE在 UI 中选择覆盖旧版数据的时间范围。Jaeger UI 始终会发送明确的时间范围,因此其时间范围选择器可以按预期工作。
将 v2 OpenTelemetry Collector 切换到新的 Jaeger
在完成OpenTelemetry v1 → v2 迁移后,重新创建的 otel OpenTelemetryCollector 仍位于 cpaas-system 中,并继续向旧版 Jaeger 写入 trace,因为其 trace exporter 继承自 v1 备份。其 spec.config 中与 trace 相关的部分通常如下所示(其他字段与此步骤无关,因此省略):
- 从 v1 备份继承的旧版 Jaeger exporter 名为
otlp,目标是cpaas-system中旧版 Jaeger Collector 的 headless Service。balancer_name: round_robin会在 headless Service 的端点之间分发 span。otlp是otlp_grpcexporter 类型的弃用别名,下面的切换步骤将采用后者。 - trace pipeline 会将 span 发送到
debug(日志)和otlp(旧版 Jaeger)。
修补 Collector,以便 (1) 添加一个指向 jaeger-system 中新 Jaeger v2 Collector Service 的新 otlp_grpc/jaeger-v2 exporter,(2) 将旧版 otlp exporter 设置为 null,从而移除该 exporter,以及 (3) 将 trace pipeline 的 exporter 列表替换为 [debug, otlp_grpc/jaeger-v2]:
otlp_grpc
exporter 类型名称为 otlp_grpc,而不是 otlp。前一个名称仍可作为弃用别名使用,但 Collector 会在启动时为每个受影响的组件实例记录弃用警告,上游计划在未来版本中移除该别名。由于继承的 exporter 无论如何都要被替换,此次迁移正好可以采用当前名称。
此重命名仅适用于新创建的 exporter。保留 otlp: null 不变:它会移除 Collector 上已使用该名称的 exporter。
service.pipelines.traces.exporters 是一个数组,合并补丁会整体替换数组,而不是追加数组内容。上面的补丁列出了 trace pipeline 中必须保留的所有 exporter(debug、otlp_grpc/jaeger-v2)。如果你的 trace pipeline 包含其他自定义 exporter,请在应用补丁前将它们添加到此列表中。
如果 Collector 上继承的旧版 Jaeger exporter 名称不是 otlp(例如你的 v1 备份使用了 jaeger 或其他 OTLP 变体),请在 null 移除步骤中相应替换该名称。
上面的补丁会替换旧版 exporter,而不是添加第二个 exporter。不要让两个 exporter 同时保留在 pipeline 中。由于旧版索引已附加到读别名,写入两个后端的 span 会同时编入两个索引系列,新 Jaeger 会将其返回两次 — 一个包含五个 span 的 trace 会显示为十个。请参阅Trace 数据连续性策略。
至此,trace 摄取已恢复。新的 trace 会写入新的 Jaeger v2 后端,并可在新的 Jaeger UI 中搜索。
验证迁移
-
确认两个
OpenTelemetryCollector资源均处于健康状态:示例输出:
cpaas-system/otel(面向应用的 Collector,由 OpenTelemetry v1 → v2 迁移重新部署)和jaeger-system/jaeger(新的 Jaeger v2 后端,在部署新的 Jaeger v2 实例中部署)都必须报告READY为<ready>/<desired>,其中<ready>等于<desired>(通常为1/1),并且MANAGEMENT为managed。如果READY列显示0/1或为空,请在继续之前检查相应命名空间中的 Collector Pod 日志。 -
使用
telemetrygen生成示例 trace,并确认它们显示在新的 Jaeger UI 中:位于
<platform-url>/clusters/<cluster>/jaeger的新 Jaeger UI 应列出jaeger-migration-check服务及其 trace。 -
确认新的索引系列正在 Elasticsearch 中创建,并且旧版索引系列完整无缺:
你应看到匹配
acp-tracing-<cluster>-jaeger-*的旧版索引(带日期、不再增长)以及匹配acp-<cluster>-jaeger-*-000001的新索引(rollover、持续增长)。 -
抽查一个真实业务请求,确认其在新的 Jaeger UI 中生成 trace。选择一个或两个已完成 instrumentation 的应用,触发一个具有代表性的请求,然后在新的 Jaeger UI 中查找其 traceID。
-
确认迁移前的 trace 仍可访问,并且新的 Jaeger 没有覆盖索引模板:
读别名必须同时列出旧版日期索引和新的
-000001索引,并且在切换前最后一次上报数据的服务仍必须显示在新的 Jaeger UI 中。第二条命令必须输出读别名和
rollover_alias。如果结果为空,表示 Jaeger 实例启动时重新创建了索引模板,因为create_mappings未设置为false。已经附加的旧版索引不受影响,但后续 rollover 索引将不再添加到读别名,并且 ILM 将无法继续执行 rollover。在 Jaeger 实例上设置create_mappings: false,然后重新运行安装指南中的jaeger-es-rollover initJob。
验证期
无需将旧版 Jaeger 保留完整的保留周期。切换前的 trace 由新的 Jaeger 通过读别名提供,因此旧实例仅用作回滚目标。只要你希望保留该回退能力,就应持续保留它——通常为几小时到几天——并利用此窗口:
- 针对新的 Jaeger UI 和 v2 Java agent 指标名称,验证仪表板、告警和 Kiali 集成。
- 确认切换前和切换后的 trace 都可以在新的 Jaeger UI 中搜索。
- 告知用户新的 Jaeger UI 现已成为 trace 的唯一入口,旧版 UI
<platform-url>/clusters/<cluster>/acp/jaeger将被停用。
确认新 pipeline 运行可靠后,继续执行清理。
删除旧版 Jaeger 实例不会删除其 Elasticsearch 索引,因此切换前的 trace 之后仍可在新的 Jaeger UI 中查询。删除的内容是由 Jaeger 资源拥有的旧版 jaeger-es-index-cleaner CronJob。此后将不会再有任何机制使这些索引过期,这正是为什么必须先执行接管旧版索引的保留策略。
清理
接管旧版索引的保留策略
到目前为止,旧版 jaeger-es-index-cleaner CronJob 一直在使旧版索引过期。该 CronJob 由旧版 Jaeger 资源拥有,并将在下一步中随该资源一起进行垃圾回收,因此必须先移交保留策略。否则旧版索引会无限期保留在 Elasticsearch 中——而且由于它们已附加到读别名,还会继续在每次查询中被扫描。
为这些索引指定专属的 Index Lifecycle Management 策略,其中只能包含一个 delete 阶段。
jaeger-ilm-policy 无法管理旧版索引
jaeger-ilm-policy 还包含一个 rollover 操作,而 Elasticsearch 只能对 rollover 别名的写入索引执行 rollover。将其应用于带日期标记的旧版索引时,会失败并显示 setting [index.lifecycle.rollover_alias] for index [...] is empty or not defined,索引永远不会离开 hot 阶段,也永远不会被删除。因此必须使用单独的仅删除策略。
在切换完成后执行此步骤,确保旧版 Jaeger 已停止创建新的每日索引。
操作步骤
-
创建策略。将
min_age设置为旧版清理器应用的保留期限,即盘点旧版 Jaeger 部署中记录的esIndexCleaner.numberOfDays值,默认为7: -
将其应用于整个旧版索引系列:
-
确认每个旧版索引都受策略管理,并且没有任何索引报告错误。Elasticsearch 默认每 10 分钟轮询一次 ILM,因此阶段在推进前会暂时保持为
new:每个索引都必须报告
"managed" : true,其策略为jaeger-legacy-ilm-policy,并且不得出现任何"reason"行。
当索引达到保留期限末尾时,Elasticsearch 会将其删除,并自动将其从读别名中移除——无需维护该别名。
卸载旧版 Jaeger 实例
删除旧版 Jaeger 实例及其支持资源。Elasticsearch 索引不会受到影响,因此切换前的 trace 仍可在新的 Jaeger UI 中查询:
卸载 Alauda Build of Jaeger Operator:
如果集群中不再存在其他 Jaeger 资源,也可以删除 jaegers.jaegertracing.io CRD:
禁用旧版功能开关并停用旧版索引系列
-
在 ACP Web 控制台中,打开 Feature Switch,并禁用
acp-tracing-ui。卸载旧版 Alauda Build of OpenTelemetry v1 Operator 后,平台定制的 Observability → Tracing 视图将不再可用。更新内部文档和操作手册,将其指向 Jaeger UI URL<platform-url>/clusters/<cluster>/jaeger。 -
等待旧版索引过期。接管旧版索引的保留策略中应用的策略会在每个索引达到保留期限后将其删除,并从读别名中移除,因此此步骤无需执行任何操作,只需检查剩余内容:
如果要在保留期限结束前停用切换前的 trace,请直接删除索引,而不是等待其过期:
删除索引也会将其从读别名中移除,因此新的 Jaeger 将不再返回这些 trace。
-
上一步的列表为空后,删除 ILM 不会自行清理的内容——旧版索引模板和仅删除策略:
回滚
有关 OpenTelemetry v1 → v2 阶段的回滚,请参阅 OpenTelemetry v2 迁移指南中的 Rollback。对于本文档中执行的 Jaeger 迁移阶段,请根据当前所处阶段选择相应的回滚路径:
要分离旧版索引,请反向执行将旧版索引附加到新的读别名中的别名操作:
如果接管旧版索引的保留策略中的仅删除 ILM 策略已经应用,也请将其移除,以免在恢复旧版堆栈期间旧版索引过期:
FAQ
应用是否需要更新其 OTLP 端点?
不需要。按照 OpenTelemetry v2 迁移指南中 Recreate the OpenTelemetryCollector resources 的指导操作后,v2 OpenTelemetry Collector 会部署在相同的命名空间(cpaas-system)中,使用相同的 Service 名称(otel-collector)和相同的端口(4317/4318)。导出到 otel-collector.cpaas-system:4317 的工作负载无需任何更改即可继续工作。
新版 Jaeger UI 会显示切换之前的 trace 吗?
会,在完成将旧版索引附加到新的读别名后即可。旧版索引会添加到新索引系列的读别名中,因此在旧版索引达到其保留期限之前,新版 Jaeger UI 会同时提供切换前和切换后的 trace。不会复制或重新建立索引,旧版索引仍保持只读。
如果跳过此步骤,行为将与 2.1 之前的版本相同:切换前的 trace 只能通过旧版 Jaeger UI 访问,并会在移除旧版堆栈时丢失。
是否需要重新建立旧版数据的索引,或将其转换为 Jaeger v2 格式?
不需要。Jaeger 1.60.0 和 Jaeger 2.20.0 写入相同的 Elasticsearch 文档模型,因此 Jaeger v2 会直接读取旧版文档。索引模板有所不同——旧版模板声明 tags.tagType,而 v2 模板声明 tags.type,并且 v2 添加了 scopeTags 和 references.traceState——但 Jaeger 会通过 tags.key 和 tags.value 解析标签搜索,这两个字段在两个模板中的索引方式相同。可以将旧版数据重新建立到 v2 映射中,但不会带来任何功能收益。
是否可以同时写入两个 Jaeger 后端?
不可以。将旧版索引附加到读别名后,同时导出到两个后端的 span 会分别由旧版 Jaeger 写入旧版索引系列,并由新版 Jaeger 写入新版索引系列。单个读别名会解析到这两个索引,而 Jaeger 不会对 span 去重,因此新版 Jaeger UI 会将每个 span 显示两次。在 Collector trace pipeline 中始终只保留一个 Jaeger exporter。执行回滚时,应将这个 exporter 切回旧版 Jaeger,而不是添加第二个 exporter;请参阅回滚。
旧版 Jaeger 和新版 Jaeger 可以共享同一个 Elasticsearch 索引吗?
不可以——它们共享的是读别名,而不是索引。旧版 Jaeger 写入按日期命名的每日索引(acp-tracing-<cluster>-jaeger-span-YYYY-MM-DD),而 Jaeger v2 通过 rollover 别名写入(由 *-000001、*-000002 等提供支持的 acp-<cluster>-jaeger-span-write)。它们的生命周期分别管理,并且只有新的编号索引会被写入。请保留部署新版 Jaeger v2 实例中显示的默认前缀,以避免两个索引系列发生冲突。
迁移期间需要多少额外的 Elasticsearch 存储空间?
新的索引系列会从零开始增长,而旧版索引系列会在旧版保留期限内逐渐过期;请按一份完整额外保留期的 trace 存储量规划稳定状态下的缓冲空间。将旧版索引附加到读别名完全不会增加存储空间——它只会改变查询解析到的索引。
是否可以在迁移过程中启用 Service Performance Monitoring(SPM)?
SPM 是可选功能,可在验证迁移之后的任意时间启用。按照(可选)启用 Service Performance Monitoring(SPM)中的说明,在新版 Jaeger 中添加 span_metrics connector 并配置指标后端。