OpenTelemetry Kubernetes attributes
processor(k8sattributes)已升到
v1.0.0。真正会改名的只有 7
类属性:标签与注解从复数变成单数,container.image.tag 变成
container.image.tags。k8s.pod.name、k8s.namespace.name、k8s.deployment.name
等核心资源属性保持不变。默认只抽取这些核心字段的 Collector 配置(例如
EDOT kube-stack 默认 Helm
values)基本不受影响;真正要提前改的,是自定义查询、告警、看板里对旧标签/注解属性名的引用。
本文依据 OpenTelemetry 官方公告(2026-09-16) 与 Elastic Observability Labs 迁移说明(2026-09-28) 整理。后者补充了 EDOT 9.6 默认切换与双写迁移细节。
v1.0.0 意味着什么
v1.0.0 表示该组件已满足 Collector「稳定」标准:文档、测试、基准、遥测稳定性,以及可作为 Go 库或发行版二进制分发时的 API 承诺。稳定输出依赖的是稳定的语义约定。K8s Semantic Conventions SIG 从 2025 年 11 月起集中推进;约定在 2026 年 3 月 进入 Release Candidate,并在 2026 年 6 月 随 Semantic Conventions v1.42.0 进入 stable。处理器随后走完毕业流程(含生产用户与发行方背书),对齐新的属性命名。
上游公告写明:这次升级会给既有用户带来一部分破坏性变更,因此配套了迁移说明。变更范围集中在标签、注解与镜像 tag 命名空间,并不是整套 K8s 资源属性推倒重来。
按 Elastic 文中的说法,v1.0.0 已合入 OpenTelemetry Collector Contrib
main,随 contrib v0.161.0 发布;EDOT
Collector 在 9.6 引入,并把相关 feature gate
默认翻成「只发 v1」。Elastic 工程师也参与了上游毕业相关工作,包括 feature gate
机制、K8s 基准与负载测试,以及最终 promotion PR。
7 处更名(旧名 → 新名)
两篇主源与处理器 README 的 Semantic Conventions Compatibility 一节给出的对应关系一致:
| v0 属性名 | v1 属性名 |
|---|---|
container.image.tag |
container.image.tags |
k8s.pod.labels.<key> |
k8s.pod.label.<key> |
k8s.pod.annotations.<key> |
k8s.pod.annotation.<key> |
k8s.node.labels.<key> |
k8s.node.label.<key> |
k8s.node.annotations.<key> |
k8s.node.annotation.<key> |
k8s.namespace.labels.<key> |
k8s.namespace.label.<key> |
k8s.namespace.annotations.<key> |
k8s.namespace.annotation.<key> |
规律很简单:标签/注解属性去掉末尾的
s(labels →
label,annotations →
annotation),镜像 tag
则从单数变成复数。<key>
是你实际抽取的标签或注解键名。例如抽取了 app 标签时,字段从
k8s.pod.labels.app 变为
k8s.pod.label.app。
哪些属性没改
下列核心属性在 v0 与 v1 下同名。依赖它们的查询、告警、看板在升级后仍可继续工作(类别划分取自 Elastic 文):
| 类别 | 属性 |
|---|---|
| Pod 身份 | k8s.pod.name、k8s.pod.uid、k8s.pod.ip、k8s.pod.start_time |
| 工作负载 | k8s.deployment.name、k8s.replicaset.name、k8s.statefulset.name、k8s.daemonset.name、k8s.job.name、k8s.cronjob.name |
| 集群位置 | k8s.namespace.name、k8s.node.name |
| 容器 / 服务 | container.id;service.name、service.version、service.instance.id |
EDOT kube-stack 默认的 k8s_attributes
抽取列表也正是这些核心字段,不包含 labels、annotations 或
container.image.tag。DaemonSet collector 额外会加
container.id,并用 filter.node_from_env_var
把元数据查找限制在本节点。因此「只用默认 Helm values」时,Elastic
侧内置的 kubernetes_otel 包(12 个看板、18 个告警模板、2 个
ML 模块、4 个 SLO 模板)经审计后无需改字段名。
Feature gate:何时开始只发 v1
处理器通过两个 feature gate 控制 v0 / v1 属性发射(整条 v1 发行线内仍标为 beta):
| Feature gate | EDOT 9.6 之前 | EDOT 9.6 起默认 | 开启后效果 |
|---|---|---|---|
processor.k8sattributes.EmitV1K8sConventions |
关闭 | 开启 | 发射 v1 属性名 |
processor.k8sattributes.DontEmitV0K8sConventions |
关闭 | 开启 | 停止发射 v0 属性名 |
升级到 EDOT 9.6 且未覆盖这些开关时,Collector 默认只写 v1 名。这才是自定义资产容易「静默断数据」的转折点。
通用 Collector(contrib / k8s distro)同样用这两个
gate;具体默认何时翻转为「只发
v1」,以你所用发行版的发行说明为准。Elastic 文中的时间线绑定的是 EDOT
9.6。可在 kube-stack Helm 的 feature-gates 里按
collector(cluster / daemon)分别覆盖。
上游实现还有一条约束:不能只开 DontEmitV0K8sConventions
却不开
EmitV1K8sConventions,否则启动会失败。双写正确写法是关闭
DontEmitV0、开启 EmitV1。
静默失败风险:过滤、查询、看板
危险之处在于:字段名对不上时,后端通常不会报错,只会查不到新写入的数据。Elastic
文明确写道:自定义资产在 EDOT 9.6 之后若仍查
k8s.pod.labels.* 或
container.image.tag,会安静地不再返回新数据,没有报错,也没有空状态提示。
另一层后果来自存储侧:Elasticsearch 不会把已索引字段改名。旧文档继续带 v0 名,新文档写 v1 名。只查其中一个名字,时间线会被拦腰截断。
在升级前,建议在自己的看板、告警规则、transform、ingest pipeline、保存的搜索里扫一遍这些旧前缀:
k8s.pod.labels.
k8s.pod.annotations.
k8s.node.labels.
k8s.node.annotations.
k8s.namespace.labels.
k8s.namespace.annotations.
container.image.tag
若服务通过 Collector 注入了业务标签(例如
app、version)或注解做路由过滤,对应的字段名也会落在上述命名空间里。Spring
Boot / Micrometer / OTel Java agent 本身通常只产出应用侧属性;K8s
标签与注解是 Collector 侧 k8sattributes
抽取后才写入资源属性的。
过渡期双写与迁移步骤
若已有自定义资产引用了旧名,Elastic 建议在升级到 EDOT 9.6
时先开双写:同时发射 v0 与 v1,给迁移留窗口。Helm
feature-gates 示例(daemon /
cluster 可分别设置):
# 双写:发 v1,同时保留 v0(迁移过渡)
collectors:
daemon:
args:
feature-gates: -processor.k8sattributes.DontEmitV0K8sConventions,processor.k8sattributes.EmitV1K8sConventions
cluster:
args:
feature-gates: -processor.k8sattributes.DontEmitV0K8sConventions,processor.k8sattributes.EmitV1K8sConventions
若短期仍需只发 v0(规划迁移时):
collectors:
daemon:
args:
feature-gates: -processor.k8sattributes.EmitV1K8sConventions,-processor.k8sattributes.DontEmitV0K8sConventions
可按这个顺序落地:
- 升级前先盘点自定义资产是否引用上表旧名。
- 升级时开启双写(或先短期锁在 v0),保证内置资产与旧自定义查询都能读到数据。
- 把看板、告警、查询里的字段改成 v1 名。
- 确认无遗漏后,去掉
-processor.k8sattributes.DontEmitV0K8sConventions覆盖,回到只发 v1,降低索引冗余。
Elastic 在 kind 与 GKE 上用 feature gate 强制 v1-only
输出做过端到端验证,并对 kubernetes_otel
包做了字段审计。双写是过渡手段,不宜长期保留。完整迁移说明见处理器
README 的 Semantic Conventions Compatibility
一节,以及上文两篇主源。
升级前最小核对清单
- 确认发行版:contrib v0.161.0+,或 EDOT 9.6+(及你所用 distro 的对应版本)。
- 若配置只抽取核心 metadata、未开
labels/annotations/
container.image.tag,优先做一次冒烟即可。 - 若抽取了标签/注解或镜像 tag,按上表改字段,并决定是否双写。
- 核对后端已索引文档:历史 v0 与新写入 v1 会并存,查询条件要覆盖迁移窗口。
主源链接:OpenTelemetry:Kubernetes attributes processor reaches v1.0.0、Elastic:Kubernetes attributes processor v1 for EDOT Collector。
一起交流
分享你的思考,让讨论更进一步。