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