跳到主要内容

接入链路追踪

链路追踪展示一次请求在多个微服务间的调用路径与耗时。数据由业务侧通过 OTLP 上报给运维平台的 Alloy,再转发进 Tempo 存储。

仅 HAP/HDP 集群部署可用

链路追踪面向 Kubernetes 集群部署。单机(Docker Compose)部署暂不支持。

推荐方式:Istio sidecar 自动上报

业务在 Istio 网格内时,sidecar 自动产生并上报 span,业务代码零改动。HAP/HDP 集群模式通常已在网格内。

注入了 sidecar ≠ 会上报链路

已安装 Istio 并开启 istio-injection=enabled 后,默认仍不会产生 span—— 还需要为 Istio 配置上报地址与采样率。未配置时通常不会报错,但链路追踪页无数据。

自查:

kubectl -n istio-system get cm istio \\
-o jsonpath='{.data.mesh}' | grep -A3 extensionProviders

无输出表示尚未配置,请按以下步骤补充。

第 1 步:给 Istio 加一个指向运维平台 Alloy 的上报出口

kubectl -n istio-system edit configmap istio

打开后是这样一个结构——mesh 的值本身是一段 YAML 文本,要加的 extensionProviders 放在这段文本的顶层,和 defaultConfigrootNamespace 平级:

apiVersion: v1
kind: ConfigMap
metadata:
name: istio
namespace: istio-system
data:
mesh: |- # ← 注意这里是个字符串块
defaultConfig:
discoveryAddress: istiod.istio-system.svc:15012
defaultProviders:
metrics:
- prometheus
enablePrometheusMerge: true
rootNamespace: istio-system
trustDomain: cluster.local
extensionProviders: # ← 加这一整段
- name: mdis-otel
opentelemetry:
service: ops-alloy.<运维平台命名空间>.svc.cluster.local
port: 4317
meshNetworks: |-
networks: {}
常见配置错误

① 不要缩进到 defaultConfig 里面。 extensionProviders 是 mesh 的顶层字段, 放错层级 istiod 会静默忽略——配置存在但不会产生 span。

service 必须写完整 FQDN,且命名空间换成运维平台实际所在的。 默认清单是 hap-ops, 实际部署时可能使用其他命名空间。命名空间错误时 sidecar 无法解析服务,通常也不会报错。 可通过以下命令确认:

kubectl get svc -A | grep ops-alloy

③ 端口是 4317(OTLP gRPC),不是 4318。 opentelemetry provider 走 gRPC。

改完重启 istiod 让它重新加载:

kubectl -n istio-system rollout restart deployment/istiod
kubectl -n istio-system rollout status deployment/istiod

回读确认真的进去了(应打印出你刚加的那段):

kubectl -n istio-system get cm istio -o jsonpath='{.data.mesh}' | grep -A4 extensionProviders

第 2 步:开启采样

上一步仅配置 Istio 的上报地址,还需配置采样率——未创建 Telemetry 时采样率为 0, 不会产生 span。

kubectl apply -f - <<'EOF'
apiVersion: telemetry.istio.io/v1
kind: Telemetry
metadata:
name: mdis-tracing
namespace: istio-system # 放在 istio 根命名空间 = 全网格生效
spec:
tracing:
- providers:
- name: mdis-otel # 必须与第 1 步的 name 完全一致
randomSamplingPercentage: 100
EOF

确认 Telemetry 资源已创建:

kubectl get telemetry -A
采样率先给 100,验证完再降

randomSamplingPercentage 验证阶段建议设为 100(否则 10% 采样下少量请求可能无法命中采样, 容易误判为配置未生效);确认链路连通后改回 1~10——采样率越高,Tempo 的存储和写入压力越大。 修改该值不需要重启 istiod,但需重启业务 Pod 才会生效。

Telemetry API 版本

上例使用 telemetry.istio.io/v1(Istio 1.22+,1.29 实测可用)。更早版本的 Istio 使用 v1alpha1,其余字段相同。可通过以下命令确认当前版本:

kubectl api-resources | grep telemetry

第 3 步:重启业务 Pod

sidecar 要重新拿配置才会开始上报,未执行该步骤时前置配置不会生效

kubectl -n <业务命名空间> rollout restart deployment/<名字>

顺带确认业务命名空间确实开了注入:

kubectl get ns -L istio-injection

对应行显示 enabled 才会有 sidecar。

第 4 步:确认 span 已推送到运维平台

该步骤用于确认运维平台 Alloy 是否已接收到 span:

kubectl -n <运维平台命名空间> exec deploy/ops-alloy -- \
curl -s localhost:12345/metrics | grep otelcol_receiver_accepted_spans_total

先触发几次跨服务调用,再执行一次检查。若指标增长,表示上报链路已连通:

otelcol_receiver_accepted_spans_total{...,transport="grpc"} 83

若指标持续为 0 或查询不到该指标,按下表排查:

现象通常是
指标为 0业务 Pod 未重启(第 3 步),或采样率过低、请求未命中采样
指标不存在Alloy 未开启 OTLP 接收,检查 ops-alloy Service 是否暴露 4317
指标增长但页面空Alloy→Tempo 链路异常,检查 ENV_TEMPO_GRPC_URL 与 ops-tempo 容器日志

上报端点

Alloy 接收 OTLP 的端点:

协议端点
OTLP gRPC4317
OTLP HTTP4318

应用若自带 OpenTelemetry SDK,将 exporter 指向上述端点即可:集群内使用 Service DNS,如 http://ops-alloy.<运维平台命名空间>.svc.cluster.local:4317(命名空间换成运维平台实际所在的, kubectl get svc -A | grep ops-alloy 可查)。

上报方在其他集群时无法访问

ops-alloy 是 ClusterIP,只在运维平台所在集群内可解析。跨集群上报需要先暴露 4317 (NodePort 或 Ingress)。链路数据量较大,暴露方式与限流策略需结合实际网络环境规划。

Alloy 转发到 Tempo 的地址由 ENV_TEMPO_GRPC_URL 控制(默认 http://ops-tempo:4317),标准部署无需改动。

数据保留与存储

链路数据保留时长由 ENV_TEMPO_RETENTION 控制,默认 30 天,详见 环境变量

要让链路数据长期留存、不受节点磁盘限制,在部署时为 Tempo 准备对象存储桶(建议名 mdis-tempo),见 对象存储

验证

接入后触发几次跨服务调用,到 链路追踪 页查看:顶部三张概览图(请求量/错误率/P95 延迟)出现数据、底部 Recent Traces 列表出现 Trace 明细,即接入成功。