[TOC]html
envoy原生就支持分布式追踪系统的接入,如支持jaeger和zipkin,如envoy的Tracing官方文档中代表envoy支持以下trace特性:git
相关信息能够参考这里 或者 envoy官方文档Jaeger Tracing,另外,在源码中有对应的trace相关的源码。github
Istio的分布式追踪相关介绍里面相关说明能够知道,Istio的envoy代理拦截流量后会主动上报trace系统,经过proxy的参数zipkinAddress指定了trace系统的地址,这样就不会再通过mixer了,直接envoy和trace系统交互,大致流程:docker
若是incoming的请求没有trace相关的headers,则会再流量进入pods以前建立一个root spanjson
若是incoming的请求包含有trace相关的headers,Sidecar的proxy将会extract这些span的上下文信息,而后再在流量进入pods以前建立一个继承上一个span的新的span后端
因为Istio的proxy代理是envoy,而envoy又原生支持jaeger,那所以Istio天然而然就支持jaeger了,在官方文档Distributed Tracing中有相关较为详细的说明api
固然,默认是经过envoy这个proxy直接上报的,若是要通过mixer上报,也是可行的,能够进行相关配置,额外处理一下,具体能够参考idou老师教你学Istio 08: 调用链埋点是否真的“零修改”?bash
不过目前envoy支持的trace方案相对比较简单,采用策略没法应用于Jaeger的全部策略,而后也不支持不一样业务有不一样的采样策略,所以Istio进行配置,也是全局的。微信
~/goDev/Applications/src/Istio.io/Istio/pilot/pkg/networking/core/v1alpha3/listener.go中的源码以下:架构
if env.Mesh.EnableTracing {
tc := model.GetTraceConfig()
connectionManager.Tracing = &http_conn.HttpConnectionManager_Tracing{
OperationName: httpOpts.direction,
ClientSampling: &envoy_type.Percent{
Value: tc.ClientSampling,
},
RandomSampling: &envoy_type.Percent{
Value: tc.RandomSampling,
},
OverallSampling: &envoy_type.Percent{
Value: tc.OverallSampling,
},
}
connectionManager.GenerateRequestId = &google_protobuf.BoolValue{Value: true}
}
复制代码
目前官方自带的jaeger采用的是jaegertracing/all-in-one这个镜像,这个会包含三个组件 jaeger-agent、jaeger-collector、jaeger-query,其中jaeger-collector会将数据存储,而all-in-one这镜像目前仅仅是存储在内存里面的,也就是临时存储,若是删掉pod重启,jaeger的数据是没有了的。 jaegertracing/all-in-one镜像内存存储相关。
为此,咱们要考虑,如何将jaeger-collector的数据存储指定为本身的存储服务如ES集群,采用官方自带的确定不行了,只能是本身部署一套jaeger服务,或者让jaeger服务的agent的收集地址指向咱们本身的服务
doc.Istio.cn/en/help/faq… Istio.io/docs/refere…
这两篇文章有说设置trace_zipkin_url, trace_jaeger_url,能够达到目的,查看yaml配置发现mixer只有设置trace_zipkin_url:
containers:
- name: mixer
image: "docker.io/Istio/mixer:1.0.0"
imagePullPolicy: IfNotPresent
ports:
- containerPort: 9093
- containerPort: 42422
args:
- --address
- unix:///sock/mixer.socket
- --configStoreURL=k8s://
- --configDefaultNamespace=Istio-system
- --trace_zipkin_url=http://zipkin:9411/api/v1/spans
复制代码
这个只是针对Mixer组件而言的trace,若是是envoy自己的tarce,须要修改proxyv2的参数
Istio开源版本中,调用链对接jaeger是从envoy直接报上去的,没有经过mixer来作。
由于调用链的数据量会很大,可靠性以及规模确是须要重点考虑的,所以必需要使用本身的服务 ,若是要配置为本身的jaeger服务,须要用kubectl修改Istio这个configmap中的zipkinAddress,配置为本身的服务地址,另外就是jaeger收数据是兼容zipkin的。
kubectl get configmap Istio -n Istio-system -o yaml |grep zipkinAddress
有两处zipkinAddress地址,以下:
zipkin.Istio-system:9411
复制代码
对于华为云而言,调用链这里他们会对接到华为云的apm服务,在可靠性和性能上都会有保证。
根据K8S安装部署Jaeger官方文档部署基于k8s的Jaeger的生产环境下的容器,注意必定要采用文档中Production这个生成的部署方式。
注意建立Elasticserach的时候,须要等待特别久,并且必定要等到Elasticserach这个pod的状态为Running的时候才能建立Jaeger的其余组件,由于其余组件要依赖Elasticserach
而后修改jaeger-query这个Service的type为NodePort,而后经过 kubectl get service jaeger-query
,能够看到Port,而后利用host ip能够访问,如2.2集群独立部署的Jaeger Query UI
须要部署jaeger相对比较麻烦,有一些参数须要设置,这个须要必定的学习能力,须要对jaeger对外暴露的端口、协议有必定的理解;而后还须要对存储引擎如ES有必定的了解
另外,若是是经过二进制安装部署的话,相对较为简单,只须要注意启动参数便可
经过kubectl get configmap istio -n istio-system -o yaml |grep zipkinAddress
先直接修改zipkinAddress的地址,指定为jaeger-collector这个Service的地址,端口是9411,只有这个9411地址才兼容zipkin协议。由于envoy这个proxy会默认使用环境变量来设置zipkinAddress地址,默认地址是zipkin.istio-system:9411
。修改过configmap以后,若是后面经过helm upgrade更新,则如今经过这个方式来修改的数据会失效,所以要彻底修改,则必须经过修改过install/kubernetes/helm/istio//templates/configmap.yaml
,同时还要修改install/kubernetes/helm/istio//charts/mixer/templates
下面的zipkin相关的地址。
若是是istio.yaml这个模板文件部署,则还需:
修改istio.yaml文件中的 zipkinAddress: zipkin.Istio-system:9411
修改istio.yaml文件中的mixer相关的trace_zipkin_url地址
修改istio.yaml文件中的proxyv2相关的zipkinAddress这个args
其余说明:
修改全部zipkinAddress相关的地址为jaeger-collector这个Service的地址,这个若是都是K8S集群,能够直接配置为ClusterIP,可是实际中须要配置一个全局域名
jaeger-agent这个服务,若是Istio直接配置为外部jaeger地址的话,是不会通过jaeger-agent的,所以能够关闭
因为经过ES进行数据存储,所以如今杀掉jaeger相关的Pod,重启后数据依然存在
对接到外部jaeger服务的话,Istio自带的jaeger相关的就能够直接关闭了
Jaeger自己支持在client端调整和经过collector调整采样策略,可是在Istio中并无Jaeger的client,只是envoy里面支持了trace,直接修改envoy的trace相关源码不太友好。不过Istio中提供了一个全局的设置,经过设置pilot的参数能够用来控制采用策略。
Istio的采样流程大体是:在pilot的v1alpha3的流量管理接口中,在提供Listener的Http filters的时候会判断:是否使能了mesh的trace,若是使能,则建立trace并读取 采用配置,采样经过环境变量PILOT_TRACE_SAMPLING
来配置,其范围是0.0 - 100.0,默认为100,全采样。
修改的方式有两种:
helm安装时候的选项参数:pilot.traceSampling
经过kubectl -n Istio-system edit deploy Istio-pilot
修改PILOT_TRACE_SAMPLING
变量
当PILOT_TRACE_SAMPLING
的值是100的时候,表示全采样,每一次请求都会采样,能够验证获得,经过访问测试页面,记录发起的请求次数,而后查看Jaeger Trace UI,查看Services为productpage的Trace,发现发起请求的次数和Trace的次数保持一致。
当PILOT_TRACE_SAMPLING
的值是50的时候,表示采样1/2,每两次请求都会采样一次,修改完后,等待一小会儿,而后验证。验证结果表示如今并不是1:2,可是也不彻底是1/2的几率,具体还有待分析Jaeger的原理,可是至少证实了策略的修改是有效的
现有Mtrace系统,在原有Jaeger基础上作了一些调整,使用了protobuf协议,同时增长了kafka。所以要想对接MTrace系统,还须要对proxy(envoy)作一些调整,并非仅仅修改一些配置参数和地址等就能够解决的
虽然Istio可以拦截流量并自动发送Span信息,可是要把整个过程统一追踪并连接起来,还须要业务在代码中处理和追踪相关的HTTP Header,这样代理在发送 Span 信息的时候,才能正确的把同一个跟踪过程统一块儿来。具体详见
在Mtrace等系统或者原生的jaeger中,会有有个client的角色存在,这个client会建立并初始化一个trace,并处理好TraceID的事情,可是Istio后,服务中没有Mtrace 发client端的 SDK,所以才须要再业务代码中处理好http header,可是对于非HTTP如TCP须要自行扩展支持,这个暂时不考虑;对应gRPC的话,由于也是基于http,所以能够经过一些方式添加。
因此,对于trace这块,并不是彻底没有任何侵入,业务代码有一点点小的改动,就是须要额外处理下http 的指定的header并依次传递
百分比默认值为100,所有采样,能够修改成0-100;修改的方式有两种:
helm安装时候的选项参数:pilot.traceSampling
经过kubectl -n Istio-system edit deploy Istio-pilot
修改PILOT_TRACE_SAMPLING变量
这个设置是全局的,没有办法针对特定业务有特定的采样策略。若是须要对特定业务采样,就须要给collector配置静态的json策略文件,而后也须要client支持,具体能够参考Jaeger官方文档。
须要业务代码中处理好http header,可是对于非HTTP而言,怎么弄 ?
不经过envoy上报,经过mixer上报
支持不一样业务不一样的采用策略
idou老师教你学Istio 08: 调用链埋点是否真的“零修改”?
【"欢迎关注个人微信公众号:Linux 服务端系统研发,后面会大力经过微信公众号发送优质文章"】