在istio里,通过虚拟服务(vs)与gateway的绑定,结合目标策略(distinationrule,DR)定义的规则,提供了从服务暴露到流量分配的实现,gateway比较简单,主要用于声明istio的ingress控制器,需要重点关注的是vs与dr进行流量的,而dr通常仅作负载均衡方式、连接池、tls、端口流量等等的规则性说明,与实际路由指向关系不大。所以个人认为,搞定了vs配置,基本上就可以满足大部分的路由需求。下面是关于vs的一些简单实践。供分享或指正。

      vs可定义精确的匹配规则,目前有5类,包括http头(header),schema(http、https、ftp等),authority(匹配authority头),method(方法, 如get、post等),uri(匹配的url)。下面我们主要以header为案例展开讨论。
     针对header,除了常规使用的destination外,vs还可以将请求进行header重写或重定向,例如我们希望把/v1改为/v2,可以采用rewrite字段,定义到/v2;或者利用redirect直接重定向到另外一个完全不同的服务,例如v1是customer服务,但可以在redirect指定hearer为hello的服务,重定向到uri为/hello的服务。留意,vs配置中,destination与redirect字段是相斥的,如果某个服务使用了redirect,就不需要设置destination。

    vs配置中,在匹配时,可以使用and和or语义,这个在精确路由时非常有用,参考如下:

使用and语义:

http:
    - match:
        - uri:
              prefix: /v1
          headers: 
              myheaders: 
                   extract: httpdemo

上面定义了前缀为v1,同时(and)http头为精确的值httpdemo。

使用or语义

http:
    - match:
        - uri:
              prefix: /v1

.....
    - match:

         - headers: 
              myheaders: 
                   extract: httpdemo

这里定义了or,系统首先匹配uri前缀是否/v1,如果是,直接路由到v1,如果不是,匹配header是否httpdemo。(留意,在vs中设置显式权重比较有助于控制你的流量。假设你有两个服务,不声明权重的话,它就按照大概5:5这样的比例分发,就像没有配置vs一样,但我不是很确定是否必然按这个比例。所以,保险起见,建议有需要的话最好还是指定权重。)

       以下是我做的一个测试。创建两个pod,建立服务,创建一个vs配置,加上header的定义,如下:

http:
  - match:
    - headers:
        user:
          exact: batman
route:
    - destination:
        host: customers.istio-test.svc.cluster.local
        port:
          number: 80
        subset: v2
  - route:
      - destination:
          host: customers.istio-test.svc.cluster.local
          port:
            number: 80
          subset: v1

以上定义了一个headr规则,user: batman,如果匹配,流量走向服务v2,kubectl apply后进行测试。

curl -H "user: batman" http://你的域名:端口

或者浏览器装一个插件(我用modhearder,还可以的一个插件)。

最后通过kiali观察流量走向,可以发现,所有hearder添加了user: batman的请求,都会跑到v2上。上面提到的customers镜像,由于被墙的关系,官方提供的路径下载不了,可以用docker.io/pj3677的版本。

Logo

K8S/Kubernetes社区为您提供最前沿的新闻资讯和知识内容

更多推荐