本文环境:
阿里云的k8s集群1.9.7;
Istio 0.8.0。
istio最近升级到0.8了,整个路由部分都升级到v1alpha3
了,这就导致之前关于路由的配置全部要推倒重来。
首先看一下我之前写的这篇文章。这里面的文件需要一些小小的改动。
#============one============
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
labels:
app: one
version: v1
name: one
spec:
replicas: 1
selector:
matchLabels:
app: one
version: v1
template:
metadata:
labels:
app: one
version: v1
spec:
containers:
- image: yubotao/istio-one:test
imagePullPolicy: IfNotPresent
name: one
ports:
- containerPort: 8180
---
apiVersion: v1
kind: Service
metadata:
name: one
labels:
app: one
spec:
ports:
- name: http
port: 8180
# nodePort: 30180
# type: NodePort
selector:
app: one
---
#=============two===============
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
labels:
app: two
version: v1
name: two
spec:
replicas: 1
selector:
matchLabels:
app: two
version: v1
template:
metadata:
labels:
app: two
version: v1
spec:
containers:
- image: yubotao/istio-two:test
imagePullPolicy: IfNotPresent
name: two
ports:
- containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
name: two
labels:
app: two
spec:
ports:
- name: http
port: 8080
selector:
app: two
---
#========ingress gateway==========
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: one-gateway
spec:
selector:
istio: ingressgateway # use Istio default gateway implementation
servers:
- port:
number: 80
name: http
protocol: HTTP
hosts:
- "*"
---
#==========VirtualService==========
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: one-virtualservice
spec:
hosts:
- "*"
gateways:
- one-gateway
http:
- match:
- uri:
prefix: /one/
route:
- destination:
port:
number: 8180
host: one
---
主要修改的部分就是,剔除了之前的Ingress
,增加了Gateway
和VirtualService
。
在开始之前,我们先看看改版的路由部分新增的四个模块内容吧。它们分别是:VirtualService
,DestinationRule
,Gateway
,ServiceEntry
。
我们先来看看这新增的四部分内容是怎么回事。
VirtualService
定义了在istio服务网格中控制如何路由到一个服务的请求的规则。我们在spec:hosts
字段中指定发送到某个服务的流量,可以配置多个目标hosts;这个hosts字段直接或间接地指定了一个或多个完全限定域名,而短名字是间接地扩展实现特定的FQDN。而其spec:http:route:destination
字段则是指定了应该路由到的具体服务实例(host指定)和相应版本(subset指定)。以及另外的一些字段,比如spec:http:match:sourceLabels
字段,可限定调用者及它的特定版本;或spec:http:match:headers
字段可以限制请求的headers中所包含的内容,比如匹配cookie等。另外像权重分流;超时;重试;故障注入等,都是通过它的相关标签实现。
这里我只是进行了一些精简的阐述,可以去我的翻译文章查阅相关内容(在比较靠下的位置,标识了0.8),或者是查阅官网。
DestinationRule
配置了适用于VirtualService路由发生后的请求策略,由服务所有者撰写。它可以定义负载均衡的路由规则(如随机,轮询等),使用trafficPolicy:loadBalancer:simple
实现。其host字段和subsets字段应该是和VitualService中的类似,且subsets字段是和VitualSerivce中的相应字段一一对应的。就是说,在VirtualService中的路由发送后,其subset和DestinationRule中的subsets对应了以后,再执行DestinationRule中定义的关于相应的subsets的相关规则。还可以配置熔断和最大连接数什么的。
以上也是我的简单总结,有可能有疏漏,烦请指正。
VirtualService与DestinationRule的关系
VirtualService与DestinationRule必须成对出现(针对服务间路由,未必所有情况都适用,比如gateway只用到了virtualService)。执行过程是:先看是否有相关请求符合VirtualService的路由规则,如符合,此时寻找匹配VirtualSerivce中的hosts其中的条目的DestinationRule的host,再执行其中的subset,而该subset与相关的DestinationRule中的subsets是相对应的,找到DestinationRule中的匹配的subsets条目,执行其中定义的相关规则。大体如下:
request ——> VirtualService ——> DestinationRule ——> 具体的实例版本子集。
VirtualService和DestinationRule的匹配关系通过host字段和subset字段确定。
也只是我目前的粗浅理解,有待探讨。
ServiceEntry
允许向Istio的内部服务注册表中添加其他条目,以便网格中自动发现的服务可以访问/路由到这些手动指定的服务。应该是对应着原egress,负责与外部服务的沟通。
Gateways
描述了一个运行在网格边缘的负载均衡器,用于接受传入或传出的HTTP/TCP连接。对应着原ingress。其与VirtualService绑定使用。
到这里我就简单的总结了以下新增的四部分内容,及它们的大体用法。不过还是建议看官网的内容和示例,对照着理解。也可以看我翻译的文章。
接下来说说我在替换新的内容碰到的坑。
Gateway的新坑
由于路由改版,所以需要使用Gateway来进行外部访问了,不同于之前的Ingress的简单配置,这次改版后的Gateway略显复杂,那么有没有更加强大的功能呢?暂不清楚。。。
首先是Gateway和VirtualService两者的搭配,由于两者是成对出现的,所以必然有互相对应的地方,一个是Gateway中的spec:hosts
和VirtualService中的spec:https
匹配,这里都使用"*"
目前感觉是麻烦最少的,但是安全性不敢保证;其次是Gateway的metadata:name
和VirtualService中的spec:gateways
,两者内容必须一致。
最后还有一部分,是和我之前的理解偏差有关。我之前以为istio的gateway的做法和spring cloud中的zuul类似,是做一个转发而已,但是我发现我错了。
事实证明,istio的VirtualService中match里的uri前缀,必须在服务中也存在,这个和zuul的转发不同。也就是说,这时想要区分多个微服务,就需要每个服务自己在内部做了,而不是像之前一样用一个网关服务统一做转发。
比如在virtualservice中配置的uri:prefix: /one/
,那么one服务中的url必须要有/one/
这个内容,sidecar访问服务的时候是带着这部分url的,而不是剔除掉再访问。这是与zuul不同的地方。
目前先暂时写这么多吧,后续还要测试之前完成的其他和路由相关的内容。