9.0 移除了
tracing.apm.*系列设置,改用telemetry.*/telemetry.tracing.*。这条 breaking 的失效方式是"节点拒绝启动"——是起不来,不是配了不生效。而且官方特别点名:包括 keystore 里的 secret settings。
说明
实测环境:本地起的 Elasticsearch 9.4.2 单节点实例(官方 tar 包直接跑,堆内存 512MB,安全与机器学习关闭),curl 连本地 9200 端口。本文「实测」小节的命令和输出都出自这个实例。
来源和边界先交代:本文的依据出自 v9.4.2 标签下的官方文件(9.0.0.yml、APMAgentSettings.java),文中引用的原文均来自这些文件。示例取自官方示例;哪些是文档写明、哪些是我的推断,正文里逐处标注。
图 1:官方文件 9.0.0.yml(v9.4.2 标签)。来源:GitHub elastic/elasticsearch v9.4.2 9.0.0.yml
官方条目
9.0 的 changelog 标为 breaking(9.0.0.yml 第 1430–1440 行 @ v9.4.2),area: Infra/Metrics,PR 119968。
details 和 impact 都很完整,是少数把失效方式写得斩钉截铁的条目。
图 2:官方文件 APMAgentSettings.java(v9.4.2 标签)。来源:GitHub elastic/elasticsearch v9.4.2 APMAgentSettings.java
官方原文
details:
Deprecated
tracing.apm.*settings got removed, use respectivetelemetry.*/telemetry.tracing.*settings instead.
impact:
9.x nodes will refuse to start if any such setting (including secret settings) is still present.
第二句要逐字读:
- 节点会拒绝启动(refuse to start);
- 任何这样的设置(any such setting);
- 包括 secret settings(including secret settings)。
两个设置体系
旧的:tracing.apm.* —— 早年为 APM 链路追踪引入的设置。
新的:telemetry.* / telemetry.tracing.* —— 后来统一的遥测(telemetry)设置体系。
改名背后的意图是这样的(这是理解,官方没解释):最初只有 APM 链路追踪,所以叫 tracing.apm。后来 ES 要支持的不只是追踪,还有指标(metrics)、以及不同的后端实现——继续叫 apm 就不合适了,于是统一成 telemetry。
源码里的注释支持这个理解。
图 3:官方页面 PR #119968。来源:GitHub elastic/elasticsearch pull/119968
源码里的证据
APM 模块的设置类里有几处注释直接说明了替代关系。
APMAgentSettings.java 第 220 行(源码 @ v9.4.2):
// forbid secret_token: use telemetry.secret_token instead
明确写了"禁止 secret_token,改用 telemetry.secret_token"。
第 132 行(源码 @ v9.4.2):
// forbid 'recording', controlled by 'telemetry.metrics.enabled' / 'telemetry.tracing.enabled'
recording 被禁止,改由 telemetry.metrics.enabled / telemetry.tracing.enabled 控制。
这两处注释的价值在于:它们展示了新旧设置的对应关系,而不只是说"旧的没了"。
另外确认了一件事:9.4.2 的 server/src/main/java/ 下已经搜不到任何 tracing.apm 的残留(git grep "tracing.apm" 无结果)。删得干净。
"包括 secret settings" 这句最要命
这是本篇最该记住的一点。
secret settings 存在 keystore 里,不在 elasticsearch.yml 里。
这意味着:打开配置文件看,可能什么都找不到——干干净净,一个 tracing.apm 都没有。但节点还是起不来,因为该设置躺在 keystore 里。只查配置文件会得出"我没用这个设置"的错误结论。
keystore 是个容易漏掉的地方,原因有几个:
- 它不在版本控制里(配置文件通常在);
- 它由
elasticsearch-keystore命令管理,不看命令输出就不知道里面有什么; - 它是节点本地的——集群里每个节点都有自己的一份,可能各不相同。
第三点尤其麻烦:你可能修好了 A 节点,B 节点还是起不来。
怎么排查
第一步,查配置文件:
grep -rn "tracing.apm" /etc/elasticsearch/
第二步,查 keystore(关键,别漏):
# 列出 keystore 里所有的键
elasticsearch-keystore list
看输出里有没有 tracing.apm.* 开头的键。
第三步,删掉或改名。 按官方说明,改成对应的 telemetry.* / telemetry.tracing.*,或者直接删(如果不再需要)。
# 删除旧键
elasticsearch-keystore remove tracing.apm.secret_token
第四步,重启验证。
(说明:上面这几条命令的路径和参数名未实测,elasticsearch-keystore 的用法以你版本的文档为准。核心动作是"配置里找 + keystore 里找",两处都要查。)
keystore 为什么这么容易漏
上面说 keystore 容易漏,这里把原因讲透,因为它是本篇排查的关键。
一,它不在版本控制里。 配置文件的改动有 git 记录、有 review、有 CI 检查。keystore 的改动通常是一次性手工操作,做完就没痕迹了。时间一长没人记得里面有什么。
二,它是二进制的。 你不能直接 cat 看内容,必须走 elasticsearch-keystore list。多一道命令就多一道被跳过的可能——尤其当"看看配置"这个动作已经完成时,很容易以为查完了。
三,它是节点本地的。 配置文件可能由 Ansible / Puppet 统一分发,集群里所有节点一致;keystore 往往是各自生成的。所以存在"部分节点有问题"的情况——修好一个不等于修好了全部。
第四点最实际:配置文件里的设置删掉后,重启节点会报错;keystore 里的也可能报错,但错误信息未必像配置文件那样直接指出行号位置。 所以如果升级后节点起不来、而配置文件看着没问题,第一个该怀疑的就是 keystore。
把这四点写出来,是因为"配置分两处存"这个事实本身就容易制造盲区。凡是涉及敏感值(密码、token)的设置,都要记得它们可能在配置文件之外。
这条属于"升级阻塞项"
按改动的分类:
| 维度 | 判断 |
|---|---|
| 失效方式 | 节点拒绝启动 |
| 是否阻塞升级 | 是(起不来就没法升级) |
| 排查成本 | 中(配置好查,keystore 容易漏) |
| 修复成本 | 低(改名或删除) |
它和 data_frame_transforms 角色移除(Transform 角色)是同一类:必须在升级前处理,因为升级后节点直接起不来,没有"慢慢观察"的余地。
建议在升级前把每个节点的 keystore 都列一遍。命令就一条,但能避免升级当天面对起不来的节点。而且要注意逐节点做——keystore 是节点本地的,配置文件一致不代表 keystore 一致。
为什么删得这么彻底
顺着"节点拒绝启动"再想一层:为什么不温和一点,比如只警告?
理解(官方没解释):
设置被移除后,如果继续接受它,就只有两条路——要么忽略(静默失效),要么报错(明确失败)。ES 选了后者。
选后者的理由成立:留着一个不生效的设置,比直接拒绝更危险。前者你会以为自己配了 APM 追踪,实际上没生效——等到需要看追踪数据时才发现,已经晚了。
而"拒绝启动"听起来严厉,实际好处明显:
- 升级当天就能发现,不会拖到后面;
- 报错位置明确,改法唯一;
- 不会留下"配置写了但没生效"的隐患。
这和 profile 与文本格式(profile 与文本格式)是同一个取向:宁可明确失败,也不要静默不完整。那篇里说过同样的判断标准。
和别的"设置删除"放一起看
9.0 删了不少设置,前面写过几篇:
| 篇 | 删了什么 | 失效方式 |
|---|---|---|
| discovery-ec2 换 SDK v2 | ec2 的部分配置 | 静默失效(设置还注册着) |
| data_frame_transforms 角色移除 | Transform 角色 | Transform 起不来 |
| 本篇 | tracing.apm.* | 节点拒绝启动 |
三篇的失效方式一个比一个强硬。 其中最难处理的是 discovery-ec2 换 SDK v2——因为静默;本篇最"吵",但也最好处理——因为它把问题摆在你面前。
这个对比有实用价值:升级前排查时,优先处理那些会"吵"的(它们阻塞升级),但别忘了那些静默的(它们不会拦你,但会留下隐患)。两类都要查,只是优先级不同。
由此能得出一条排查顺序:
- 先查会阻塞启动的(本篇这类)——不处理就升不了;
- 再查会明确报错的(data_frame_transforms 角色移除 这类)——升级后能发现,但最好提前;
- 最后查静默失效的(discovery-ec2 换 SDK v2 这类)——它们不会拦你,只能靠主动扫。
这个顺序按"不处理会不会被发现"排列。越靠前的越容易被发现,所以先处理它们性价比低——真正该多花时间的是第三类,因为它不会自己暴露。
在 9.4.2 上跑一遍
先试一个普通设置确认接口正常,再试 tracing.apm.*:
图 4:本地 9.4.2 单节点实例上的实测输出。上:普通设置;下:tracing.apm.enabled
curl -s -X PUT "http://localhost:9200/_cluster/settings" \
-H 'Content-Type: application/json' \
-d '{"persistent":{"cluster.routing.allocation.enable":"all"}}'
curl -s -X PUT "http://localhost:9200/_cluster/settings" \
-H 'Content-Type: application/json' \
-d '{"persistent":{"tracing.apm.enabled":true}}' \
| jq -r '"HTTP \(.status): \(.error.root_cause[0].reason)"'
普通设置返回 {"acknowledged":true,...};tracing.apm.enabled 返回 HTTP 400: persistent setting [tracing.apm.enabled], not recognized。
同一句 not recognized 在 transient 和 persistent 上写法一致,所以先试一个已知存在的设置做对照很有必要——否则"接口通不通"和"这个设置还在不在"会混在一起,容易把 400 归错因。
结论是:这类被删的设置,动态接口上会被拦下来,不会静默接受;真正危险的是 yml 里那份,节点启动时才发作。升级前 grep 一遍配置文件里的 tracing.apm,命中就删掉。
写在最后
这条 breaking 的内容很简单:一批设置改名,旧的删除。
一,tracing.apm.* 删除,改用 telemetry.* / telemetry.tracing.*。 源码注释里有具体的对应关系(secret_token → telemetry.secret_token,recording 改由 telemetry.metrics.enabled / telemetry.tracing.enabled 控制)。
二,失效方式是节点拒绝启动,且包括 keystore 里的 secret settings。 所以配置文件和 keystore 都要查,而且每个节点都要查——keystore 是节点本地的,修好一个不等于修好全部。
三,属于升级阻塞项,必须在升级前处理。 好消息是报错明确、改法唯一,排查成本不高——难的点只在"别忘了查 keystore"这一处。
另外诚实标注两处:"改名的意图"是理解(依据源码注释,官方没解释设计动机);elasticsearch-keystore 的命令细节未实测。
参考
- changelog 9.0.0:Deprecated tracing.apm.* settings got removed(第 1430–1440 行)@ v9.4.2
APMAgentSettings.java:secret_token 的替代说明(第 220 行)@ v9.4.2APMAgentSettings.java:recording 改由 telemetry.* 控制(第 132 行)@ v9.4.2- PR 119968
本文对照 Elasticsearch
v9.4.2标签的 changelog 与源码核对,引文与代码逐字取自原文。另确认 9.4.2 的server/src/main/java/下已无tracing.apm残留。"改名背后的意图"是理解,官方未解释设计动机;elasticsearch-keystore的具体命令细节未实测;新旧设置的完整映射表未逐个整理,仅列出源码注释中出现的两项。图 4 的两次设置请求来自本地 9.4.2 单节点实例。
