虚拟服务(Virtual Service)以及目标规则(Destination Rule)是istio流量路由最核心的部分,虚拟服务规定了流量路由到istio服务中,每个虚拟服务都是由一组路由规则组成的。

示例1

定义一个客户端,用来发送请求

apiVersion: apps/v1
kind: Deployment
metadata:
name: client
spec:
replicas: 1
selector:
matchLabels:
app: client
template:
metadata:
labels:
app: client
spec:
containers:
- name: busybox
image: busybox
imagePullPolicy: IfNotPresent
command:
- /bin/sh
- -c
- sleep 3600

为了方便一会看出效果,我们弄2个服务,一个httpd、一个nginx

apiVersion: apps/v1
kind: Deployment
metadata:
name: test-httpd
spec:
replicas: 2
selector:
matchLabels:
app: app-httpd
name: web
template:
metadata:
labels:
app: app-httpd
name: web
spec:
containers:
- name: httpd
image: httpd
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: test-nginx
spec:
replicas: 2
selector:
matchLabels:
app: app-nginx
name: web
template:
metadata:
labels:
app: app-nginx
name: web
spec:
containers:
- name: nginx
image: nginx
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80

创建service关联pod

apiVersion: v1
kind: Service
metadata:
name: test-web
spec:
selector:
name: web
ports:
- port: 80

我们先看下效果

#进入client容器
kubectl exec -it client-59785d99f9-zd5hb -- /bin/sh
#访问test-web svc,可以发现基本是轮询访问到后端的nginx和httpd服务的
wget -q -O - http://test-web:80

然后我们在弄个DestinationRule,这边host指向的是test-web的svc,subsets包含svc下pods的集合,通过labels确定pods


apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: web-rule
spec:
host: test-web
subsets:
- name: nginx
labels:
app: app-nginx
- name: httpd
labels:
app: app-httpd

定义一个VirtualService,指定流量策略

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: web-vs
spec:
hosts:
- test-web
http:
- route:
- destination:
host: test-web
subset: nginx
weight: 20
- destination:
host: test-web
subset: httpd
weight: 80

此处hosts字段指向一个kubernetes svc,是一个短名称,会被替换成test-web.default.svc.cluster.local

这里subset就是指向DestinationRule的subsets定义的name,也就是80%的流量分配给httpd服务,20%流量分配给nginx服务

可以进入client容器看下效果

#进入client容器
kubectl exec -it client-59785d99f9-zd5hb -- /bin/sh
#访问test-web svc,基本可以发现是1:4的比例分配流量的
wget -q -O - http://test-web:80

示例2

前面基本不改动,我们修改下virtualservice资源文件

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: vs-demo1
spec:
hosts:
- test-web
http:
- match:
- headers:
end-user:
exact: jack
route:
- destination:
host: test-web
subset: nginx
- route:
- destination:
host: test-web
subset: httpd

virtualservice还支持根据匹配条件来将流量路由到具体服务的相关配置

这个示例演示了基于身份验证的路由匹配,当我们请求的headers中携带end-user=jack,将流量路由到nginx,否则就路由到httpd

#进入client容器
kubectl exec -it client-59785d99f9-zd5hb -- /bin/sh
#访问test-web svc
wget -q -O - http://test-web:80
wget -q -O - http://test-web:80 --header 'end-user:jack'