分享

Istio 监控方案解析

 新用户0175WbuX 2022-02-07

  大家知道,“服务网格”是当下科技行业的热门话题 , Istio 就是这一领域最流行的项目之一。Istio 由 IBM、谷歌和 Lyft 联合开发,用来解决当下微服务架构面临的众多问题。容器和 Kubernetes 的流行使微服务架构得到了广泛应用,但与此同时它们也带来了一系列全新的问题和挑战。

  如今,我们所有的服务都在使用 HTTP/gRPC API 来互相通信。在传统的单体架构时代,这些通信只是在单个应用内部传递的函数调用而已。相比而言,在微服务体系中不同服务之间存在着大量的交互,更难观察、保护和监控。

  现在,已经有很多资料介绍 Istio 的概况 及其工作原理,这里我不再赘述。本文将着重讨论一个话题,也就是监控。Istio 的官方文档谈到了这方面的内容,但我花了不少时间才搞清楚它是怎么回事。所以我会在这篇教程中带你浏览一遍相关内容,这样你就能更好地理解如何使用 Istio 来监控任务了。

  现状

  选择服务网格(mesh)的主要目的之一是提高可观察性。直到现在,开发者都需要在自己的应用中插入诸如公共库或者 New Relic 或 Datalog 这样的代理服务,从而暴露一系列指标数据;这样一来,运营就能使用监控解决方案来获取应用的终端节点指标,从而知晓系统的运行状态。但为此不得不修改代码实在很麻烦,尤其是改动或新增内容较多时更让人痛苦不堪。另外多个团队都使用这种方式做监控时,代码维护也会变得很困难。

  Istio 的做法是在无需改动任何代码的前提下暴露并追踪应用行为。这是通过所谓“边车(sidecar)”的概念实现的,它是一个与我们的应用共同运行,并向中央遥测组件提供数据的容器。边车能够识别应用正在使用的协议(redis、mongo、http、grpc 等),从而嗅探出与数据请求相关的大量信息。

  混合器,Istio 的“瑞士军刀”

  首先来看混合器(Mixer)组件,谈一谈它的作用以及它给监控带来的好处。在我看来,所谓“混合器”最好看作是一种属性处理器。网格中的代理都会发送一组内容各异的属性,比如数据请求或环境信息之类,“混合器”会处理所有这些数据并将它们分别路由到正确的适配器上。

  “适配器”是附加到“混合器”上的 handler,负责为后端调整属性数据。后端可以是对这些数据感兴趣的外部服务,诸如监控工具(如 Prometheus 或 Stackdriver)、授权后端或日志堆栈。

  Istio 监控方案解析

  概念

  入门 Istio 最难的过程之一是熟悉新术语。你刚以为自己好容易搞明白了整个 Kubernetes 词汇表的时候,却会发现 Istio 又多出来 50 多个新术语!

  在监控这方面,以下是混合器设计中最有趣且有用的一些概念:

  属性(Attribute):指由混合器处理的一段数据。大多数属性是从边车发送来的,但适配器也能产生属性。在实例中会使用属性将所需数据映射到后端。适配器(Adapter):嵌入在混合器组件中的逻辑,用来将数据转发到指定的后端。Handler:适配器的配置。由于一个适配器可以服务多个用例,因此将配置解耦就可以让适配器以多种设置来运行了。实例:将来自 Istio 的数据绑定到适配器模型的实体。 Istio 有一套由边车容器获取的统一属性集,这些数据需要翻译成后端语言。模板:定义实例 模板 的通用接口。

  创建一个新的监控案例

  了解过 Istio 相关的定义和概念后,我们要牢记它们的最好方法就是在真实场景中过一遍。

  做这个练习时,我推荐大家充分利用 Kubernetes 的标签元数据,用它来追踪我们服务的版本迭代。一般来说,转向微服务架构后你的服务最后都会有很多版本(A/B 测试,API 版本等)。 Istio 的边车会将你的群集中的所有元数据都发送到混合器。所以在我们这个示例中,我们将利用部署的标签来识别服务的版本,并观察每个版本的使用状况统计信息。

  简单起见我们先来找一个现成的项目,用谷歌微服务 演示项目 就行了,然后做一些修改以适用我们的方案。这个项目模拟了一个由多个组件组成的微服务架构,用来构建一个电子商务网站。

  首先,我们要确保这个项目与 Istio 一起能在我们的集群中正确运行。我们使用自动注入功能在命名空间中部署所有组件,并让 Istio 自动注入边车。

   复制代码

  $ kubectllabelnamespace mesh istio-injection=enabled

  警告:一定要提前创建 mesh 命名空间,并让你的 kubectl 上下文指向它。

  如果启用了一个 pod 安全策略,则需要为 init 容器配置一些权限,以使其能正确配置 iptables。出于测试目的你可以使用:

   复制代码

  $kubectlcreateclusterrolebindingmesh--clusterrolecluster-admin--serviceaccount=mesh:default

  这会将默认服务帐户绑定到群集管理员角色。现在我们可以使用全资源 YAML 文档来部署所有组件了。

   复制代码

  $ kubectl apply -f release/kubernetes-manifests.yaml

  现在你应该能看到 pod 在 mesh 命名空间中开始运行了。其中一些 pod 会出错,因为 Istio 资源还没添加进去。例如,出口流量会被阻止,currency 组件也会出错。用下面这些资源来解决问题,并通过 Istio ingress 暴露前端组件。

   复制代码

  $ kubectl apply -f release/istio-manifests.yaml

  现在我们就可以查看正在使用你的云服务商提供的 IP 或域工作的前端了(frontend-external 服务通过云服务商的负载均衡器暴露)。

  现在我们的微服务应用开始工作了,下面再进一步,将其中一个组件配置为多个版本。正像你在微服务 YAML 中看到的那样,部署会有带着应用名称的单个乐器标签。如果我们要管理 canary 部署或运行我们应用的多个版本,我们可以添加另一个版本标签。

   复制代码

  apiVersion:extensions/v1beta1

  kind:Deployment

  metadata:

  name:currencyservice

  spec:

  template:

  metadata:

  labels:

  app:currencyservice

  version:v1

  将更改应用于我们的集群后,我们可以用其他名称复制部署并更改版本。

   复制代码

  apiVersion:extensions/v1beta1

  kind:Deployment

  metadata:

  name:currencyservice2

  spec:

  template:

  metadata:

  labels:

  app:currencyservice

  version:v2

  现在再次将其提交给 API。

   复制代码

  $ kubectl apply -f release/kubernetes-manifests.yaml

  注意:虽然我们又一次应用了所有的清单,但只有已更改的清单才会由 API 更新。

  一位热心读者注意到我们用了一个技巧,就是让服务选择器只指向 app 标签。这样一来流量就会在不同版本之间平等分配了。

  进阶之路

  现在轮到重头戏了。我们需要创建三份资源来将版本暴露为 prometheus 中的新指标。

  首先,我们创建一个实例。在这里我们使用 metric 实例模板来将边车提供的值提供程序映射到适配器的输入端。我们只看负载的名称(源)和版本。

   复制代码

  apiVersion:"config.istio/v1alpha2"

  kind: metric

  metadata:

  name: versioncount

  namespace: mesh

  spec:

  value:"1"

  dimensions:

  source: sourceload.name |"unknown"

  version: destination.labels["version"] |"unknown"

  monitored_resource_type:'"UNSPECIFIED"'

  现在该配置适配器了。在这个示例中我们希望将指标连接到一个 Prometheus 后端。所以我们要在 handler 配置中定义指标名称,以及指标会为后端(Prometheus DSL)提供的数值类型,此外还有维度标识所需的标签名称。

   复制代码

  apiVersion:"config.istio/v1alpha2"

  kind:prometheus

  metadata:

  name:versionhandler

  namespace:mesh

  spec:

  metrics:

  - name: version_count# Prometheus metric name

  instance_name: versioncounttricsh# Mixer instance name (fully-qualified)

  kind:COUNTER

  label_names:

  - source

  - version

  最后,我们需要将这个 handler 与指定的实例(指标)链接起来。

   复制代码

  apiVersion:"config.istio/v1alpha2"

  kind:rule

  metadata:

  name:versionprom

  namespace:mesh

  spec:

  match:destination.service=="currencyservice

  sh.svc.cluster.local"

  actions:

  - handler:versionhandlermetheus

  instances:

  -versioncounttricsh

  一旦应用了这些定义,Istio 将指示 prometheus 适配器开始收集并提供新指标。如果我们看一下 prometheus 用户界面,会发现它现在正在搜索新指标,内容类似于:

  Istio 监控方案解析

  结论

  微服务架构中获得良好的可观察性并不容易。 Istio 有助于简化开发者的工作,并将工作交给运营商。

  一开始,处理服务网格带来的各种复杂问题可能很难。但是一旦你驯服了它,就能让监控配置标准化和自动化,并在极短时间内构建一个出色的可观察系统。

    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多