Istio为网格内的所有服务通信生成详细的遥测。这种遥测功能提供了服务行为的可观察性,使运维同学可以对应用程序进行故障排除,维护和优化,而不会给服务开发人员带来任何额外负担。通过Istio,可以全面了解受监控的服务如何与其他服务以及与Istio组件本身进行交互。

Istio生成以下遥测类型,以提供整体服务网格可观察性:

  • Metrics. Istio根据监控的四个“黄金信号”(延迟,流量,错误和饱和度)生成一组服务指标。 Istio还提供了网格控制平面的详细指标。还提供了基于这些指标构建的一组默认的网格监控仪表板。
  • Distributed Traces. Istio为每种服务生成分布式跟踪范围,从而使我们可以详细了解网格中的调用流程和服务依赖性。
  • Access Logs. 当流量流入网格内的服务时,Istio可以生成每个请求的完整记录,包括源和目标元数据。该信息使我们能够审核服务行为,可以到单个工作负载实例级别。

本文我们主要讲述logs。

Logs 简介

为什么我们需要logs?

这里讲到的log,只包含代理Envoy的访问日志,不包含业务本身日志。

Envoy的访问日志包含了丰富的流量信息,如下:

  • Start time -- 请求开始时间
  • Method -- 请求使用方法
  • Protocol -- HTTP/1.1或HTTP/2。如果协议为TCP,则值为-
  • Response Code -- HTTP响应代码。如果请求是TCP请求,则值为-
  • Response Flags -- 如果超出标准响应代码,该字段提供了有关响应或连接的更多详细信息。 HTTP和TCP请求的可能值包括UH(没有健康的上游主机); UF(上游连接失败); UO(上游溢出); NR(未配置路由); URX(由于上游重试限制或达到最大连接尝试而被拒绝)
  • Bytes Received / Bytes Sent -- body接收或发送的字节。对于WebSocket连接,发送的字节将包括响应头字节
  • Response Duration -- 从开始时间到从上游主机读取到第一个字节的请求的总持续时间(以毫秒为单位)
  • Upstream Service Time -- 上游主机处理请求所花费的时间(以毫秒为单位)。如果要将服务时间与网络延迟进行比较,这很有用。
  • X-Forwarded-For
  • User-Agent -- 该字符串允许服务器标识软件请求代理的特定类型
  • Request ID -- Envoy使用x-request-id标头唯一标识每个请求。这对于跨多个微服务的分布式跟踪和稳定的访问日志记录尤其重要
  • Authority -- Host(HTTP/1.1)或Authority(HTTP/2) header的值

此外还包括流量五元组信息,通过五元组信息,我们可以清楚知道流量从哪里来,到哪里去。

  • UPSTREAM_CLUSTER
  • DOWNSTREAM_REMOTE_ADDRESS
  • DOWNSTREAM_LOCAL_ADDRESS
  • UPSTREAM_LOCAL_ADDRESS
  • UPSTREAM_HOST

在使用istio的过程中,由于引入了代理,整个访问链路更长了,会使一些问题的排查变得复杂。比如当请求返回503等状态码的时候,我们无法确定是服务本身返回,还是代理返回。而envoy 用access log 记录流量信息,我们可以基于访问日志进行更细粒度的故障定位。

配置

Istio中对于accesslog的设置,主要通过以下配置项完成:

  • meshConfig.accessLogFile -- 如果设置为/dev/stdout,表示开启accesslog功能。以标准输出的形式打印日志,该日志我们可以使用kuebctl logs ...查看具体日志,本质上这些日志由docker收集,并存储到主机的指定位置。如果想禁用accesslog,则设置该项值为""。
  • meshConfig.accessLogEncoding -- 设置为JSONTEXT 选择访问日志的输出格式。
  • meshConfig.accessLogFormat -- 此项允许用户通过实际需要自定义访问日志的格式。

实战

在生产环境中,我们使用filebeat + kafka + es + clickhouse + kibana+ superset的组合。具体架构如下:

采集端

采集端选型轻量级日志收集组件filebeat,通过其Autodiscover功能,可以实现只收集指定容器的日志,并且具备灵活性。

当我们的应用在容器上运行时,容器的弹性决定了传统的基于配置文件的发现收集目标的方式不再适用。自动发现可以跟踪它们并在发生更改时调整设置。通过定义配置模板,自动发现子系统可以在服务开始运行时对其进行监视。

我们选择kubernetes autodiscovery,具体在filebeat配置增加如下设置:

filebeat.autodiscover:
  providers:
    - type: kubernetes
      templates:
        - condition:
            equals:
              kubernetes.container.image: "docker.io/istio/proxyv2:1.7.3"
          config:
            - module: envoy
              log:
                input:
                  type: container
                  paths:
                    - /var/log/containers/*-${data.kubernetes.container.id}.log

通过condition条件匹配,我们只采集了istio数据平面envoy的访问日志。

Kafka

由于我们的日志量比较大,所以引入了kafka。避免在高峰期由于写入压力太大,导致数据丢失。

ES + Kibana

将日志写到es中,是为了短期debug的时候,方便从海量日志中搜索关键信息,出于成本的考虑,es只保留最近3天的日志。

Clickhouse + superset

中期来看,我们会将原始日志进行聚合,然后将聚合后的数据存储到clickhouse中,并在superset中展示。这些聚合的结果,通过不同的维度反应了各个服务的流量信息。

实际我们的聚合后展示效果如下:

对于访问日志的分析展示,其实通过另外一个维度补强了基于metrcis的监控。

其实我们依旧保留了一份完整的原始日志,存放到云上的对象存储中,主要为了长期存储,便于业务在出问题的时候进行故障回溯。目前离线分析方案,使用了presto。离线分析这块,也是我们后续发力的地方。

iyacontrol
1.4k 声望2.7k 粉丝

专注kubernetes,devops,aiops,service mesh。