前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >《istio实战指南》第6章 策略与遥测

《istio实战指南》第6章 策略与遥测

作者头像
yeedomliu
发布2020-07-14 14:33:55
1.2K0
发布2020-07-14 14:33:55
举报
文章被收录于专栏:yeedomliuyeedomliu

第6章 策略与遥测

  • 常常需要为服务设置一定的授权策略,比如限制流量的速率、设置黑名单等。另外,遥测(Telemetry)也是一个很重要的功能,可以通过分析收集到的指标(Metric)来监控系统的状态。在Istio中,策略设定和遥测都是通过Mixer组件完成的

开启限流

  • istio默认是开启的,为false表示已经开启了
代码语言:javascript
复制
$ kubectl -n istio-system get cm istio -o jsonpath="{@.data.mesh}" | grep disablePolicyChecks

disablePolicyChecks: false
  • 没有启动的话,修改一下就可以了
代码语言:javascript
复制
$ istioctl manifest apply --set values.global.disablePolicyChecks=false

- Applying manifest for component Base...
✔ Finished applying manifest for component Base.
- Applying manifest for component Citadel...
- Applying manifest for component Prometheus...
- Applying manifest for component IngressGateway...
- Applying manifest for component Galley...
- Applying manifest for component Policy...
- Applying manifest for component Pilot...
- Applying manifest for component Telemetry...
- Applying manifest for component Injector...
- Pruning objects for disabled component Grafana...
- Pruning objects for disabled component Kiali...
- Pruning objects for disabled component Tracing...
- Pruning objects for disabled component EgressGateway...
✔ Finished pruning objects for disabled component Kiali.
✔ Finished pruning objects for disabled component EgressGateway.
✔ Finished pruning objects for disabled component Grafana.
✔ Finished applying manifest for component Prometheus.
✔ Finished applying manifest for component Citadel.
✔ Finished applying manifest for component IngressGateway.
✔ Finished pruning objects for disabled component Tracing.
✔ Finished applying manifest for component Galley.
✔ Finished applying manifest for component Policy.
✔ Finished applying manifest for component Injector.
✔ Finished applying manifest for component Pilot.
✔ Finished applying manifest for component Telemetry.

Mixer的工作原理

  • Mixer具有下面3种功能
  1. 先决条件检查:可以简单地把它理解为是对服务调用者的权限检查,比如调用者的身份验证是否正确、调用者是否在白名单里和是否达到了调用限制等
  2. 配额管理:允许服务在多个维度上分配和释放配额
  3. 遥测报告:生成日志记录、监控、追踪数据
  • Sidecar代理在每次发送请求时都会调用Mixer,此时Mixer就可以根据发送方的信息进行检查,确认它是否有权限进行下游服务的调用。在请求过后,Sidecar仍然会调用Mixer,并将定义的遥测数据交给Mixer收集起来,Mixer再把收集的数据交给后端接入的系统进行分析、监控
  • 这些由Sidecar发送给Mixer的数据被称作属性(Attribute),用来描述请求和与请求相关的环境或系统(如请求路径、目的服务和主机IP)

限流配置

  • 分为客户端和Mixer端
  1. 客户端配置
    1. QuotaSpec定义了Quota实例和对应的每次请求消耗的配额数
    2. QuotaSpecBinding将QuotaSpec与一个或多个服务相关联绑定,只有被关联绑定的服务限流才会生效
  2. Mixed端配置
    1. quota实例定义了Mixer如何区别度量一个请求的限流配额,用来描述请求数据收集的维度
    2. memquota/redisquota适配器定义了配置,根据quota实例的请求数据收集维度来区分并定义一个或多个限流配额
    3. rule规则定义了quota实例应该何时分发给memquota/redisquota适配器处理
  • Mixer将收集的属性交给后端的基础设施进行处理的流程。那么这些后端设施是如何被集成进来的?这就要提到Mixer中的一个重要特性:配置模型,它包含两个部分
  1. 适配器(Adapter):后端设施的接口。类似于插件,每个适配器封装了与一个后端设施交互的接口,使得它们可以像插件一样被接入进来
  2. 模板(Template):定义了属性和适配器输入的映射关系
  • 配置模型包含3种资源
  1. 处理器(Handler):用于确定正在使用的适配器及其操作方式
  2. 实例(Instance):描述如何将请求属性映射到适配器输入,实例表示一个或多个适配器将操作的各种数据
  3. 规则(Rule):定义了实例和处理器的映射关系,规则包含match表达式和action标签,match天工控制何时调用适配器,而action决定了要提供给适配器的一组实例
  • 处理器定义了和适配器的关联。比如下面定义的是listchecker适配器
