博客/社区

Istio、Tempo和Loki如何加速微服务的调试

2021年8月31日8分钟

安东尼奥·伯本是现场工程师solo.ioGloo网(与Istio)和Gloo边缘(代表)。他是Kubernetes的狂热爱好者,他最喜欢的一句话是:“我愿意去任何地方,只要它是向前的。”你可以找到并跟踪安东尼奥推特

“我该怎么调试这个?”

想象一下:周五晚些时候,你正准备关闭笔记本电脑,这时出现了一个问题。警告,警告,红色的颜色。所有我们开发者最讨厌的东西。

架构师决定基于微服务开发该系统。成百上千个!作为开发人员,你会想为什么?为什么建筑师这么恨我?然后,现在的主要问题是:我应该如何调试这个?

当然,我们都理解微服务架构的好处。但我们也讨厌它的缺点。其中之一是跨数百个服务进行调试或运行事后分析的过程。这既乏味又令人沮丧。

下面是一个例子:

-我从哪里开始?你思考,然后选择一个明显的候选者开始分析:app1 *。您可以读取按时间周期收缩的日志:*

Kubectl logs -l app=app1——since=3h[…]

没什么。一切都很正常。你会想,也许问题来自于其他相关服务。再一次:

Kubectl logs -l app=app2——since=3h[…]

啊哈!我觉得有点奇怪。这app2已经向另一个应用程序运行了请求,app3 *。让我们来看看。再一次:*

Kubectl logs -l app=app3——since=3h[…]

调试需要很长时间。有很多挫折,直到最后,一个人设法把事情弄清楚。

如你所见,这个过程很慢。相当低效。一段时间以前,我们没有日志记录和可跟踪性。

今天,情况可能有所不同。有了Grafana Loki、Grafana Tempo和其他工具,我们几乎可以立即调试。

可追溯性:您需要的特性

为了能够快速调试,您需要用唯一的ID标记请求。这个标记叫做Trace ID。在请求中涉及的所有元素中,添加另一个惟一ID span。

在这条路的尽头,您能够过滤出产生问题的请求中涉及的精确跟踪集。

不仅如此。您还可以在可视化中绘制所有这些内容,以方便地理解组成系统的各个部分。

如何用Grafana堆栈做到这一点

您将使用一个服务网格:Istio来模拟一个微服务系统。

你会说:Istio通过Kiali提供可观察性。

对于可观察性,Istio依赖于Kiali。然而,在微服务的世界中,我们应该始终表明,存在满足需求的替代方案,至少与默认方案一样好。

Grafana节奏而且Grafana洛基都是完成良好的日志记录和跟踪后端的好例子。抛开性能比较不谈,以下几点是值得考虑的:

  • Tempo和Loki都集成了S3桶来存储数据。这使您不必维护和索引可能不需要的存储(取决于您的需求)。
  • Tempo和Loki是Grafana.因此,它与Grafana仪表板无缝集成。(说实话:我们都喜欢并使用Grafana仪表盘。)

现在,让我们看看如何使用Istio和Grafana Stack加快调试过程。

这将是你的架构:

手吧!

先决条件

  • Kuberentes集群
  • Istioctl.该任务是在v.1.10中开发的

准备Istio

你需要让Istio运行起来。

让我们安装Istio操作符:

Istioctl操作符init

现在,让我们实例化服务网格。对象中包含一个traceIDx-b3-traceid.注意,您将设置访问日志以将跟踪ID作为日志消息的一部分注入:

kubectl apply -f - << 'EOF' apiVersion: install.istio. kubectlio/v1alpha1 kind: IstioOperator metadata: name: istio-operator namespace: istio-system spec: profile: default meshConfig: accessLogFile: /dev/stdout accessLogFormat:| [% start_time %] "% req (: method)% % req (x - agent - original - path ?: path)% % protocol %" % response_code % % response_flags % % response_code_details % % connection_termination_details %" % upstream_transport_failure_reason %" % bytes_received % % bytes_sent % % duration % % resp (x - agent - upstream - service - time)%" % req (x - forwarding - for)%" "% req (x-request-id)%" "% upstream_host %" % upstream_local_address % % downstream_local_address % % downstream_remote_address %"% requestd_server_name % %ROUTE_NAME% traceID=%REQ(x-b3-traceid)% enableTracing: true defaultConfig: tracing: sampling: 100 max_path_tag_length: 99999 zipkin: address: otel-collector.tracing. max_path_tag_length: 99999svc: 9411 EOF

安装演示应用程序

让我们创建命名空间并给它贴上标签以自动注入Istio代理:

Kubectl创建ns bookinfo Kubectl标签命名空间bookinfo istio-injection=enabled——覆盖

现在是演示应用程序bookinfo:

Kubectl应用-n bookinfo -f https://raw.githubusercontent.com/istio/istio/release-1.10/samples/bookinfo/platform/kube/bookinfo.yaml

要通过Istio访问应用程序,需要对其进行配置。它需要一个Gateway和一个VirtualService:

kubectl apply -f - << 'EOF' apiVersion: network .istio. apiVersion:io/v1alpha3 kind: Gateway metadata: name: bookinfo- Gateway namespace: bookinfo spec: selector: istio: ingressgateway # use istio default controller servers:—port: number: 80 name: http protocol: http hosts:—“*”#注意主机。这个匹配所有——apiVersion: networking.istio。io/v1alpha3 kind: VirtualService元数据:name: bookinfo namespace: bookinfo spec: hosts:—“*”网关:—tracing/bookinfo-gateway—bookinfo-gateway http:—match:—uri: prefix:“/”route:—destination: host: productpage.bookinfo.svc.cluster.local port: number: 9080 EOF . io: productpage.bookinfo.svc.cluster.local port: number: 9080

