服务网格里面有一类资源很不好理解的,但是他非常的重要。那就是DestinationRule,简称dr。表面上来看,dr的作用就是扩充service的能力,将一个service实例(endpoint)拆成多个子组。
真就只是如此吗?要是真认为是这样,那其实大大的限制dr的能力。我刚开始也有个困惑,dr既然只是绑定一个svc,是不是有点过度设计。
很显然不是的,从实践结果和envoy架构 。我这里不做什么实验过程的介绍。envoy的架构图大概如下。
其中dr就是对应的是cluster,cluster对应就是实例池。也就是说,dr就是用来定义envoy实例池的,当然从能力上来看,dr既是实例池又是链接池。比如说dr能够实现探活就是链接池的功能。
实际上一个k8s service就是实例池,dr只是用来拆分子集。我们配置virtualservice的时候,根本就不需要关心dr。在我不需要链接池功能时,甚至可以用两个独立版本service来代替dr拆分子集的功能。这样配置就会改变
kind: VirtualService
spec:
hosts:
- "server.ns1"
http:
- match:
- uri:
prefix: /api/v1/booking
route:
- destination:
host: server-v1.ns1
port:
number: 8080
- route:
- destination:
host: server-v2.ns1
port:
number: 8080
创建两组service服务名为为server-v1,server-v2,其中不需要为service创建dr。默认istio会把service当成实例池。
对比一下官方推荐配置。需要配置dr
kind: VirtualService
metadata:
name: server-service
spec:
hosts:
- server.ns1
http:
- route:
- destination:
host: server.ns1
subset: v1
weight: 90
- destination:
host: server.ns1
subset: v2
weight: 10
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: server-service
spec:
host: server.ns1
subsets:
- name: v1
labels:
version: v1
- name: v2
labels:
version: v2
有人会问,这有什么用呢。子集拆分功能是独立功能,其实为的就是实现多版本的目标。istio通过service-endpoint机制能够区分多版本,整个机制对http 7层为主有很大开成。但是服务不使用http协议,比如说kitkex框架以ttheaser thrift协议,那就只能通过创建多个service来感知多版本。在这个体系下,上服务网格和不上服务网格的服务都得到兼容。