代码语言:javascript
复制
apiVersion: config.istio.io/v1alpha2
kind: listchecker
metadata:
  name: staticversion
  namespace: default
spec:
  overrides: ["v1", "v2"]  # 重写提供静态列表
  blacklist: false
  • 实例就是一个数据片段的定义,这些数据由属性组成。下面例子中destination.service等都是属性
代码语言:javascript
复制
apiVersion: "config.istio.io/v1alpha2"
kind: metric
metadata:
  name: requestduration
  namespace: default
spec:
  value: response.duration | "0ms"
  dimensions:
    destination_version: destination.labels["version"] | "unknown"
    destination_service: destination.service | "unknown"
    destination_service_name: destination.service.name | "unknown"
    response_code: response.code | 200
  monitored_resource_type: '"UNSPECIFIED"'
  • 规则定义哪些实例被交给哪个处理器进行处理。下面是一个规则例子,把handler.prometheus处理器和requestduration.metri.default实例进行了绑定
代码语言:javascript
复制
apiVersion: config.istio.io/v1alpha2
kind: rule
metadata:
  name: promhttp
  namespace: default
spec:
  match: destination.service == "service1.ns.svc.cluster.local"
  actions:
  - handler: handler.prometheus
    instances:
    - requestduration.metric.default

当Envoy调用Mixer时

  1. 规则配置进行检查,确定调用哪个处理器
  2. 将要处理的实例发送给处理器
  3. 处理器确定对应的后端适配器以及操作方式
  4. 将解析实例中的数据作为适配器的输入

限流策略

  • 在某些情况下,当服务器资源不足以应对大量的请求时,为保证整个系统能够正常地提供服务,要根据设定的规则对流量进行限制

Mixer配置项

  • 运行以下命令通过memquota启用速度限制
代码语言:javascript
复制
kubectl apply -f samples/bookinfo/policy/mixer-rule-productpage-ratelimit.yaml
处理器
  • 从配置中看到,默认情况下处理器memquota每秒的最大请求数是500,并定义了如下两种速率限制
  1. 如果目标是reviews服务,5s内只能访问1次
  2. 如果目标是productpage服务,5s内只能访问2次
  • 处理请求时,Istio会选择第一条符合条件的规则(读取顺序从上到下)并将其应用到请求上;如果没有,则使用默认设置
代码语言:javascript
复制
apiVersion: config.istio.io/v1alpha2
kind: handler
metadata:
  name: quotahandler
  namespace: default
spec:
  compiledAdapter: memquota
  params:
    quotas:
    - name: requestcountquota.instance.default
      maxAmount: 500
      validDuration: 1s
      overrides:
      - dimensions:
          destination: reviews
        maxAmount: 1
        validDuration: 5s
      - dimensions:
          destination: productpage
        maxAmount: 2
        validDuration: 5s
实例
  • 实例requestcount定义了3种属性,分别是源、目标和目标版本
代码语言:javascript
复制
apiVersion: config.istio.io/v1alpha2
kind: instance
metadata:
  name: requestcountquota
  namespace: default
spec:
  compiledTemplate: quota
  params:
    dimensions:
      source: request.headers["x-forwarded-for"] | "unknown"
      destination: destination.labels["app"] | destination.service.name | "unknown"
      destinationVersion: destination.labels["version"] | "unknown"
规则
代码语言:javascript
复制
apiVersion: config.istio.io/v1alpha2
kind: rule
metadata:
  name: quota
  namespace: default
spec:
  actions:
  - handler: quotahandler
    instances:
    - requestcountquota

客户端配置项

  • 包含两部分内容
  1. QuotaSpec:定义请求的配额名称和大小
  2. QuotaSpecBinding:将配额和服务进行绑定
  • 配置将实例(requestcountquota)负载值 设置为1
