微服务可观测性与集中日志管理:Istio与EFK栈的应用
1. Istio服务网格回顾
在微服务架构中,服务网格是处理安全、策略执行、弹性和流量管理等挑战的强大工具。Istio作为开源服务网格实现,为微服务系统提供了可观测性和管理能力。
1.1 流量回滚
如果在升级到v2版本后出现严重问题,可以执行以下命令将所有流量回滚到所有微服务的v1版本:
./kubernetes/routing-tests/split-traffic-between-old-and-new-services.bash 100 0
短时间后,Kiali中的图表应显示所有请求再次流向所有微服务的v1版本。
1.2 Docker Compose测试
为确保微服务的源代码不依赖于Kubernetes或Istio的部署,可使用Docker Compose进行测试。测试脚本
test-em-all.bash
的默认值已更改,使用Docker Compose时必须设置以下参数:
USE_K8S=false HOST=localhost PORT=8443 HEALTH_URL=https://localhost:8443
例如,使用默认的Docker Compose文件
docker-compose.yml
运行测试的命令如下:
USE_K8S=false HOST=localhost PORT=8443 HEALTH_URL=https://localhost:8443 ./test-em-all.bash start stop
测试脚本将启动所有容器,运行测试,最后停止所有容器。
1.3 Istio功能概述
- 可观测性 :Istio可与Kiali、Jaeger和Grafana集成,可视化微服务之间的流量。
- 安全性 :可配置使用证书通过HTTPS保护外部API,并要求外部请求包含有效的基于JWT的OAuth 2.0/OIDC访问令牌。还能使用相互认证(mTLS)自动保护内部通信。
- 弹性和健壮性 :Istio提供重试、超时处理和类似断路器的异常检测机制。此外,它还能注入故障和延迟,验证微服务的弹性和健壮性。
- 零停机部署 :使用细粒度的路由规则,可执行金丝雀和蓝绿部署。
2. EFK栈集中日志管理
在微服务系统中,每个微服务实例将日志记录写入本地文件系统,难以全面了解系统状态。因此,需要一个组件将日志记录从本地文件系统收集到中央数据库进行分析、搜索和可视化。EFK栈是一个流行的开源解决方案,由以下工具组成:
-
Elasticsearch
:分布式数据库,具有强大的大数据集搜索和分析能力。
-
Fluentd
:数据收集器,可从各种源收集日志记录,过滤和转换信息,并将其发送到各种消费者,如Elasticsearch。
-
Kibana
:Elasticsearch的图形前端,用于可视化搜索结果和分析收集的日志记录。
2.1 Fluentd概述
历史上,处理日志记录最流行的开源栈之一是ELK栈,基于Elasticsearch、Logstash和Kibana。由于Logstash运行在Java VM上,需要相对大量的内存。多年来,开发了许多内存需求显著低于Logstash的开源替代方案,其中之一就是Fluentd。
Fluentd由云原生计算基金会(CNCF)管理,与Kubernetes项目同属一个组织。它用C和Ruby混合编写,关键性能部分使用C,需要灵活性的部分使用Ruby,允许使用Ruby的
gem install
命令简单安装第三方插件。
在Fluentd中,日志记录作为事件处理,包含以下信息:
-
时间字段
:描述日志记录的创建时间。
-
标签字段
:标识日志记录的类型,用于Fluentd的路由引擎确定如何处理日志记录。
-
记录
:包含实际的日志信息,存储为JSON对象。
Fluentd配置文件用于告诉Fluentd如何收集、处理和发送日志记录到各种目标,如Elasticsearch。配置文件由以下核心元素组成:
-
-
-
:决定将日志记录发送到何处,作为输出元素。主要执行两个任务:将处理后的日志记录发送到目标,如Elasticsearch;路由以决定如何处理日志记录,路由规则可以重写标签并将日志记录重新发送到Fluentd路由引擎进行进一步处理。
graph LR
A[日志记录] --> B[<source>]
B --> C[<filter>]
C --> D[<match>]
D --> E[Elasticsearch]
2.2 Fluentd配置
Fluentd的配置基于GitHub上的
fluentd-kubernetes-daemonset
项目的配置文件。该项目包含从Kubernetes中运行的容器收集日志记录并将其发送到Elasticsearch的配置文件。
主要配置文件
kubernetes.conf
和
fluent.conf
的内容如下:
-
kubernetes.conf
:
- 源元素跟踪容器日志文件和Kubernetes外部进程的日志文件,并为Kubernetes的日志记录添加标签,标签包含命名空间、Pod和容器的名称,便于通过匹配标签查找感兴趣的日志记录。
- 过滤元素丰富来自Kubernetes内部容器的日志记录,添加Kubernetes特定的字段。
-
fluent.conf
:
- 包含其他配置文件的
@include
语句,以及自定义配置文件的包含路径。
- 输出元素将日志记录发送到Elasticsearch。
我们自己的配置文件需要处理以下内容:
- 检测和解析微服务的Spring Boot格式日志记录。
- 处理多行堆栈跟踪。
- 分离
istio-proxy
边车的日志记录和同一Pod中微服务的日志记录。
为实现这些目标,配置主要基于
rewrite_tag_filter
插件,通过更改标签名称并将日志记录重新发送到Fluentd路由引擎来路由日志记录。
以下是
fluentd-hands-on.conf
配置文件的详细步骤:
1.
ConfigMap定义
:
apiVersion: v1
kind: ConfigMap
metadata:
name: fluentd-hands-on-config
namespace: kube-system
data:
fluentd-hands-on.conf: |
- 匹配Istio日志记录 :
<match kubernetes.**istio**>
@type rewrite_tag_filter
<rule>
key log
pattern ^(.*)$
tag istio.${tag}
</rule>
</match>
此规则匹配所有以
kubernetes
开头且包含
istio
的标签的日志记录,并为其标签添加
istio.
前缀。
3.
匹配
hands-on
命名空间的日志记录
:
<match kubernetes.**hands-on**>
@type rewrite_tag_filter
<rule>
key log
pattern ^(.*)$
tag spring-boot.${tag}
</rule>
</match>
此规则匹配
hands-on
命名空间的日志记录,并为其标签添加
spring-boot.
前缀。
4.
匹配Spring Boot日志记录并处理堆栈跟踪
:
<match spring-boot.**>
@type rewrite_tag_filter
<rule>
key log
pattern /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}([-+]\d{2}:\d{2}|Z).*/
tag parse.${tag}
</rule>
<rule>
key log
pattern /^\s+Suppressed:.*$/
tag skip.${tag}
</rule>
<rule>
key log
pattern /^Error has been observed at the following site.*/
tag skip.${tag}
</rule>
<rule>
key log
pattern /^\s+\*__checkpoint.*/
tag skip.${tag}
</rule>
<rule>
key log
pattern /^Original Stack Trace:.*/
tag skip.${tag}
</rule>
<rule>
key log
pattern /^.*/
tag check.exception.${tag}
</rule>
</match>
此规则根据日志记录是否以时间戳开头,将其标记为
parse.
、
skip.
或
check.exception.
前缀。
5.
丢弃Project Reactor的日志输出
:
<match skip.spring-boot.**>
@type null
</match>
- 处理多行堆栈跟踪 :
<match check.exception.spring-boot.**>
@type detect_exceptions
languages java
remove_tag_prefix check
message log
multiline_flush_interval 5
</match>
detect_exceptions
插件将多行日志记录合并为一个包含完整堆栈跟踪的日志记录,并在重新发送到路由引擎之前移除
check
前缀。
7.
解析Spring Boot日志消息
:
<filter parse.spring-boot.**>
@type parser
key_name log
time_key time
time_format %Y-%m-%dT%H:%M:%S.%N
reserve_data true
format /^(?<time>\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}([-+]\d{2}:\d{2}|Z))\s+(?<spring.level>[^\s]+)\s+(\[(?<spring.service>[^,]*),(?<spring.trace>[^,]*),(?<spring.span>[^\]]*)]*\])\s+(?<spring.pid>\d+)\s+---\s+\[\s*(?<spring.thread>[^\]]+)\]\s+(?<spring.class>[^\s]+)\s*:\s+(?<log>.*)$/
</filter>
此过滤器使用正则表达式解析Spring Boot日志消息,提取时间、日志级别、微服务名称、跟踪ID、跨度ID、进程ID、线程ID、Java类名和实际日志消息等信息。
| 字段 | 描述 |
|---|---|
| 日志记录的创建时间戳 | |
| 日志记录的级别 | |
| 微服务的名称 | |
| 用于分布式跟踪的跟踪ID | |
| 分布式处理的部分ID | |
| 进程ID | |
| 线程ID | |
| Java类名 | |
| 实际日志消息 |
通过以上配置,我们可以有效地收集、处理和分析微服务的日志记录,提高系统的可观测性。
3. 实际应用与总结
3.1 应用EFK栈的优势
- 集中化管理 :通过EFK栈,将分散在各个微服务实例中的日志集中收集到Elasticsearch,避免了在多个节点上查找日志的繁琐过程,大大提高了日志管理的效率。
- 可视化分析 :Kibana提供了直观的图形界面,能够将收集到的日志以各种图表和报表的形式展示出来,方便开发人员和运维人员快速发现问题和趋势。
- 分布式追踪 :通过提取Spring Boot日志中的跟踪ID和跨度ID,可以实现分布式追踪,了解请求在各个微服务之间的调用路径和性能情况。
3.2 配置注意事项
- 标签管理 :合理使用标签是Fluentd配置的关键。通过为不同类型的日志记录添加特定的标签,可以方便地对日志进行分类和过滤,提高日志处理的效率。
- 正则表达式优化 :在解析Spring Boot日志时,使用的正则表达式较为复杂。需要确保正则表达式的准确性和性能,避免因正则表达式匹配不当导致日志解析失败或性能下降。
- 资源消耗 :Elasticsearch和Fluentd在处理大量日志时可能会消耗较多的系统资源。需要根据实际情况进行资源规划和优化,确保系统的稳定性。
3.3 总结
在微服务架构中,Istio服务网格和EFK栈是两个非常重要的工具。Istio为微服务提供了可观测性、安全性、弹性和零停机部署等功能,而EFK栈则实现了日志的集中收集、处理和分析,提高了系统的可维护性和可观测性。
通过本文的介绍,我们了解了如何使用Istio进行流量管理和服务治理,以及如何配置Fluentd和EFK栈来实现日志的集中管理。在实际应用中,需要根据具体的业务需求和系统架构,合理配置和使用这些工具,以提高微服务系统的性能和可靠性。
graph LR
A[微服务实例] --> B[Fluentd]
B --> C[Elasticsearch]
C --> D[Kibana]
E[Istio] --> A
E --> B
常见问题解答
-
Fluentd配置文件中的
、 和 元素有什么作用? -
元素用于指定Fluentd收集日志记录的位置,例如跟踪容器日志文件。 -
元素用于处理日志记录,例如解析日志消息、提取关键信息等。 - 元素用于决定将日志记录发送到何处,以及如何进行路由和处理。
-
-
如何处理多行堆栈跟踪?
使用detect_exceptions插件可以将多行日志记录合并为一个包含完整堆栈跟踪的日志记录。在配置文件中,通过<match check.exception.spring-boot.**>规则调用该插件,并设置相关参数。 -
如何确保EFK栈的性能和稳定性?
- 合理规划Elasticsearch的集群规模和存储容量,避免数据过载。
- 优化Fluentd的配置,减少不必要的日志处理和传输。
- 定期清理过期的日志数据,释放系统资源。
通过以上内容,我们对微服务的可观测性和集中日志管理有了更深入的了解。希望这些信息能够帮助你在实际项目中更好地应用Istio和EFK栈,提高微服务系统的管理效率和可靠性。
超级会员免费看
36

被折叠的 条评论
为什么被折叠?



