自定义Deployment粒度的链路追踪标签
本文将介绍使用阿里云服务网格(ASM)和阿里云链路追踪(Tracing),以业务无侵入的方式,实现Deployment粒度的自定义链路追踪标签。示例代码为asm-best-practises。
概述
链路追踪是服务网格可观测性的重要组成部分,通过链路追踪我们可以很容易观察到服务节点之间的调用情况。在此基础上,我们可以通过在EnvoyFilter中配置自定义标签,实现以业务无侵入的方式为每条trace打标,进而实现细粒度、精细化的查询、统计和分析。
如下图所示,ACK集群内有3个串行调用关系的服务(hello1/hello2/hello3),每个服务存在3组Deployment(分别v1英语/v2法语/v3西语版本)。当我们以Deployment粒度打标时,假设某次请求的链路是hello1服务的v1版
到hello2服务的v2版
到hello3服务的v3版
,那么我们将在阿里云链路追踪服务中看到hello1-v1
-hello2-v2
- hello3-v3
这样自定义标签。
链路追踪数据中有了这样细粒度的标签,我们就可以具备了流量染色、按发布版本进行分组统计等能力。
原理
在envoy的配置tracing.custom_tags
中,我们可以为链路追踪定义自定义标签。示意如下:
"tracing": {
"custom_tags": [
{
"tag": "version-tag",
"request_header": {
"name": "VERSION",
"default_value": "hello2-v1"
}
}
]
}
为了动态添加自定义标签,Envoy定义了相应协议type.tracing.v2.CustomTag。为此,ServiceMesh的控制平面需要定义一个EnvoyFilter来声明在什么地方哪个阶段添加自定义标签。我们可以通过定义EnvoyFilter的workloadSelector
字段,将具体范围缩小的某个具体的POD;通过定义applyTo
字段为NETWORK_FILTER
、匹配条件match.listener.filterChainfilter
定义为名称是envoy.http_connection_manager
的过滤器。示意如下:
apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
name: hello1-deploy-v1-tag
namespace: http-hello
spec:
workloadSelector:
labels:
app: hello1-deploy-v1
configPatches:
- applyTo: NETWORK_FILTER
match:
listener:
filterChain:
filter:
name: envoy.http_connection_manager
patch:
operation: MERGE
value:
name: envoy.http_connection_manager
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
tracing:
custom_tags:
- tag: version-tag
environment:
name: VERSION
default_value: v1
request_header:
name: VERSION
default_value: hello1-v1
实战
1 部署容器
执行如下命令,部署上图所示的hello1-3服务和POD:
alias k="kubectl --kubeconfig $USER_CONFIG"
# https://github.com/feuyeux/asm-best-practises/blob/master/tracing_tag/kube
k apply -f kube/
2 部署路由规则和自定义标签EnvoyFilter
执行如下命令,部署上图所示的路由规则和9个POD维度的自定义标签EnvoyFilter:
alias m="kubectl --kubeconfig $MESH_CONFIG"
# https://github.com/feuyeux/asm-best-practises/tree/master/tracing_tag/mesh
m apply -f mesh/
3 配置网格实例
登录ASM管控台,进入服务网格实例,在可观测配置中启用链路追踪。
4 请求入口网关
通过执行如下命令请求入口网关,从而生成trace数据:
ingressGatewayIp=$(k -n istio-system get service istio-ingressgateway -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
echo "access http://$ingressGatewayIp:8001/hello/eric"
for i in {10..60}; do
curl -s "http://$ingressGatewayIp:8001/hello/$i"
echo
done
响应信息如下所示:
access http://8.136.115.99:8001/hello:
Hello 10@hello1:10.20.0.88<Bonjour 10@hello2:10.20.0.87<Hola 10@hello3:10.20.0.151
...
Hello 60@hello1:10.20.0.88<Bonjour 60@hello2:10.20.0.87<Hola 60@hello3:10.20.0.151
5 从链路数据中自定义标签
登录Tracing,选择服务网格所在的地域,然后选择服务网格实例ID对应的标签:
左侧菜单点击调用链分析
然后在调用链列表中选择一条链路追踪数据,可以看到如下图所示的自定义标签数据出现在相应的trace-span行中: