istio 0.8——用gateway在集群外访问服务

本文环境:
阿里云的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,增加了GatewayVirtualService

在开始之前,我们先看看改版的路由部分新增的四个模块内容吧。它们分别是:VirtualServiceDestinationRuleGatewayServiceEntry

我们先来看看这新增的四部分内容是怎么回事。

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不同的地方。

目前先暂时写这么多吧,后续还要测试之前完成的其他和路由相关的内容。

你可能感兴趣的:(Istio)