微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Istio 调用链追踪与指标收集

Istio 调用链追踪与指标收集

引言

mixer组件 提供策略控制遥测收集功能,我在Istio架构那篇文章有写,但是从Istio 1.5开始Istio标准指标Envoy代理直接导出遥测组件被实现为Proxy-wasm插件
由于看的书比较老了,王夕宁《Istio 服务网格技术解析与实战》,让我非常折磨的点在于很多东西我需要去istio.io官网文档对比。

那么这到底能用来干嘛呢,如果想了解就继续往下看。顺便说一下从现在开始已经开始偏向运维的东西了。写这类文章不容易,请赞一个吧,不求关注也不收费。

调用链追踪

在学习spring-cloud的时候调用链追踪我们是将它集成在项目代码中的,但使用istio后我们将它移到了基础架构中。

文章中只写一个Zipkin,使用都差不多,如果想使用jaeger,请参考官方文档,都差不多,链接使用 jaeger

安装Zipkin

kubectl apply -f https://raw.githubusercontent.com/istio/istio/release-1.8/samples/addons/extras/zipkin.yaml

如果您无法访问github,我这里提供资源清单

apiVersion: apps/v1
kind: Deployment
Metadata:
  name: zipkin
  namespace: istio-system
  labels:
    app: zipkin
spec:
  selector:
    matchLabels:
      app: zipkin
  template:
    Metadata:
      labels:
        app: zipkin
      annotations:
        sidecar.istio.io/inject: "false"
    spec:
      containers:
        - name: zipkin
          image: openzipkin/zipkin-slim:2.21.0
          env:
            - name: STORAGE_METHOD
              value: "mem"
          readinessProbe: # 就绪探针 
            httpGet:
              path: /health
              port: 9411
            initialDelaySeconds: 5
            periodSeconds: 5
---
apiVersion: v1
kind: Service
Metadata:
  name: tracing
  namespace: istio-system
  labels:
    app: zipkin
spec:
  type: ClusterIP
  ports:
    - name: http-query
      port: 80
      protocol: TCP
      targetPort: 9411
  selector:
    app: zipkin
---
apiVersion: v1
kind: Service
Metadata:
  labels:
    name: zipkin
  name: zipkin
  namespace: istio-system
spec:
  ports:
    - port: 9411
      targetPort: 9411
      name: http-query
  selector:
    app: zipkin

Istio 启用调用链追踪

istio install的时候添加配置项,让其使用调用链追踪功能,在install添加--set values.global.tracer.zipkin.address=zipkin.istio-system:9411(如果你没有DNS服务发现可以使用ip:port形式)。

如果你已经安装了Istio,那么可以使用istioctl profile dump demo > demo.yaml,然后修改yaml,使用istioctl upgrade命令进行更新。

暴露zipkin服务

如果您已将zipkin部署到istio-system命名空间,执行下面的命令可以暴露服务:

istioctl dashboard zipkin

自定义采样率

使用全局配置

可以通过全局配置所有跟踪选项MeshConfig。为了简化配置,建议创建一个YAML文件,您可以将其传递给istioctl install -f命令。

apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
spec:
  meshConfig:
    defaultConfig:
      tracing:
        sampling: 10 # 采样率
        custom_tags: # 自定义标签 zipkin体现在span
          my_tag_header:
            header:
              name: host

针对Deployment设置

Deploymentspec.template.Metadata加入proxy.istio.io/config设置

apiVersion: apps/v1
kind: Deployment
Metadata:
  name: sleep
spec:
  ...
  template:
    Metadata:
      ...
      proxy.istio.io/config: |
        tracing:
          sampling: 10 # 采样率
          custom_tags: # 自定义标签 zipkin体现在span
            my_tag_header:
              header:
                name: host
    spec:
      ...

指标收集

在以前有些人可能会通过ElasticsearchKibana+MetricbeatFilebeat等来实现指标和日志采集,有些人使用Prometheus + Grafana + Alertmanager + node_exporter来进行报警+监控+可视化,实际上在Istio中我们也可以使用Prometheus+Grafana,区别的点在于我们不需要node_exporter了。

dashboard-metrics-scraper

这是istio插件中就有的,如果你选择了安装,在(minikube + istio部署demo)那篇文章有写如何安装额外插件,这里面也可以收集到一些指标。

CEXL表达式

我们先讲讲mixer configuration expression language(CEXL),它用来指定mixer遥测策略配置匹配表达式映射表达式。这个玩意会用在我们需要自定义收集某些指标的时候。