代码语言:javascript
复制
apiVersion: config.istio.io/v1alpha2
kind: QuotaSpec
metadata:
  name: request-count
  namespace: default
spec:
  rules:
  - quotas:
    - charge: 1
      quota: requestcountquota
  • 把配额绑定到productpage服务上
代码语言:javascript
复制
apiVersion: config.istio.io/v1alpha2
kind: QuotaSpecBinding
metadata:
  name: request-count
  namespace: default
spec:
  quotaSpecs:
  - name: request-count
    namespace: default
  services:
  - name: productpage
    namespace: default

在浏览器中请求Bookinfo应用来进行测试。前面对productpage的设置是每5s允许 2个请求。如果不断地快速刷新页面,就会看到页面出现429的错误信息“RESOURCE_EXHAUSTED:Quota is exhausted for: requestcountquota”,这说明限流生效了

有条件的限流

  • 添加一个match标签,内容设置为"match(request.headers["cookies"], "user=*")==false",这代表匹配请求头中没有用户信息的流量。就是说登录的用户不受限流影响
代码语言:javascript
复制
/usr/local/bin/kubectl -n default edit rules quota -f - <<EOF
apiVersion: config.istio.io/v1alpha2
kind: rule
metadata:
  name: quota
  namespace: default
spec:
  match: match(request.headers["cookie"], "user=*") == false
  actions:
  - handler: quotahandler
    instances:
    - requestcountquota
EOF
  • 我们配置了一个实例requestcountquota,它代表一套计数器,计数器集合就是各个维度和限流策略的结合。如果某一个限制被触发,Mixer就会返回RESOURCE_EXHAUSTED信息给Proxy。Proxy则返回HTTP 429给调用方
  • 清理限流设置
代码语言:javascript
复制
kubectl delete -f samples/bookinfo/policy/mixer-rule-productpage-ratelimit.yaml

黑名单和白名单策略

  • 黑名单指的是在名单列表中的设备无法访问网络,白名单指的是只有名单上的设备才能访问网络

初始化路由规则

  • 先恢复默认路由规则,使用jason身份登录的用户访问reviews v2版本,并将其他请求分配到v3版本
代码语言:javascript
复制
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: reviews
spec:
  hosts:
  - reviews
  http:
  - match:
    - headers:
        end-user:
          exact: jason
    route:
    - destination:
        host: reviews
        subset: v2
  - route:
    - destination:
        host: reviews
        subset: v3
  • 执行命令生效配置
代码语言:javascript
复制
$ kubectl apply -f samples/bookinfo/networking/virtual-service-all-v1.yaml
virtualservice.networking.istio.io/productpage created
virtualservice.networking.istio.io/reviews created
virtualservice.networking.istio.io/ratings created
virtualservice.networking.istio.io/details created
$ kubectl apply -f samples/bookinfo/networking/virtual-service-reviews-jason-v2-v3.yaml
virtualservice.networking.istio.io/reviews configured
  • 打开浏览器访问应用测试,发现以jason用户登录的请求会显示黑色星标,未登录会显示红色星标,和我们的设置是一致的

用Denier适配器实现黑名单

  • Mixer适配器3种配置项
  1. 处理器为denier,它拒绝服务返回,设置为“Not allowed”
  2. 实例为checknothing,它是一个空数据模板,主要用来测试
  3. 规则为denyreviewsv3,当匹配到reviews服务的v3版本,并且目标是ratings服务时执行
代码语言:javascript
复制
/usr/local/bin/kubectl apply -f - <<EOF
apiVersion: "config.istio.io/v1alpha2"
kind: handler
metadata:
  name: denierhandler
  namespace: default
spec:
  compiledAdapter: denier
  params:
    status:
      code: 7
      message: Not allowed
EOF
代码语言:javascript
复制
/usr/local/bin/kubectl apply -f - <<EOF
apiVersion: "config.istio.io/v1alpha2"
kind: instance
metadata:
  name: denyrequest
  namespace: default
spec:
  compiledTemplate: checknothing
EOF
代码语言:javascript
复制
/usr/local/bin/kubectl apply -f - <<EOF
apiVersion: "config.istio.io/v1alpha2"
kind: rule
metadata:
  name: denyreviewsv3
  namespace: default
