Istio流量管理-虚拟服务

786 阅读5分钟

前言

Istio 的流量路由规则可以让您很容易的控制服务之间的流量和 API 调用。Istio 简化了服务级别属性的配置,比如熔断器、超时和重试,并且能轻松的设置重要的任务,如 A/B 测试、金丝雀发布、基于流量百分比切分的概率发布等。

demo

接口说明

在学习Istio流量管理时,这边参考官方demo设计了一个简易的接口请求。

  • book应用:

    主应用入口,调用其他两个服务进行接口返回

  • comment:评论应用
    • default版本:采用master分支,并返回默认数据
    • dev版本:采用dev分支,在默认数据基础上增加star字段
  • user: 用户应用

    返回用户信息,book和comment都会调用

应用列表

image.png

服务列表

image.png

接口请求示例

{
    "code": 200,
    "message": "ok",
    "data": {
        "name": "《简爱》",
        "author": "夏洛蒂·勃朗特",
        "registerId": 1,
        "commentList": [
            {
                "bookId": 1,
                "userId": 1,
                "content": "这本书写的真好",
                "datetime": "2021-05-19 03:03",
                "userInfo": {
                    "id": 1,
                    "name": "张三",
                    "age": 35
                }
            },
            {
                "bookId": 1,
                "userId": 2,
                "content": "这是一本好书",
                "datetime": "2021-05-19 03:03",
                "userInfo": {
                    "id": 2,
                    "name": "李四",
                    "age": 50
                }
            }
        ],
        "registerInfo": {
            "id": 1,
            "name": "张三",
            "age": 35
        }
    }
}
  • 字段说明:将所有字段展示出来,方便后续调整后展示
    • commentList: 评论列表
    • userInfo: 用户信息

调用结构

image.png

流量管理组件说明

虚拟服务

概念

虚拟服务(Virtual Service) 和目标规则(Destination Rule) 是 Istio 流量路由功能的关键拼图。虚拟服务让您配置如何在服务网格内将请求路由到服务,这基于 Istio 和平台提供的基本的连通性和服务发现能力。

为什么使用虚拟服务?

虚拟服务在增强 Istio 流量管理的灵活性和有效性方面,发挥着至关重要的作用,通过对客户端请求的目标地址与真实响应请求的目标工作负载进行解耦来实现。虚拟服务同时提供了丰富的方式,为发送至这些工作负载的流量指定不同的路由规则。

虚拟服务功能点
  • 通过单个虚拟服务处理多个应用程序服务。
  • 和网关整合并配置流量规则来控制出入流量

目标规则

概念

与虚拟服务一样,目标规则也是 Istio 流量路由功能的关键部分。您可以将虚拟服务视为将流量如何路由到给定目标地址,然后使用目标规则来配置该目标的流量。在评估虚拟服务路由规则之后,目标规则将应用于流量的“真实”目标地址。

负载均衡选项

默认情况下,Istio 使用轮询的负载均衡策略,实例池中的每个实例依次获取请求。Istio 同时支持如下的负载均衡模型,可以在 DestinationRule 中为流向某个特定服务或服务子集的流量指定这些模型。

  • 随机:请求以随机的方式转到池中的实例。
  • 权重:请求根据指定的百分比转到实例。
  • 最少请求:请求被转到最少被访问的实例。

demo演示

配置目标规则(主要是对comment应用进行演示)

  • 添加文件:vim destinationRule.yaml
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: comment                 // 目标规则集合名称
  namespace: istiopreview       // 命名空间
spec:
  host: comment-svc             // 对应的service名称
  subsets:                      // 路由规则集合
    - name: default             // 具体规则名称
      labels:                   // 根据标签来选择
        version: master         // app标签选择器
    - name: dev
      labels:
        version: dev
  • 将规则设置到集群:kubectl apply -f destinationRule.yaml
  • 查看路由规则:kubectl get destinationrules.networking.istio.io -n istiopreview

image.png

设置虚拟服务规则

  • 添加文件:vim virtualService.yaml
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: comment-virtual-svc              // 虚拟服务规则名称
  namespace: istiopreview                // 命名空间设置
spec:
  hosts:
    - "comment-svc"                      // 虚拟服务对应的原始服务
  http:                                  // http规则设置
    - route:                             // 路由配置
        - destination:                   // 描述
            host: comment-svc            // 路由host
            subset: default              // 路由规则选择
        - destination:
            host: comment-svc
            subset: dev
  • 将虚拟服务添加到集群:kubectl apply -f virtualService.yaml
  • 查看虚拟服务:kubectl get virtualservices.networking.istio.io -n istiopreview

image.png

演示一:按权重请求路由规则

  • 调整虚拟服务配置:vim virtualService.yaml
...
        - destination:
            host: comment-svc
            subset: default
          weight: 100              // 设置权重为100
        - destination:
            host: comment-svc
            subset: dev
          weight: 0                // 设置权重为0
  • 效果说明:原本根据k8s服务负载会50%流量到default,50%流量到dev,这样配置之后。100%流量都到default了,没有流量到dev应用了。

演示二:设置超时

  • 增加user应用路由的路由规则

    • vim userdestinationRule.yaml
    apiVersion: networking.istio.io/v1alpha3
    kind: DestinationRule
    metadata:
      name: user
      namespace: istiopreview
    spec:
      host: user-svc
      subsets:
        - name: default
          labels:
            app: user
    
    • vim uservirtualService.yaml
    apiVersion: networking.istio.io/v1alpha3
    kind: DestinationRule
    metadata:
      name: user
      namespace: istiopreview
    spec:
      host: user-svc
      subsets:
        - name: default
          labels:
            app: user
    
    • kubectl apply -f userdestinationRule.yaml && kubectl apply -f uservirtualService.yaml
  • 给user虚拟服务设置10秒延迟

    • vim uservirtualService.yaml
    ...
      - route:
        - destination:
            host: user-svc
            subset: default
        fault:                          // 故障注入
          delay:                        // 延迟
            percent: 100                // 百分比
            fixedDelay: 10s             // 固定延迟时间
    ...
    
    • kubectl apply -f uservirtualService.yaml
    • 验证:在浏览器请求接口,耗时20秒(因为2个服务都请求了user),验证成功。
  • 给comment虚拟服务添加超时控制

    • vim virtualService.yaml
    ...
        - route:
          - destination:
              host: comment-svc
              subset: default
            weight: 50
          - destination:
              host: comment-svc
              subset: dev
            weight: 50
          timeout: 5s
    
    • kubectl apply -f virtualService.yaml
  • 验证超时:接口请求花费15秒(book->user花费10秒,book->comment花费5秒),评论信息未返回,超时成功。

其他的功能就不演示了,有兴趣的可以参考文档自己来做demo尝试

参考文档: Virtual Service

总结

路由规则和虚拟服务是istio流量管理中非常重要的一环,只有通过这两个我们才能无侵入的对服务进行故障注入,超时,路由配置等操作,对于虚拟服务来说,可以将其看成service端的Sidecar,其代理了service的一切流量,并按照设置的规则进行流量处理。本篇采用两个小demo来展示了虚拟服务是如何进行流量操作的,有兴趣的可以根据官方文档处理更多的操作,比如路由重写,灰度请求等等操作。