为了访问应用程序,让我们打开一个到Istio入口网关(网格的入口点)的隧道:

Kubectl port-forward svc/istio-ingressgateway -n istio-system 8080:80

现在,您可以通过浏览器访问该应用程序:http://localhost:8080/productpage

安装Grafana Stack

现在,让我们创建Grafana组件。让我们从Tempo开始,我们之前提到过的跟踪后端:

kubectl创建ns tracing helm repo add grafana https://grafana.github.io/helm-charts helm repo更新helm install tempo grafana/tempo——版本0.7.4 -n tracing -f - << 'EOF' tempo: extraArgs: "distributor.log-received-traces": true receivers: zipkin: otlp: protocols: http: grpc: EOF . true

下一个组件吗?让我们创建一个简单的Loki部署:

helm install loki grafana/loki-stack——version 2.4.1 -n tracing -f - << 'EOF' fluent-bit: enabled: false promtail: enabled: false prometheus: enabled: true alertmanager: persistentVolume: enabled: false server: persistentVolume: enabled: false EOF


现在,让我们部署Opentelemetry Collector。您可以使用此组件在基础设施中分布跟踪:

kubectl apply -n tracing -f https://raw.githubusercontent.com/antonioberben/examples/master/opentelemetry-collector/otel.yaml kubectl apply -n tracing -f - << 'EOF' apiVersion: v1 kind: ConfigMap metadata: name: otel-collector-conf labels: app: opentelemetry component: otel-collector-conf data: otel-collector-config: | receivers: zipkin: endpoint: 0.0.0.0:9411 exports: otlp: endpoint: temp .tracing.svc.cluster. conf: << 'EOF' apiVersion: v1 kind: ConfigMaplocal:55680 insecure: true service: pipeline: traces: receivers: [zipkin] exporters: [otlp] EOF

下面的组件是流畅位。你将使用这个组件从你的集群中废弃日志跟踪:

(注意:在配置中,您指定只接受符合以下模式的容器/var/log/containers/ * istio-proxy * . log

helm repo add fluent https://fluent.github.io/helm-charts helm repo update helm install fluent-bit fluent/fluent-bit——version 0.16.1 -n tracing -f - << 'EOF' logLevel: trace config: service: | [service] Flush 1 Daemon Off Log_Level trace Parsers_File custom_parservers .conf HTTP_Server On HTTP_Listen 0.0.0.0 HTTP_Port {{. values .service. Log_Level: trace config: service: | [service] Flush 1 Daemon Off| [INPUT]名称tail路径/var/log/containers/*istio-proxy*.log解析器cri Tag kube. log* Mem_Buf_Limit 5MB outputs: | [OUTPUT] name loki match * host loki. trace .svc port 3100 tenant_id "" labels job=fluentbit label_keys $trace_id auto_kubernetes_labels on customparser: | [PARSER] name cri Format regex regex ^(?

现在,Grafana查询。该组件已经配置为连接Loki和Tempo:

helm install grafana/grafana -n tracing——version 6.13.5 -f - << 'EOF' datasources:数据源。yaml: apiVersion: 1 datasources: - name: Tempo type: Tempo access: browser orgId: 1 uid: Tempo url: http://tempo.tracing.svc:3100 isDefault: true editable: true - name: Loki type: Loki access: browser orgId: 1 uid: Loki url: http://loki.tracing.svc:3100 isDefault: false editable: true jsonData: derivedFields: - datasourceName: Tempo matcherRegex: "traceID=(\\w+)" name: traceID url: "$${__value. "datasourceeuid: tempo env: JAEGER_AGENT_PORT: 6831 adminUser: admin adminPassword:密码service: type: LoadBalancer EOF

测试它

安装完成后,让我们打开一个到转发端口的Grafana查询的隧道:

Kubectl端口转发svc/grafana -n跟踪8081:80

使用您在安装时配置的凭据访问它:

  • 用户:管理员
  • 密码:密码

http://localhost:8081/explore

您将被提示到Explore选项卡。在那里,你可以选择在一边显示Loki,然后点击split选择在另一边显示Tempo:

你将看到如下内容:

最后,让我们用我们已经创建的bookinfo应用程序的隧道创建一些流量:

http://localhost:8080/productpage

多次刷新(硬刷新以避免缓存)页面,直到可以看到进入Loki的痕迹。记得将过滤器添加到ProductPage要查看其访问日志跟踪:

点击日志,就会出现一个Tempo按钮:

立即,TraceID将被传递到Tempo仪表板,显示可追溯性和图表:

最终的想法

拥有一个通过微服务显示请求中涉及的所有元素的图表,可以加快发现错误的速度,或者在运行事后分析时了解系统中发生了什么。

通过减少时间,您可以提高效率,以便您的开发人员可以继续工作并产生更多的业务需求。

在我个人看来,这是关键:提高企业的生产力。

可跟踪性,在本例中,Grafana堆栈可以帮助您实现这一点。

现在,让我们将其设置为生产状态。

从Tempo和Loki开始是最简单的方法Grafana云.我们有免费的(包括50 GB的跟踪和日志)和付费的Grafana Cloud计划,以适应每个用例-现在就免费注册