spec:
  match: source.labels["app"]=="reviews" && source.labels["version"]=="v3"
  actions:
  - handler: denierhandler
    instances: [ denyrequest ]
EOF
  • 未登录情况下会返回下图展示的ratings服务不可用的信息,说明用Denier模拟的黑名单策略生效了
  • 查看服务版本调用情况,首页调用的是reviews的v3版本,reviews调用ratings的v1版本
  • 从Jaeger调用链分析看出,错误是在ratings服务报错的

用List适配器实现黑白名单

  • 先创建whitelist的处理器,overrides字段中设置为v1和v2,blacklist为false代表白名单,true代表黑名单
代码语言:javascript
复制
/usr/local/bin/kubectl apply -f - <<EOF
apiVersion: config.istio.io/v1alpha2
kind: handler
metadata:
  name: whitelist
spec:
  compiledAdapter: listchecker
  params:
    overrides: ["v1", "v2"]  # overrides provide a static list
    blacklist: false
EOF
  • 创建listentry模板。它配合List适配器使用的,用来检查一个字符串是否在列表中。下面的配置用来检查version标签是否在上面设置的列表中(v1、v2)
代码语言:javascript
复制
/usr/local/bin/kubectl apply -f - <<EOF
apiVersion: config.istio.io/v1alpha2
kind: instance
metadata:
  name: appversion
spec:
  compiledTemplate: listentry
  params:
    value: source.labels["version"]
EOF
  • 配置规则,目标服务是ratings
代码语言:javascript
复制
/usr/local/bin/kubectl apply -f - <<EOF
apiVersion: config.istio.io/v1alpha2
kind: rule
metadata:
  name: checkversion
spec:
  match: destination.labels["app"] == "ratings"
  actions:
  - handler: whitelist
    instances: [ appversion ]
EOF
  • 打开浏览器验证。没有登录情况下访问Bookinfo看不到星形图标,只能看见未评论版本和黑星图标,红星图标评论版本服务是不可用的
  • 从Kiali上可以看到ratings服务的v1、v2版本可用,v3版本不可用
  • 没有评论版本(v1)
  • 黑星评论版本(v2)
  • 红星评论版本(v3)不可用

遥测

收集新的指标数据

  • 遥测的配置主要包括两部分
  1. 指标配置
  2. 日志配置
  • Mixer适配器需要3种配置
  1. 实例:先生成实例(指标和日志)
  2. 处理器:创建处理实例的处理器(Prometheus和Stdio)
  3. 规则:根据规则把实例传递给处理器处理
  • 定义doublerequestcount实例。每个请求都会生成实例,value的值 为2代表对每个实例计数两次。dimensions定义了指标的维度,对指标进行多维分析,这里配置了源服务、目标服务和消息3个维度
代码语言:javascript
复制
/usr/local/bin/kubectl apply -f - <<EOF
apiVersion: "config.istio.io/v1alpha2"
kind: instance
metadata:
  name: doublerequestcount
  namespace: default
spec:
  compiledTemplate: metric
  params:
    value: "2" # count each request twice
    dimensions:
      reporter: conditional((context.reporter.kind | "inbound") == "outbound", "client", "server")
      source: source.workload.name | "unknown"
      destination: destination.workload.name | "unknown"
      message: '"twice the fun!"'
    monitored_resource_type: '"UNSPECIFIED"'
EOF
  • 定义名为doublehandler的处理器,它对应Prometheus适配器。metrics用来定义指标,定义了一个名为double_request_count的指标,它对应上面定义的实例doublerequestcount,类型是计数器,并带有3个和维度一致的标签,用来进行多维分析
代码语言:javascript
复制
/usr/local/bin/kubectl apply -f - <<EOF
apiVersion: "config.istio.io/v1alpha2"
kind: prometheus
metadata:
  name: doublehandler
  namespace: default
spec:
  metrics:
  - name: double_request_count # Prometheus metric name
    instance_name: doublerequestcount.instance.istio-system # Mixer instance name (fully-qualified)
    kind: COUNTER
    label_names:
    - reporter
    - source
    - destination
    - message