操作符/函数定义示例说明
==相等request.size == 200请求体大小等于200
!=不相等request.auth.principal != “admin”请求认证的主要信息不等于admin
||逻辑或request.size == 200 || request.auth.principal != “admin”
&&逻辑与request.size == 200 && request.auth.principal != “admin”
[ ]访问字典request.headers[“X-Forwarded-For”]
+request.host + request.path
|认值request.size|0如果a存在返回a,否则返回b
隐式三元表达式
编程语言中体现为 a?a:b
python理解为 a and a or b 或 a if a else b
PHP/c#理解为 a??b
match全局匹配match(source.labels[“app”],“myapp-*”)匹配所有来源的标签app值为myapp-* ,*为通配
email将email字符串转为EMAIL_ADDRESS 类型email(“[email protected]”)使用email函数创建一个EMAIL_ADDRESS类型的字面量
dnsName将域名字符串转为DNS_NAME类型dnsName(“www.istio.io”)使用dnsName函数创建一个DNS_NAME类型的字面量
ip将IPv4地址字符串转换为IP_ADDRESS类型destination.ip == ip(“10.20.11.11”)使用IP创建一个IP_ADDRESS类型的字面量
timestamp将RFC 3339格式的时间字符串转为TIMESTAMP类型timestamp(“2020-12-18T00:00:00Z” )使用timestamp函数创建一个TIMESTAMP类型的字面量
uri一个URI字符串转为一个URI类型uri(“http://istio.io”)使用uri函数创建一个URI类型的字面量
.matches正则表达式匹配“myapp-+”.matches(source.labels[“app”])用正则表达式 “myapp-+” 匹配source.labels[“app”]
.startsWith匹配字符串前缀destination.service.startsWith(“myapp”)匹配目标服务名以myapp开头
.endsWith匹配字符串后缀destination.service.endsWith(“Nginx”)匹配目标服务名以Nginx结尾
emptyStringMap创建一个空字符串字典request.headers | emptyStringMap()如果request的headers为空就返回一个空的字符串字典,否则返回本身内容
conditional模拟三元表达式conditionnal(request.headers[“token”] === “123456789”,“authenticated”,“unauthorized”)如果请求头中的token值等于123456789 返回authenticated否则返回unauthorized
toLower字符串转换为小写toLower(“User-Agent”)返回user-agent

使用Prometheus+Grafana

安装Istio到您的集群并部署一个应用。该任务假定mixer已经用认配置(--configDefaultNamespace=istio-system)设置好了。如果您使用的不同的值,请更新配置和命令以匹配该值。

关于如何搭建PrometheusGrafana我这跳过了。

配置模型

控制策略和遥测功能设计配置3种类型资源:

  • 处理程序(Handler),用于确定正在使用的适配器组及其操作方式。
  • 实例(Instance),描述如何将请求属性映射到适配器输入。实例表示一个或多个适配器将操作的各种数据,资源清单对应的kindmetric
  • 规则(Rule),这些规则描述了合适调用特定的适配器及哪些实例,kind对应为rule

下面会分别讲解这3个玩意并且给出小栗子,演示如何使用它们

处理程序

处理程序用于处理实例传回来的指标

{Metadata.name}.{kind}.{Metadata.namespace}是处理程序的全限定名
举个栗子:

apiVersion: config.istio.io/v1alpha2
kind: listchecker
Metadata:
  name: staticversion
  namespace: istio-system
spec:
  providerUrl: http://white_list/ # 指定URL
  blacklist: false # 是否为黑名单模式

上面对应的全限定名(FQDN)就是staticversion.listchecker.sitio-system,这个listchecker适配器的作用是,如果URL在白名单中(因为我们不是黑名单模式),就会返回成功的结果。

再给一个prometheus的栗子:
关于实例instance会在下面写出来。

apiVersion: config.istio.io/v1alpha2
kind: prometheus
Metadata:
  name: handler
  namespace: istio-system
spec:
  metrics:
  - name: my_request_count# 请求数
    instance_name: myrequestcount.metric.istio-system # 实例的全限定名
    kind: COUNTER # 这里指定为计数器 就是将实例返回的内容每次递增,递增数值为实例中spec.value的值
    label_names: # 对应实例的dimensions
    - destination_service
    - distination_version
    - response_code
  - name: request_duration # 请求持续时间
    instance_name: requestduration.metric.istio-system # 实例的全限定名
    label_names: # 对应实例的dimensions
    - destination_service
    - distination_version
    - response_code
    buckets: # 对应实例的spec.value
      explicit_buckets:
        bounds: [0.005, 0.01, 0.025, 0.05, 0.1, 0.25, 0.5, 1, 2.5, 5, 10]

实例

实例用于描述收集哪些指标

apiVersion: config.istio.io/v1alpha2
kind: metric
Metadata:
  name: myrequestcount
  namespace: istio-system
spec:
  value: "1" # 返回处理程序需要处理的值
  dimensions:
    destination_service: destination.service | "unkNown"
    distination_version: destination.labels["version"] | "unkNown"
    response_code: response.code | 501
  monitored_resource_type: '"UNSPECIFIED"' # 监视资源类型为不明确的
---
apiVersion: config.istio.io/v1alpha2
kind: metric
Metadata:
  name: requestduration
  namespace: istio-system
spec:
  value: response.duration|"0ms" # 返回处理程序需要处理的值 持续时间
  dimensions:
    destination_service: destination.service | "unkNown"
    distination_version: destination.labels["version"] | "unkNown"
    response_code: response.code | 501
  monitored_resource_type: '"UNSPECIFIED"' # 监视资源类型为不明确的

规则

规则指定什么时候使用实例调用特定的处理程序。你可以理解为将实例和处理程序进行绑定,并加了一个条件。

apiVersion: config.istio.io/v1alpha2
kind: rule
Metadata:
  name: promhttp
  namespace: istio-system
spec:
  match: destination.service == "httpbin.ns.svc.cluster.local" && request.headers["token"] == "123456789"
  actions:
  - handler: handler.prometheus # 指定处理程序
    instances: # 指定有哪些实例
    - requestduration.metric.istio-system
    - myrequestcount.metric.istio-system

kubectl apply create -f 这几个yaml
此时就会自动收集这些指标了。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