第7章 可视化工具
分布式追踪
- 分布式追踪(
Distributed Tracing)主要用于记录整个请求链的信息。在微服务应用中,一个完整的业务往往需要调用多个服务才能完成,服务之间就产生了交互。当出现故障时,如何找到问题的根源非常重要。追踪系统可以地展示出请求的整个调用链以及每一步的耗时,方便查找问题所在 - 本节主要介绍如何使用
Jaeger在Istio中实现追踪
启动Jaeger
Jaeger是一个开源的分布式追踪系统,它可以在复杂的分布式系统中进行监控和故障排查。Jaeger的主要功能包括分布式请求监控、性能调优、故障分析和服务依赖分析等Jaeger主要由以下5个部分组成
Jaeger Client:为不同语言实现了符合OpenTracing标准的SDK。应用程序通过API写入数据,客户端把Trace信息按照应用程序指定的采样策略传递给Jaeger AgentAgent:它是一个网络守护进程,负责监听UDP端口上接收的Span数据,它会将数据批量发送给Collector。它被设计成一个基础组件,并部署到所有的宿主机上。Agent将Client Library和Collector解耦,为Client Library屏蔽了路由和发现Collector的细节Collector:接收Agent发送的数据,然后将数据写入后端存储。Collector被设计成无状态的组件,因此可以同时运行做生意数量的CollectorData Store:后端存储被设计成一个可插拔的组件,支持将数据写入Cassandra和ElaticsearchQuery:接收查询请求,然后从后端存储系统中检索Trace并通过UI进行展示。Query是无状态的,可以启动多个实例,把它们部署在Nginx这样的负载均衡器中以提高性能
- 开始练习之前,请确认在用
Helm安装Istio时使用了--set-tracing.enabled=true选项。如果没有在Istio-system命名空间中找到Jaeger的Pod,则可以使用下面的命令进行安装

- 确保部署了
Jaeger服务之后,用下面的命令转发端口来启用来Jaeger的访问
kubectl -n istio-system port-forward $(kubectl -n istio-system get pod -l app=jaeger -o jsonpath='{.items[0].metadata.name}') 16686:16686
- 注意,
app标签在分布式追踪的过程中会被用来加入上下文信息,Istio还会用app和version标签来给遥测指标数据加入上下文信息。因此,如果读者的Jaeger Pod没有这两个标签,将无法启动。还要注意是否注入了Sidecar,否则将无法捕获服务请求 - 打开浏览器访问
http://localhost:16686,查看Jaeger的仪表板页面

生成追踪数据
- 访问
Bookinfo应用数次,就会生成一些追踪数据。在Jaeger左侧版面的Service下拉列表中选择productpage,单击Find Traces按钮

- 单击右侧的
URL进入详细页,可以看到具体的服务调用情况,并且能够了解每个服务的耗时

追踪原理
- 在
OpenTracing的数据模型中,一个调用链(Trace)是通过Span来定义的,可以理解为一个调用过程就是由若干个Span组成的有向无环图。Span中包含了一些必要的追踪信息,比如操作名称、起始结束时间等。Istio代理能够自动发送Span信息,但还是需要应用程序自己传播并追踪要使用的HTTP请求头,这样在代理发送Span信息的时候,才能正确地把同一个跟踪过程统一起来 - 为了完成跟踪的传播过程,应用需要从请求源中从头中收集请求头信息,并传播给外发请求:在对下游服务进行调用的时候,应该在请求中包含获取的请求头信息,使这些头信息在调用链的各个服务中传递下去
Istio默认会捕获所有请求的追踪信息。在高并发、大流量的应用场景下,为提高 性能,我们不需要追踪全部的请求,只需要取得一定的采样数据就够了。可以在Pilot组件的环境变量PILOTTRACESAMPING中修改采样率以达到这样的目的
使用Prometheus查询指标
Prometheus简介
- 它是一套开源的监控和报警工具集,其核心是一个时间序列数据库。
Prometheus将所有信息都存储为时间序列数据,实时分析系统运行的状态、执行时间和调用次数等,以找到系统的热点,为性能优化提供依据 Prometheus具有 如下特性
- 多维数据:
Prometheus实现了一个高度的多维数据模型。时间序列数据由指标名称或者一个键值 对集合定义 - 强大的查询语言
PromQL:这种灵活的查询语言允许对收集的指标数据进行分片和切块,以输出特定的图表和警报 - 可视化:提供了多种可视化方案、内部的
UI工具以及终端模板语言,可与Grafana整合 - 高效的存储:可以把时间序列数据以自定义的格式存储在内存和磁盘上,支持分片和联合
- 维护简单:每个服务器都是独立的,只依赖于内地存储。使用
Go语言编写,生成的bin文件很容易部署 - 准确报警:报警依赖于灵活的
PromQL和多维数据,管理器负责处理通知 - 多种客户端以及和第三方系统的整合