EOF
  • 定义名为doubleprom的规则,它对实例和处理器进行关联,让Mixer把所有doublerequestcount的实例发送给doublehandler.prometheus处理器进行处理
代码语言:javascript
复制
/usr/local/bin/kubectl apply -f - <<EOF
apiVersion: "config.istio.io/v1alpha2"
kind: rule
metadata:
  name: doubleprom
  namespace: default
spec:
  actions:
  - handler: doublehandler.prometheus
    instances:
    - doublerequestcount
EOF
  • 定义了名为newlog的实例,告知Mixer如何根据请求中的属性生成日志。severity定义了日志级别,这里是warning。timestamp定义了日志的时间信息,从request.time属性中得到。variables参数提供了一些日志中可以配置的数据,如源服务、目标服务、用户和响应状态码等
代码语言:javascript
复制
/usr/local/bin/kubectl apply -f - <<EOF
apiVersion: config.istio.io/v1alpha2
kind: instance
metadata:
  name: newlog
  namespace: default
spec:
  compiledTemplate: logentry
  params:
    severity: '"warning"'
    timestamp: request.time
    variables:
      source: source.labels["app"] | source.workload.name | "unknown"
      user: source.user | "unknown"
      destination: destination.labels["app"] | destination.workload.name | "unknown"
      responseCode: response.code | 0
      responseSize: response.size | 0
      latency: response.duration | "0ms"
    monitored_resource_type: '"UNSPECIFIED"'
EOF
  • 处理器使用标准输入输出stdio。severity_levels参数定义了日志级别。outputAsJson参数要求适配器生成JSON格式的日志
代码语言:javascript
复制
/usr/local/bin/kubectl apply -f - <<EOF
apiVersion: config.istio.io/v1alpha2
kind: handler
metadata:
  name: newloghandler
  namespace: default
spec:
  compiledAdapter: stdio
  params:
    severity_levels:
      warning: 1 # Params.Level.WARNING
    outputAsJson: true
EOF
  • 定义名为newlogstdio的规则。让Mixer把日志发送给stdio处理器。match: "true"表示对所有请求都会生效,不需要过渡
代码语言:javascript
复制
/usr/local/bin/kubectl apply -f - <<EOF
apiVersion: config.istio.io/v1alpha2
kind: rule
metadata:
  name: newlogstdio
  namespace: default
spec:
  match: "true" # match for all requests
  actions:
   - handler: newloghandler
     instances:
     - newlog
EOF

用Prometheus查看指标

  • 在浏览器访问Bookinfo页面,刷新几次产生数据。设置Prometheus端口转发,以便在浏览器中访问
代码语言:javascript
复制
/usr/local/bin/kubectl -n istio-system port-forward $(/usr/local/bin/kubectl -n istio-system get pod -l app=prometheus -o jsonpath='{.items[0].metadata.name}') 9090:9090
  • 打开localhost:9000页面,在查询框中输入doublerequestcount,点击Execute查询,可以看到有3个维度数据:源服务、目标服务和消息
  • 对于日志,可以输入下面的命令查询。和期望的一样,日志是以JSON格式输出的,除了级别和时间戳以外,在newlog实例中定义的变量都正常输出了
代码语言:javascript
复制
kubectl logs -l istio-mixer-type-telemetry -c mixer | grep newlog.logentry.default
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-07-13,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 yeedomliu 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 第6章 策略与遥测
    • 开启限流
      • Mixer的工作原理
        • 限流配置
      • 限流策略
        • Mixer配置项
        • 客户端配置项
        • 有条件的限流
      • 黑名单和白名单策略
        • 初始化路由规则
        • 用Denier适配器实现黑名单
        • 用List适配器实现黑白名单
      • 遥测
        • 收集新的指标数据
        • 用Prometheus查看指标
    相关产品与服务
    Prometheus 监控服务
    Prometheus 监控服务(TencentCloud Managed Service for Prometheus,TMP)是基于开源 Prometheus 构建的高可用、全托管的服务,与腾讯云容器服务(TKE)高度集成,兼容开源生态丰富多样的应用组件,结合腾讯云可观测平台-告警管理和 Prometheus Alertmanager 能力,为您提供免搭建的高效运维能力,减少开发及运维成本。
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档