
Grafana Tempo IPv6 网络配置指南Ring 地址族、memberlist 监听与 Kubernetes 部署验证【免费下载链接】tempoGrafana Tempo is a high volume, minimal dependency distributed tracing backend.项目地址: https://gitcode.com/GitHub_Trending/tempo1/tempoGrafana Tempo 允许组件之间使用 IPv6Internet Protocol Version 6进行通信。本文以 docs/sources/tempo/configuration/network/ipv6.md 为骨架结合仓库源码与配置文件完整讲解 IPv6 场景下的协议配置、各 Ring 的地址族切换、Kubernetes Service 与 gossip 集群配置以及 distroless 镜像下如何验证监听端口。读完本文你将掌握在单栈 IPv6 或双栈环境中让 Tempo 各组件distributor、backend-worker、metrics-generator、live-store 等通过 IPv6 互相发现并通信的完整实战方案。前置条件与适用范围在动手配置之前需要明确两个硬性前提底层基础设施必须支持 IPv6 地址族。该配置既可用于单栈single-stackIPv6 环境也可用于同时存在 IPv6 与 IPv4 的双栈dual-stack环境。双栈环境下同一时刻只能配置一个地址族且所有组件必须统一配置为该地址族。如果部分组件监听 IPv6、部分监听 IPv4组件之间的 Ring 心跳、memberlist 八卦协议与 gRPC/HTTP 调用都会失联集群将无法收敛。换句话说IPv6 配置是全集群一致的决策要么全体走 IPv6要么全体走 IPv4不允许混用。协议层配置监听地址与 Ring 地址族完整配置示例下面这段配置让 gRPC 与 HTTP 服务器监听 IPv6并将各类 memberlist 组件切换为 IPv6 地址族以下 YAML 完整继承自原文档memberlist: bind_addr: - :: bind_port: 7946 # Required only when using the global ingestion rate strategy. distributor: ring: enable_inet6: true # Only needed if the backend-worker ring is enabled (kvstore.store is set). backend_worker: ring: enable_inet6: true metrics_generator: ring: enable_inet6: true live_store: ring: enable_inet6: true server: grpc_listen_address: ::0 grpc_listen_port: 9095 http_listen_address: ::0 http_listen_port: 3200关键配置项逐项解读memberlist.bind_addr: [::]memberlist 是 Tempo 组件间发现彼此的核心机制gossip 协议。bind_addr设为 IPv6 通配地址::后memberlist 将在所有 IPv6 接口上监听。bind_port: 7946是 memberlist 的通信端口与 cmd/tempo/app/config.go 中memberlist.bind-port的默认值一致该文件还设置了RetransmitMult2、GossipInterval1s、GossipNodes2等默认参数。server.grpc_listen_address/server.http_listen_address分别设为::0让 gRPC默认 9095 端口与 HTTP默认 3200 端口监听 IPv6 通配地址。注意 YAML 中::0需要加引号避免被解析为其他类型。各ring.enable_inet6: trueTempo 的多个模块distributor、backend-worker、metrics-generator、live-store各自维护一个用于心跳与负载均衡的 Ringenable_inet6控制 Ring 实例广播地址的地址族。从源码看这是各模块RingConfig中一个统一命名的字段distributor 的 modules/distributor/distributor_ring.go#L34 定义了EnableInet6 bool \yaml:enable_inet6backend-worker 的 modules/backendworker/backendworker_ring.go#L34 结构完全一致metrics-generator 与 live-store 则直接复用通用 pkg/ring/config.go#L27 中的ring.Config见 modules/generator/config.go#L49 的Ring ring.Config与 modules/livestore/config.go#L17 的Ring ring.Config因此同样支持enable_inet6。enable_inet6的底层作用该字段最终会传入 Ring 的实例地址解析逻辑。在 pkg/ring/config.go#L64-L72 的ToLifecyclerConfig中ring.GetInstanceAddr(cfg.InstanceAddr, cfg.InstanceInterfaceNames, log.Logger, cfg.EnableInet6)会根据EnableInet6在候选网络接口默认instance_interface_names: [eth0, en0]上挑选对应地址族的 IP作为该实例在 Ring 中广播的地址随后通过net.JoinHostPort拼接成地址:端口形式注册进 Ring。启用 IPv6 后Ring 中的实例地址即为 IPv6 地址组件间的心跳与流量分发也全部走 IPv6。两个按需启用的注意事项原文档明确强调distributor.ring.enable_inet6仅在使用全局摄取速率策略global ingestion rate strategy时才必需。因为该 Ring 的作用是统计健康 distributor 实例数量作为全局速率限制的分母不使用该策略时这个 Ring 可以保持默认。backend_worker.ring.enable_inet6仅在 backend-worker Ring 被启用即kvstore.store被显式设置时才需要。若未启用该 Ring则无需配置此项。live_store.partition_ring 的地址族继承原文档特别提示live_store.partition_ring不暴露enable_inet6字段它从顶层memberlist配置继承地址族。这一点在源码中得到印证live-store 的分区 Ring 配置结构 modules/livestore/partition_ring.go#L11-L38 的PartitionRingConfig只包含kvstore、min_partition_owners_count、min_partition_owners_duration、delete_inactive_partition_after等字段确实没有enable_inet6。同时该配置在注册标志时执行cfg.KVStore.Store memberlist默认用 memberlist 作为 KV 存储分区 Ring 的状态经由 memberlist 集群传播因此其地址族自然跟随顶层memberlist.bind_addr。配置时只需保证memberlist.bind_addr为 IPv6 即可无需也无法单独为 partition_ring 设置 IPv6。Kubernetes Service 配置让每个组件 Service 走 IPv6在 Kubernetes 中每个承载 Tempo 工作负载的 Service 都需要显式设置spec.ipFamilies与spec.ipFamilyPolicy否则 Service 默认使用集群的 IPv4 地址族Pod 即使监听 IPv6 也无法被正常发现。以backend-worker为例完整继承自原文档apiVersion: v1 kind: Service metadata: labels: name: backend-worker name: backend-worker namespace: tracing spec: clusterIP: fccb::31a7 clusterIPs: - fccb::31a7 internalTrafficPolicy: Cluster ipFamilies: - IPv6 ipFamilyPolicy: SingleStack ports: - name: backend-worker-http-metrics port: 3200 protocol: TCP targetPort: 3200 selector: app: backend-worker name: backend-worker sessionAffinity: None type: ClusterIP要点说明ipFamilies: [IPv6]明确该 Service 使用 IPv6 地址族ipFamilyPolicy: SingleStack声明为单栈。这里的clusterIP: fccb::31a7是示例 IPv6 地址实际部署时应由集群网络规划分配或留空让控制平面自动分配。除 backend-worker 外distributor、querier、metrics-generator、live-store、ingester 等所有组件的 Service 都应做同样的 IPv6 化处理包括server.grpc_listen_address: ::0对应的 gRPC 端口 Service。组件互发现IPv6 下的 gossip-ring headless Service除各组件自身的 Service 外Tempo 组件是通过一个独立的 headless无头gossip-ringService 来互相发现的该 Service 暴露 memberlist 端口。必须把 gossip-ring 也配置为 IPv6组件才能通过 IPv6 加入集群apiVersion: v1 kind: Service metadata: name: gossip-ring namespace: tracing spec: clusterIP: None ipFamilies: - IPv6 ipFamilyPolicy: SingleStack ports: - name: gossip-ring port: 7946 protocol: TCP targetPort: 7946 selector: tempo-gossip-member: trueheadless ServiceclusterIP: None不会分配 ClusterIP而是为每个匹配tempo-gossip-member: true标签的 Pod 生成 DNS AAAA 记录这正是 memberlist 完成成员发现的基础。随后每个 Tempo 组件通过引用该 headless Service 的 DNS 名称加入 memberlist 集群join_members使用 dskit 支持的dns前缀做 DNS 解析memberlist: join_members: - dnsgossip-ring.tracing.svc.cluster.local.:7946dns前缀表示对gossip-ring.tracing.svc.cluster.local做周期性的 DNS 解析同时解析 AAAA 记录并把解析出的全部成员作为 memberlist 的种子节点:7946为 memberlist 端口。由于 gossip-ring 是 IPv6 单栈 Service解析结果即为 IPv6 地址整个 gossip 集群在 IPv6 网络上收敛。验证监听器distroless 镜像下的排查方法为什么不能直接 exec 进 PodTempo 的容器镜像基于 distroless 静态镜像构建cmd/tempo/Dockerfile 使用gcr.io/distroless/static-debian12作为最终运行镜像不含 shell 与任何网络排查工具因此无法直接kubectl exec进 Tempo Pod 执行ss、netstat等命令检查监听状态。使用 ephemeral debug container 验证推荐做法是挂载一个**共享目标 Pod 网络命名空间network namespace**的临时调试容器ephemeral debug container使用包含ss工具的自定义调试镜像kubectl debug -n tracing -it pod-name \ --imageyour-debug-image \ --targetbackend-worker \ -- ss -ltn--targetbackend-worker指定共享哪个容器的网络命名空间--imageyour-debug-image换成你的调试镜像需自带ss例如基于iproute2的工具镜像-it提供交互式终端末尾-- ss -ltn直接执行监听套接字查询。预期输出配置成功后应当看到 memberlist、gRPC、HTTP 三个端口均为 IPv6 通配监听State Recv-Q Send-Q Local Address:Port Peer Address:Port LISTEN 0 4096 *:7946 *:* LISTEN 0 4096 *:9095 *:* LISTEN 0 4096 *:3200 *:*解读Local Address列中的*表示进程监听在该地址族的所有地址上ss对 IPv6 通配地址的显示形式对应 memberlist 端口 7946、gRPC 端口 9095、HTTP 端口 3200。若看到的是0.0.0.0或[::]以外的具体 IPv4 地址说明地址族配置未生效请回头核对各ring.enable_inet6、server.*_listen_address以及 Kubernetes Service 的ipFamilies是否一致。排错检查清单配置 IPv6 后若组件间无法通信建议按以下顺序排查配置一致性确认所有组件的memberlist.bind_addr、server监听地址、各ring.enable_inet6均为 IPv6双栈环境只允许一个地址族混用 IPv4/IPv6 会导致 Ring 与 gossip 失联。Service 地址族确认每个组件 Service 与gossip-ring无头 Service 的ipFamilies均为 IPv6、ipFamilyPolicy为SingleStack。DNS 解析确认join_members中dnsgossip-ring.namespace.svc.cluster.local.:7946能解析出 IPv6AAAA地址且 namespace 与实际部署一致。监听验证使用共享网络命名空间的 ephemeral debug container 执行ss -ltn确认 7946 / 9095 / 3200 三个端口都处于 IPv6 通配监听状态。Ring 状态可通过 Tempo 的 memberlist 状态页/memberlist端点实现见 cmd/tempo/app/memberlist_status.gohtml查看集群成员数与健康度确认各组件均以 IPv6 地址成功加入。延伸阅读官方配置文档docs/sources/tempo/configuration/network/ipv6.mdRing 配置结构enable_inet6定义与实例地址解析pkg/ring/config.go、modules/distributor/distributor_ring.go、modules/backendworker/backendworker_ring.golive-store Ring 与分区 Ring 配置 modules/livestore/config.go、modules/livestore/partition_ring.gomemberlist 默认参数与绑定端口 cmd/tempo/app/config.godistroless 运行镜像说明 cmd/tempo/Dockerfile【免费下载链接】tempoGrafana Tempo is a high volume, minimal dependency distributed tracing backend.项目地址: https://gitcode.com/GitHub_Trending/tempo1/tempo创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考