Prometheus是Istio中遥测功能的重要实现部分,默认情况下Istio会安装Prometheus,可以通过下面的命令验证
$ kubectl get svc -n istio-system prometheus
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
prometheus ClusterIP 10.98.18.185 <none> 9090/TCP 79m
- 如看到类似于上面的输出,说明
Prometheus是正常启动的。多次访问Bookinfo应用来生成一些指标数据
查询Istio指标
- 我们通过
port-forward转发端口的方式启动Prometheus的UI界面
kubectl -n istio-system port-forward $(kubectl -n istio-system get pod -l app=prometheus -o jsonpath='{.items[0].metadata.name}') 9090:9090
- 在浏览器中访问
http://localhost:9090

- 页面顶部的
Expression输入框是查询指标的位置,这里输入“apiserver_request_count”来查询请求数量,单击Execute按钮进行查询

Mixer内置Prometheus的适配器,并配置了服务器,它可以从Mixer抓取数据,并为指标提供存储和查询服务。Prometheus是Istio实现遥测能力的重要模块,它主要负责数据的收集和存储,并作为Grafana的输入端与其整合在一起,完成指标数据可视化的任务
使用Grafana监控指标数据
Grafana简介
Grafana是一个开源的监控和指标分析的可视化工具,它提供了一个非常强大的仪表板界面,来展示需要监控的指标数据。它具有如下的一些特性
- 丰富的可视化:
Grafana提供了几乎过剩的图表表示方式来描述数据,比如直方图、折线图等 - 报警:可以方便地定义一个可视化的报警临界值 ,并无缝地和
Slack、PageDuty等工具整合以发送通知 - 数据整合:
Grafana支持超过30种的数据库,用户可以不关心数据的来源,Grafana会把它们统一地展示到仪表板上 - 扩展性:提供了上百种仪表板和插件,数据的展示方式极其丰富
- 开源和多平台支持
安装Grafana
- 通过
Helm的upgrade命令更新安装配置项

- 验证
Grafana服务是否在集群中运行。注意:因为要使用Prometheus作为指标收集数据库,所以也要保证它的运行
$ kubectl get svc -n istio-system grafana
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
grafana ClusterIP 10.107.19.2 <none> 3000/TCP 39h
- 如果看到类似于上面的输出,说明
Grafana服务已经启动了。接下来,使用端口转发来打开Grafana的仪表板界面
kubectl -n istio-system port-forward $(kubectl -n istio-system get pod -l app=grafana -o jsonpath='{.items[0].metadata.name}') 3000:3000
- 在
Web浏览器中访问http://localhost:3000,可以看到如下图所示的界面

指标数据展示
- 内置的
Grafana已经和Istio进行了深度整合,并集成了若干个仪表板,可以查看网络、工作负载和服务等指标信息。Istio仪表板主要由3部分组成
- 网格全局示图:全局展示了流经网格的流量信息
- 服务示图:展示与每个服务的请求和响应相关的指标数据
- 负载示图:展示了服务的负载情况
- 还提供了展示
Istio自身资源使用情况的仪表板,可以用来查看Istio的运行状况 Istio Mesh Dashboard展示了Istio网格总览信息。从界面中可以看到流量、成功率和错误返回数等。因为Grafana是基于时间序列分析的,所以数据会实时刷新,可以在右上角设置刷新频率

- 因为
Bookinfo是安装在Kubernetes的default命名空间中的,所以在Namespace下拉框中选择default,在Workload下拉框选择想要查看的服务,这里是detail服务的v1版本,然后就可以看到具体的流量数和成功率等信息

- 除了与
Bookinfo应用相关的指标外,还可以查看Istio对系统资源的使用情况,比如内存、CPU、磁盘等信息

Grafana作为一个指标分析和可视化套件,与Istio整合后提供了多种与网络指标相关的仪表板外,还可以根据需要自定义仪表板,感兴趣的读者可以自己尝试一下
服务网格可视化工具——Kiali
Kiali简介
Kiali是Istio服务网格的可视化工具,它主要的功能是用可视化的界面来观察微服务系统以及服务之间的关系。Kiali的名字来源于希腊语里的一个词汇,意思是单筒望远镜,最早由Red Hat公司开源,现在已经获得了Istio的官方支持。Kiali提供了如下的一些功能
- 服务拓扑图:这是
Kiali最主要的功能 ,提供了一个总的服务视图,可以实时地显示命名空间下服务之间的调用和层级关系,以及负载情况 - 服务列表视图:展示了系统中所有的服务,以及它们的健康状况和出错率
- 工作负载视图:展示服务的负载情况
Istio配置视图:展示了所有的Istio配置对象
Kiali的架构比较简单,如下图所示,它分为前端和后端两部分。后端以容器的方式运行在应用平台,负责获取和处理数据,并发送给前端;前端是一个典型的Web应用,由React和TypeScript实现,负责展示后端发送过来的数据。对Kiali来说Istio是必须存在的系统,它类似于Kiali的宿主。虽然它们可以分开部署,但没有了Istio,Kiali是不能工作的

