OTel
OpenTelemetry(OTel)是一个开源项目,旨在为在分布式系统(如微服务架构)中收集、处理和导出遥测数据提供一个供所有供应商使用的中立标准。它帮助开发者更轻松地分析软件的性能和行为,从而促进应用程序问题的诊断和解决。
术语
术语 | 说明 |
---|
Trace | 提交到 OTel 服务器的数据,是一组相关事件或操作的集合,用于跟踪分布式系统中请求的流动;每个 Trace 由多个 Span 组成。 |
Span | Trace 中的一个独立操作或事件,包括开始时间、持续时间和其他相关信息。 |
OTel Server | 能够接收和存储 Trace 数据的 OTel 服务器,如 Jaeger、Prometheus 等。 |
Jaeger | 一种开源分布式追踪系统,用于监控和排查微服务架构,支持与 OpenTelemetry 的集成。 |
Attributes | 附加到 Trace 或 Span 的键值对,以提供额外的上下文信息。包括资源属性和 Span 属性;有关更多信息,请参见 Attributes。 |
Sampler | 一种策略组件,用于决定是否对 Trace 进行采样和报告。可以配置不同的采样策略,如全量采样、比例采样等。 |
ALB(另一个负载均衡器) | 分配网络请求到集群中可用节点的软件或硬件设备;平台使用的负载均衡器(ALB)是一个第七层软件负载均衡器,能够配置监控流量并使用 OTel。ALB 支持将 Traces 提交到指定的收集器,并允许配置不同的采样策略;它还支持配置是否在 Ingress 层提交 Traces。 |
FT(前端) | ALB 的端口配置,指定端口级别的配置。 |
Rule | 在端口(FT)上的路由规则,用于匹配特定路由。 |
HotROD(按需乘车) | Jaeger 提供的示例应用程序,用于演示分布式追踪的使用;有关更多详细信息,请参考 Hot R.O.D. - Rides on Demand。 |
hotrod-with-proxy | 通过环境变量指定 HotROD 内部微服务的地址;有关更多详细信息,请参考 hotrod-with-proxy。 |
先决条件
步骤
更新 ALB 配置
-
在集群的主节点上,使用 CLI 工具执行以下命令以编辑 ALB 配置。
kubectl edit alb2 -n cpaas-system <otel-alb> # 将 <otel-alb> 替换为实际的 ALB 名称
-
在 spec.config
部分下添加以下字段。
otel:
enable: true
exporter:
collector:
address: "<jaeger-server>" # 将 <jaeger-server> 替换为实际的 OTel 数据报告服务器地址
request_timeout: 1000
完成后的示例配置:
spec:
address: 192.168.1.1
config:
otel:
enable: true
exporter:
collector:
address: "http://jaeger.default.svc.cluster.local:4318"
request_timeout: 1000
antiAffinityKey: system
defaultSSLCert: cpaas-system/cpaas-system
defaultSSLStrategy: Both
gateway:
...
type: nginx
-
执行以下命令以保存更新。更新后,ALB 将默认启用 OpenTelemetry,所有请求 Trace 信息将被报告到 Jaeger 服务器。
相关操作
在 Ingress 中配置 OTel
-
启用或禁用 Ingress 上的 OTel
通过配置是否在 Ingress 上启用 OTel,可以更好地监控和调试应用程序的请求流动,通过追踪请求在不同服务之间的传播来识别性能瓶颈或错误。
步骤
在 Ingress 的 metadata.annotations 字段下添加以下配置:
nginx.ingress.kubernetes.io/enable-opentelemetry: "true"
参数说明:
- nginx.ingress.kubernetes.io/enable-opentelemetry:当设置为
true
时,表示 Ingress 控制器在处理请求时启用 OpenTelemetry 功能,这意味着请求 Trace 信息将被收集并报告。当设置为 false
或移除此注释时,表示请求 Trace 信息将不被收集或报告。
-
启用或禁用 Ingress 上的 OTel Trust
OTel Trust 决定 Ingress 是否信任并使用来自传入请求的 Trace 信息(例如 trace ID)。
步骤
在 Ingress 的 metadata.annotations 字段下添加以下配置:
nginx.ingress.kubernetes.io/opentelemetry-trust-incoming-span: "true"
参数说明:
- nginx.ingress.kubernetes.io/opentelemetry-trust-incoming-span:当设置为
true
时,Ingress 将继续使用已经存在的 Trace 信息,帮助保持跨服务追踪的一致性,允许在分布式追踪系统中完整地追踪和分析整个请求链。当设置为 false
时,将为请求生成新的追踪信息,这可能导致请求在进入 Ingress 后被视为新的追踪链的一部分,从而中断跨服务的追踪连续性。
-
在 Ingress 上添加不同的 OTel 配置
此配置允许您自定义 OTel 的行为和数据导出方法,以便对不同的 Ingress 资源进行细粒度的追踪策略或目标控制。
步骤
在 Ingress 的 metadata.annotations 字段下添加以下配置:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
alb.ingress.cpaas.io/otel: >
{
"enable": true,
"exporter": {
"collector": {
"address": "<jaeger-server>", # 将 <jaeger-server> 替换为实际的 OTel 数据报告服务器地址,例如 "address": "http://128.0.0.1:4318"
"request_timeout": 1000
}
}
}
参数说明:
- exporter:指定收集的 Trace 数据如何发送到 OTel 收集器(OTel 数据报告服务器)。
- address:指定 OTel 收集器的地址。
- request_timeout:指定请求超时时间。
在应用程序中使用 OTel
以下配置展示了完整的 OTel 配置结构,可用于定义如何在应用程序中启用和使用 OTel 功能。
在集群主节点上,使用 CLI 工具执行以下命令以获取完整的 OTel 配置结构。
kubectl get crd alaudaloadbalancer2.crd.alauda.io -o json|jq ".spec.versions[2].schema.openAPIV3Schema.properties.spec.properties.config.properties.otel"
输出结果:
{
"otel": {
"enable": true
}
"exporter": {
"collector": {
"address": ""
},
},
"flags": {
"hide_upstream_attrs": false
"notrust_incoming_span": false
"report_http_request_header": false
"report_http_response_header": false
},
"sampler": {
"name": "",
"options": {
"fraction": ""
"parent_name": ""
},
},
}
参数说明:
参数 | 描述 |
---|
otel.enable | 是否启用 OTel 功能。 |
exporter.collector.address | OTel 数据报告服务器的地址,支持 http/https 协议和域名。 |
flags.hide_upstream_attrs | 是否报告关于上游规则的信息。 |
flag.notrust_incoming_span | 是否信任并使用来自传入请求的 OTel Trace 信息(例如 trace ID)。 |
flags.report_http_request_header | 是否报告请求头。 |
flags.report_http_response_header | 是否报告响应头。 |
sampler.name | 采样策略名称;有关详细信息,请参见 Sampling Strategies。 |
sampler.options.fraction | 采样率。 |
sampler.options.parent_name | 父级基于采样策略的父策略。 |
继承
默认情况下,如果 ALB 配置了某些 OTel 参数且 FT 未配置,则 FT 将从 ALB 继承参数作为其配置;即 FT 继承 ALB 的配置,Rules 可以从 ALB 和 FT 两者继承配置。
-
ALB:ALB 上的配置通常是全局的和默认的。在此可以配置例如 Collector 地址等全局参数,这些参数将被下级 FT 和 Rules 继承。
-
FT:FT 可以从 ALB 继承配置,这意味着未在 FT 中配置的某些 OTel 参数将使用来自 ALB 的配置。然而,FT 也可以进一步细化;例如,您可以选择在 FT 上选择性地启用或禁用 OTel,而不影响其他 FT 或 ALB 的全局设置。
-
Rule:Rule 可以从 ALB 和 FT 两者继承配置。然而,Rule 也可以进一步细化;例如,特定的 Rule 可以选择不信任传入的 OTel Trace 信息或调整采样策略。
步骤
通过配置 ALB、FT 和 Rule 的 YAML 文件中的 spec.config.otel
字段,您可以添加与 OTel 相关的配置。
附加说明
采样策略
参数 | 说明 |
---|
always on | 始终报告所有追踪数据。 |
always off | 从不报告追踪数据。 |
traceid-ratio | 根据 traceid 决定是否报告。traceparent 的格式为 xx-traceid-xx-flag ,其中 traceid 的前 16 个字符代表一个 32 位的十六进制整数。如果此整数小于 fraction 乘以 4294967295(即 (2^32-1)),则将被报告。 |
parent-base | 根据请求中 traceparent 的标志部分决定是否报告。当标志为 01 时,将被报告;例如:curl -v "http://$ALB_IP/" -H 'traceparent: 00-xx-xx-01' ;当标志为 02 时,将不会被报告;例如:curl -v "http://$ALB_IP/" -H 'traceparent: 00-xx-xx-02' 。 |
属性
-
资源属性
默认情况下报告这些属性。
参数 | 说明 |
---|
hostname | ALB Pod 的主机名 |
service.name | ALB 的名称 |
service.namespace | ALB 所在的命名空间 |
service.type | 默认是 ALB |
service.instance.id | ALB Pod 的名称 |
-
Span 属性
-
默认情况下报告的属性:
参数 | 说明 |
---|
http.status_code | 状态码 |
http.request.resend_count | 重试计数 |
alb.rule.rule_name | 此请求匹配的规则名称 |
alb.rule.source_type | 此请求匹配的规则类型,目前仅 Ingress |
alb.rule.source_name | Ingress 的名称 |
alb.rule.source_ns | Ingress 所在的命名空间 |
-
默认情况下报告但可以通过修改 flag.hide_upstream_attrs 字段排除的属性:
参数 | 说明 |
---|
alb.upstream.svc_name | 转发流量的服务(内部路由)的名称 |
alb.upstream.svc_ns | 被转发的服务(内部路由)所在的命名空间 |
alb.upstream.peer | 被转发到的 Pod 的 IP 地址和端口 |
-
默认情况下未报告但可以通过修改 flag.report_http_request_header 字段来报告的属性:
参数 | 说明 |
---|
**http.request.header.<header>** | 请求头 |
-
默认情况下未报告但可以通过修改 flag.report_http_response_header 字段来报告的属性:
参数 | 说明 |
---|
**http.response.header.<header>** | 响应头 |
配置示例
以下 YAML 配置部署一个 ALB 并使用 Jaeger 作为 OTel 服务器,并以 Hotrod-proxy 作为演示后端。通过配置 Ingress 规则,当客户端请求 ALB 时,流量将转发到 HotROD。此外,HotROD 内部微服务之间的通信也通过 ALB 路由。
-
将以下 YAML 保存为名为 all.yaml 的文件。
apiVersion: apps/v1
kind: Deployment
metadata:
name: hotrod
spec:
replicas: 1
selector:
matchLabels:
service.cpaas.io/name: hotrod
service_name: hotrod
template:
metadata:
labels:
service.cpaas.io/name: hotrod
service_name: hotrod
spec:
containers:
- name: hotrod
env:
- name: PROXY_PORT
value: "80"
- name: PROXY_ADDR
value: "otel-alb.default.svc.cluster.local:"
- name: OTEL_EXPORTER_OTLP_ENDPOINT
value: "http://jaeger.default.svc.cluster.local:4318"
image: theseedoaa/hotrod-with-proxy:latest
imagePullPolicy: IfNotPresent
command: ["/bin/hotrod","all","-v"]
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: hotrod-frontend
spec:
ingressClassName: otel-alb
rules:
- http:
paths:
- backend:
service:
name: hotrod
port:
number: 8080
path: /dispatch
pathType: ImplementationSpecific
- backend:
service:
name: hotrod
port:
number: 8080
path: /frontend
pathType: ImplementationSpecific
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: hotrod-customer
spec:
ingressClassName: otel-alb
rules:
- http:
paths:
- backend:
service:
name: hotrod
port:
number: 8081
path: /customer
pathType: ImplementationSpecific
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: hotrod-route
spec:
ingressClassName: otel-alb
rules:
- http:
paths:
- backend:
service:
name: hotrod
port:
number: 8083
path: /route
pathType: ImplementationSpecific
---
apiVersion: v1
kind: Service
metadata:
name: hotrod
spec:
internalTrafficPolicy: Cluster
ipFamilies:
- IPv4
ipFamilyPolicy: SingleStack
ports:
- name: frontend
port: 8080
protocol: TCP
targetPort: 8080
- name: customer
port: 8081
protocol: TCP
targetPort: 8081
- name: router
port: 8083
protocol: TCP
targetPort: 8083
selector:
service_name: hotrod
sessionAffinity: None
type: ClusterIP
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: jaeger
spec:
replicas: 1
selector:
matchLabels:
service.cpaas.io/name: jaeger
service_name: jaeger
template:
metadata:
labels:
service.cpaas.io/name: jaeger
service_name: jaeger
spec:
containers:
- name: jaeger
env:
- name: LOG_LEVEL
value: debug
image: jaegertracing/all-in-one:1.58.1
imagePullPolicy: IfNotPresent
hostNetwork: true
tolerations:
- operator: Exists
---
apiVersion: v1
kind: Service
metadata:
name: jaeger
spec:
internalTrafficPolicy: Cluster
ipFamilies:
- IPv4
ipFamilyPolicy: SingleStack
ports:
- name: http
port: 4318
protocol: TCP
targetPort: 4318
selector:
service_name: jaeger
sessionAffinity: None
type: ClusterIP
---
apiVersion: crd.alauda.io/v2
kind: ALB2
metadata:
name: otel-alb
spec:
config:
loadbalancerName: otel-alb
otel:
enable: true
exporter:
collector:
address: "http://jaeger.default.svc.cluster.local:4318"
request_timeout: 1000
projects:
- ALL_ALL
replicas: 1
resources:
alb:
limits:
cpu: 200m
memory: 2Gi
requests:
cpu: 50m
memory: 128Mi
limits:
cpu: "1"
memory: 1Gi
requests:
cpu: 50m
memory: 128Mi
type: nginx
-
在 CLI 工具中执行以下命令以部署 Jaeger、ALB、HotROD 及所有必要的 CR 进行测试。
-
执行以下命令以获取 Jaeger 的访问地址。
export JAEGER_IP=$(kubectl get po -A -o wide |grep jaeger | awk '{print $7}');echo "http://$JAEGER_IP:16686"
-
执行以下命令以获取 otel-alb 的访问地址。
export ALB_IP=$(kubectl get po -A -o wide|grep otel-alb | awk '{print $7}');echo $ALB_IP
-
执行以下命令以通过 ALB 向 HotROD 发送请求。此时,ALB 将报告 Trace 到 Jaeger。
curl -v "http://<$ALB_IP>:80/dispatch?customer=567&nonse=" # 将命令中的 <$ALB_IP> 替换为之前步骤中获取的 otel-alb 的访问地址
-
打开在 步骤 3 中获得的 Jaeger 访问地址以查看结果。

