在上文“Istio 安装使用”中,我们对 Istio 进行了安装,并对 Bookinfo 样例进行了部署测试。本文接着上文,对 Istio 流量管理中的请求路由进行概念学习及样例测试。
我们知道,Istio 通过 Envoy 数据面拦截了所有服务实例的进出流量。这样基于 Istio 服务网格即可以实现诸多常规方式难以实现的流量管理策略,诸如灰度发布,A/B 测试,按比率分流等。
Istio 主要提供两个通过 YAML 配置的自定义资源来实现流量管理:Virtual Service 及 Destination Rule。这样即做到流量管理与上游请求服务及下游被请求服务解耦。Virtual Service 主要用来配置流量如何流动(即定义符合哪些规则的流量打到哪些服务子集上),而 Destination Rule 则主要用来定义具体的服务子集。
下面分别看一下 Vistual Service 及 Destination Rule 的概念,最后使用 Bookinfo 样例进行简单的路由配置及测试。
Virtual Service 主要用来配置流量如何流动。典型的使用场景是将流量路由到一个服务的不同版本(通过指定服务子集实现),如实现按比例分配流量,灰度发布等。区别于 Kubernetes 实现的主要优势在于,无须通过调整实例数来实现流量分配,流量路由已与部署实例解耦。另一个使用场景是使用 Virtual Service 为一个 namespace 下所有不同的服务提供统一的路由配置。
下面通过具体的样例来学习 VirtualService 的配置。
a)为一个服务的不同版本配置路由
下面使用 VirtualService 为 Bookinfo 的 reviews 服务的几个不同子集配置路由规则,实现将特定的用户访问流量打到特定的版本。
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: reviews
spec:
hosts: # 列出Virtual Service的hosts,可以是IP,DNS名称,FQDN或*
- reviews
http: # 在下面配置Virtual Service的路由规则,指定符合哪些规则的流量打到哪些Destination,支持HTTP/1.1,HTTP2,及gRPC等协议
- match: # 指定具体的匹配规则
- headers:
end-user:
exact: jason
route:
- destination: # 指定满足规则后将流量打到哪个具体的Destination
host: reviews
subset: v2
- route: # 流量规则按从上到下的优先级去匹配,若不满足上述规则时,进入该默认规则
- destination:
host: reviews
subset: v3
b)为不同的服务提供统一的路由配置
下面使用 VirtualService 为 Bookinfo 的两个不同服务 reviews 及 ratings 提供路由配置。基于不同的请求 URI 将流量导向不同的服务。支持使用 URI 前缀或正则进行匹配。
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: bookinfo
spec:
hosts:
- bookinfo.com
http:
- match:
- uri:
prefix: /reviews
route:
- destination:
host: reviews
- match:
- uri:
prefix: /ratings
route:
- destination:
host: ratings
除了使用 match 来编写条件,还可以使用 weight 来指定权重。下面使用 VirtualService 指定将 75%的流量打到 reviews 的 v1,25%的流量打到 reviews 的 v2。
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: reviews
spec:
hosts:
- reviews
http:
- route:
- destination:
host: reviews
subset: v1
weight: 75
- destination:
host: reviews
subset: v2
weight: 25
Destination Rule 主要用来定义服务的不同子集。这样 Virtual Service 即可定义路由规则,将一个服务的哪些流量打到哪些子集。Destination Rule 除了定义服务子集外,还可以为整个目标服务或特定子集的服务设置 Envoy 的流量策略,如负载均衡策略,TLS 安全模式,或熔断设置。
下面使用 DestinationRule 为 reviews 定义了 3 个子集 v1,v2 及 v3(使用 Kubernetes label 实现)。v1 与 v3 采用 RANDOM 负载均衡策略,v2 采用 ROUND_ROBIN 负载均衡策略。
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: reviews
spec:
host: reviews
trafficPolicy:
loadBalancer:
simple: RANDOM
subsets:
- name: v1
labels:
version: v1
- name: v2
labels:
version: v2
trafficPolicy:
loadBalancer:
simple: ROUND_ROBIN
- name: v3
labels:
version: v3
在上文“Istio 安装使用”中,我们知道如何部署 Bookinfo 样例应用。且知道 Bookinfo 由如下几个服务组成,除了 reviews 拥有 3 个版本外,其它服务均只有 1 个版本。reviews 的 v1 版本未有五星评价等级,v2 版本的五星评价等级展示颜色为黑色,v3 版本的五星评价等级展示颜色为红色。
而且,我们只使用如下命令部署了 Bookinfo 的各个服务,及使用 Gateway 与 Virtual Service 配置了简单的路由规则,指定 productpage 为统一的流量入口。
$ cd /usr/local/istio-1.8.1
$ kubectl apply -n istio-demo -f samples/bookinfo/platform/kube/bookinfo.yaml
$ kubectl apply -n istio-demo -f samples/bookinfo/networking/bookinfo-gateway.yaml
bookinfo-gateway.yaml
配置:
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: bookinfo-gateway
spec:
selector:
istio: ingressgateway # use istio default controller
servers:
- port:
number: 80
name: http
protocol: HTTP
hosts:
- "*"
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: bookinfo
spec:
hosts:
- "*"
gateways:
- bookinfo-gateway
http: # 指定满足productpage入口路径,登录登出路径,以static为前缀的静态资源路径,及以/api/v1/products为前缀的API路径的流量,均打到目标服务productpage:9080
- match:
- uri:
exact: /productpage
- uri:
prefix: /static
- uri:
exact: /login
- uri:
exact: /logout
- uri:
prefix: /api/v1/products
route:
- destination:
host: productpage
port:
number: 9080
未指定具体的路由规则前,productpage 请求各个服务时使用轮训策略,所以我们刷新 productpage 页面可以看到 Review 部分有时为黑色的五星评价等级,有时为红色的五星评价等级,有时无五星评价等级,即流量轮训了 reviews 服务的各个版本。
下面我们依照上述介绍,对 reviews 服务使用 Virtual Service 及 Destination Rule 配置不同的路由规则并进行验证测试。
a)将访问 reviews 的流量都打到一个版本
首先,为 reviews 配置 Destination Rule,定义服务的子集并指定负载均衡策略为 RANDOM。
$ cd /usr/local/istio-1.8.1
$ cat destination-rule-reviews.yaml
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: reviews
spec:
host: reviews
trafficPolicy:
loadBalancer:
simple: RANDOM
subsets:
- name: v1
labels:
version: v1
- name: v2
labels:
version: v2
- name: v3
labels:
version: v3
$ kubectl apply -n istio-demo -f destination-rule-reviews.yaml
然后,为 reviews 配置 Virtual Service,将访问 reviews 的所有流量都打到 v1。
$ cd /usr/local/istio-1.8.1
$ cat virtual-service-all-v1.yaml
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: reviews
spec:
hosts:
- reviews
http:
- route:
- destination:
host: reviews
subset: v1
$ kubectl apply -n istio-demo -f virtual-service-all-v1.yaml
这时,我们刷新 productpage 页面多次会发现,Review 部分始终无五星评价等级。即说明所有访问 reviews 的流量都打到了 v1 版本。
下面我们看一下如何指定特定用户的访问流量打到特定的版本。
b)将访问 reviews 的流量按特定用户打到特定版本
还采用 a)中 Destination Rule 的配置。
采用如下命令,将 a)中 reviews 的 Virtual Service 配置删除:
$ cd /usr/local/istio-1.8.1
$ kubectl delete -n istio-demo -f virtual-service-all-v1.yaml
重新为 reviews 配置 Virtual Service,若登录用户为 jason,则将流量打到 v2,否则打到 v3。
$ cd /usr/local/istio-1.8.1
$ cat virtual-service-reviews-jason-v2-v3.yaml
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: reviews
spec:
hosts:
- reviews
http:
- match: # header满足特定条件则打到v2
- headers:
end-user:
exact: jason
route:
- destination:
host: reviews
subset: v2
- route: # 不满足如上条件则打到v3
- destination:
host: reviews
subset: v3
$ kubectl apply -n istio-demo -f virtual-service-reviews-jason-v2-v3.yaml
这时,当我们使用 jason 账户登录,刷新 productpage 页面会发现,Review 部分始终显示黑色的五星评价等级(即 reviews 的 v2 版本)。
而不登录或使用其他账户登录时,Review 部分始终显示红色的五星评价等级(即 reviews 的 v3 版本)。
此即验证了 Istio 支持通过配置路由规则将特定用户的访问流量打到特定的版本,其原理是将特定用户标识通过前端一层层传下来,然后 Envoy 根据配置规则实现路由。
下面看一下如何按比例将流量打到同一服务的不同版本。
c)将访问 reviews 的流量按比例打到不同的版本
还采用 a)中 Destination Rule 的配置。
采用如下命令,将 b)中 reviews 的 Virtual Service 配置删除:
$ cd /usr/local/istio-1.8.1
$ kubectl delete -n istio-demo -f virtual-service-reviews-jason-v2-v3.yaml
重新为 reviews 配置 Virtual Service,将 90%的流量打到 v1,剩余 10%的流量打到 v2。
$ cd /usr/local/istio-1.8.1
$ cat virtual-service-reviews-90-10.yaml
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: reviews
spec:
hosts:
- reviews
http:
- route:
- destination: # 将90%的流量打到v1
host: reviews
subset: v1
weight: 90
- destination: # 将10%的流量打到v2
host: reviews
subset: v2
weight: 10
$ kubectl apply -n istio-demo -f virtual-service-reviews-90-10.yaml
这时,多次刷新 productpage 页面,发现 Review 部分大概率无五星评价等级,小概率显示黑色五星评价等级。
测试完毕,使用如下命令删除相关路由配置。
$ cd /usr/local/istio-1.8.1
$ kubectl delete -n istio-demo virtual-service-reviews-90-10.yaml
$ kubectl delete -n istio-demo destination-rule-reviews.yaml
若想卸载 Bookinfo 应用或卸载 Istio,可以参看上文“Istio 安装使用”。
总结本文,我们首先介绍了支持 Istio 流量管理的两个主要的资源 Virtual Service 及 Destination Rule,然后对 Bookinfo 样例使用 Virtual Service 及 Destination Rule 进行配置,测试了几个常用的流量转发场景。
参考资料