安装和启动Kiali
- 在安装前,需要先在
Kubernetes系统中添加一个Secret对象来作为Kiali的认证凭证。这里简单地使用admin和mysecret的Base64编码作为用户名和密码,然后在Istio命名空间里创建这个对象


- 使用
helm template进行安装,并添加--set kiali.enabled=true选项

- 验证一下
Kiali的服务是否已经启动

使用Kiali观测服务网格
Kiali启动后,在浏览器中多次访问Bookinfo应用,生成一些测试数据。接着,使用端口转发启动Kiali的页面UI
kubectl -n istio-system port-forward $(kubectl -n istio-system get pod -l app=kiali -o jsonpath='{.items[0].metadata.name}') 20001:20001
- 用浏览器打开
localhost:20001以访问Kiali界面。首先会弹出登录页面,输入刚才设置的用户名和密码,登录后会显示如下图所示的Overview页面,这里可以浏览服务网格的概况。Overview页面中会显示网格里所有 命名空间中的服务

- 把页面切换到
Graph标签,选择Namespace为default,就可以看到一个根据刚才的请求所绘制的服务拓扑图。Display用来选择显示项。从Graph Type下拉框可以选择不同的图形类别
app会忽略服务版本,只用一个节点来表示一个服务,并显示服务之间的调用关系Versioned app会把各个服务的版本作为节点展示出来,同一个服务会加上边框作为区别Service模式和app类似,可以展示服务节点,它们的区别是这种模式下只显示服务节点,没有和服务交互的节点Workload会将网格中的工作负载作为节点展示出来,如下图所示的Kiali服务拓扑图

Istio Config页面,这里可以看到各种配置项,比如VirtualService、Gateway,单击可以查看具体的YAML清单。Kiali还提供了对配置项正确性进行校验的功能,如果配置有问题,Kiali会用红色的叉来提示

- 从上面示例中可以看到,
Kiali是一个非常强大的可视化工具,可以让用户清晰和直观地了解到Istio服务网格中的服务以及服务之间的关系。除了服务拓扑图外,它还提供了健康检查、指标数据显示和配置验证等功能 。强烈推荐把Kiali作为必选项添加到服务网格中,来帮助监控和观测网格中服务的工作情况
使用EFK收集和查看日志
集中式日志架构
- 一个完整的集中式日志系统通常包括如下几个特性
- 收集:采集多种来源的日志数据
- 传输:把日志数据传输给存储系统
- 存储:存储日志数据,包括以何种方式存储多久,是否可以扩容等等
- 分析:可视化的查询分析和导出
- 报警:出现错误日志时可以通知运维人员
Fluentd是一个和Logstash类似的日志收集工具,作为Kubernetes官方使用的日志系统,Fluentd的性能和可靠性更好。在基于Kubernetes的云原生应用中,Fluentd也成为Logstash的首选系统。由此组合而成的EFK集中化日志系统也越来越流行
安装EFK
- 新建一个名叫
logging的命名空间来部署Elasticsearch、Fluentd和Kibana,而不是Bookinfo应用的默认命名空间。EFK并不是应用本身,而是服务于应用的日志系统,将其部署在不同的空间更加合理








- 我们为
Fluentd添加了一个ConfigMap对象,熟悉Kubernetes的读者应该都知道,ConfigMap是用来存储配置文件的。在data标签中添加了Fluentd运行时需要读取的配置项。把上面的清单文件保存为logging-stack.yaml,并创建这些资源


Fluentd作为守护进程运行后,遥测是Mixer的主要功能之一,它可以把来自网络的指标和日志数据通过适配器发送给后端基础设施。Fluentd就是Mixer的后端,需要利用适配器来完成日志收集工作- 一个完整的适配器需要配置实例、处理器和规则。下面的清单是为
Fluentd配置这些资源


- 使用
logentry模板作为实例,并设置了user、destination和responseCode等属性,这意味着产生的日志中应该包括这些属性

- 检查
logging命名空间,如果3个Pod都正常启动,说明EFK日志系统已经搭建完成并正常运行了

- 还可以用
Kiali来查看EFK的运行和配置情况

用Kibana查看生成的日志
- 为
Kibana建立端口转发以便可以在浏览器访问到它

- 在浏览器输入网址
http://localhost:5601,打开Kibana,单击右上角的"Set up index patterns",选择*匹配做生意数据作为索引模式,点击下一步并完成 - 日志中记录的内容正是我们在
Mixer适配器实例中配置的属性。这说明,我们部署的EFK日志系统已经和Istio整合并能够正常工作了


