从 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 后端。按照 从 Alauda Build of OpenTelemetry 迁移到 Alauda Build of OpenTelemetry v2 中的步骤执行此阶段。 -
Jaeger 后端迁移。 在旧版 Jaeger 旁部署新的
Jaeger v2实例,将旧版 Elasticsearch 索引附加到新实例的读取别名,将 v2 Collector 的 trace exporter 切换到新后端,并在新 pipeline 验证完成后卸载旧版 Jaeger。
旧版 trace 数据不会被复制或重新索引。其索引会附加到新 Jaeger 的读取别名,因此切换后,新的 Jaeger UI 会同时提供切换前和切换后的 trace,您可以在确信新 pipeline 正常工作后立即移除旧版堆栈,而不必等待完整的保留期限结束。
目录
概述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 迁移指南中的 v1 与 v2 之间的变化。
旧版 Alauda Build of Jaeger Operator 管理独立的 CRD(jaegertracing.io/v1.Jaeger),与 v2 OpenTelemetry Operator 不冲突。因此,在迁移期间会继续运行它,使旧版 Jaeger 在新 pipeline 验证完成前持续可用,作为回滚目标。
迁移中断窗口
Trace ingestion 会在以下两个位置中断:
-
OpenTelemetry v1 → v2 迁移期间,即从删除旧版
OpenTelemetryCollector到 v2OpenTelemetryCollector就绪之间。请参阅 OpenTelemetry v2 迁移指南中的 迁移中断窗口。 -
Jaeger 切换期间,即修补 v2 Collector,将其 trace exporter 从旧版 Jaeger 重定向到新版 Jaeger v2 后端时。Collector deployment 会执行滚动更新,因此更新期间可能出现短暂的 ingestion 间隔。
在这两个窗口期间,应用 Pod 均会继续正常运行,但在间隔期间生成的 telemetry 可能会暂时缓冲;如果无法及时导出,也可能被丢弃。请在低流量窗口期间规划每个阶段,并提前通知 telemetry 使用者(开发人员、SRE、Kiali 用户)。
在整个迁移过程中,旧版 Jaeger 查询路径仍然可用,因此在新 pipeline 启动期间,仍可在旧版 Jaeger UI 中搜索之前存储的 trace。
迁移流程概览
Trace 数据连续性策略
按照 OpenTelemetry v2 迁移期间 重新创建 OpenTelemetryCollector 资源 中的指导,v2 OpenTelemetry Collector 会部署在与旧版 Collector 相同的 namespace 中,并使用相同的 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 保存哪个时间范围的 trace;旧版堆栈也不再需要仅为了响应历史查询而持续运行完整的保留期限。
前置条件
- 由具有
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,而没有任何应用会与其通信。
到达变量设置步骤时,保留默认索引前缀,以便新的 Jaeger 将数据写入与旧版索引明确分离的索引:
完成安装步骤后,验证以下内容:
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 通过读取别名解析所有读取操作,因此只需将旧版按日期标记的索引添加到该别名,就能使切换前的 trace 可在新的 Jaeger UI 中查询。不会复制、重命名或重新索引任何内容,旧版 Jaeger 仍会提供相同索引的服务。
在切换前执行此步骤,以便新的 Jaeger UI 在开始接收 trace 时就已包含完整数据。
操作步骤
-
设置旧版索引前缀。该前缀是在清点旧版 Jaeger 部署中记录的
es.index-prefix值: -
将旧版索引添加到新索引系列的读取别名:
-2*模式匹配按日期标记的旧版索引,例如-2026-08-27,不会匹配新索引系列的编号滚动索引。未启用依赖分析和自适应采样运行的旧版 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 中仍会将 trace 写入旧版 Jaeger,因为其 trace exporter 继承自 v1 备份。其 spec.config 中与 trace 相关的部分通常如下所示(其他字段与此步骤无关,已省略):
- 旧版 Jaeger exporter — 继承自 v1 备份 — 名为
otlp,目标为cpaas-system中旧版 Jaeger Collector 的无头 Service。balancer_name: round_robin会在无头 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 会显示为十个 span。请参阅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的新索引(滚动增长)。 -
抽查真实业务请求是否会在新的 Jaeger UI 中生成 trace。选择一个或两个已完成插桩的应用,触发具有代表性的请求,然后在新的 Jaeger UI 中查找其 traceID。
-
确认切换前的 trace 仍可访问,并且新的 Jaeger 没有覆盖索引模板:
读取别名必须列出旧版按日期标记的索引以及新的
-000001索引,并且在切换前最后一次上报数据的服务仍必须显示在新的 Jaeger UI 中。第二条命令必须输出读取别名和
rollover_alias。如果结果为空,表示 Jaeger 实例在启动时重新创建了索引模板,因为create_mappings未设置为false。已附加的旧版索引不受影响,但未来的滚动索引将不再添加到读取别名中,ILM 也将无法执行滚动。请在 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将被停用。
确认新管道运行可靠后,继续执行清理。
删除旧版 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 只能对作为滚动别名写入索引的索引执行滚动。将其应用于按日期标记的旧版索引时,会失败并显示 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 控制台中打开功能开关,并禁用
acp-tracing-ui。卸载旧版 Alauda Build of OpenTelemetry v1 Operator 后,平台定制的可观测性 → Tracing视图将不再可用。更新内部文档和操作手册,将其指向 Jaeger UI URL<platform-url>/clusters/<cluster>/jaeger。 -
等待旧版索引过期。接管旧版索引的保留策略中应用的策略会在每个索引达到保留期后将其删除,并将其从读取别名中移除,因此此步骤无需执行任何操作,只需检查剩余内容:
若要在保留期结束前停用切换前的 trace,请直接删除索引,而不是等待其过期:
删除索引也会将其从读取别名中移除,因此新的 Jaeger 将不再返回这些 trace。
-
上一步的列表为空后,删除 ILM 不会自行清理的内容——旧版索引模板和仅删除策略:
回滚
有关 OpenTelemetry v1 → v2 阶段的回滚,请参阅 OpenTelemetry v2 迁移指南中的 回滚。对于本文档中执行的 Jaeger 迁移阶段,请根据当前所处的阶段选择相应的回滚路径:
要分离旧版索引,请反向执行将旧版索引附加到新的读取别名中的别名操作:
如果已经应用了接管旧版索引的保留策略中的仅删除 ILM 策略,也请将其移除,以免在恢复旧版堆栈期间旧版索引过期:
FAQ
应用是否需要更新其 OTLP 端点?
不需要。按照 OpenTelemetry v2 迁移指南中的 重新创建 OpenTelemetryCollector 资源 指南操作后,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 通过滚动别名写入(由 *-000001、*-000002 等支持的 acp-<cluster>-jaeger-span-write)。它们的生命周期分别管理,并且实际写入的始终只有新版的编号索引。请保留部署新版 Jaeger v2 实例中显示的默认前缀,以确保两个索引系列不会发生冲突。
迁移期间需要额外多少 Elasticsearch 存储空间?
新版索引系列会从零开始增长,而旧版索引系列会在旧版保留期限内逐渐过期;请按一整套额外保留期限所需的 trace 存储量规划稳定状态下的缓冲空间。将旧版索引附加到读取别名完全不会增加存储空间——它只会改变查询解析到的索引。
可以在迁移过程中启用 Service Performance Monitoring (SPM) 吗?
SPM 是可选功能,在验证迁移之后的任何时间都可以启用。按照(可选)启用 Service Performance Monitoring (SPM)中的说明,在新版 Jaeger 中添加 span_metrics connector 并配置 metrics 后端。