# 摸索：Istio 路由规则 Alpha v3

Istio 近期的版本中出现了一个新的 API 组：`networking.istio.io/v1alpha3`，应该会替代现有的`config.istio.io/v1alpha2` API。新的 API 不管是结构上还是功能上、以及命名上，都有很大差异。这里使用一些简单例子，体验一下 Alpha 3 带来的变化。



> 注意：正常情况下 istioctl 和 kubectl 都可以用来操作这些对象，但是 kubectl 缺乏验证功能，因此调试阶段使用 istioctl 会更方便一些。



## 路由分配



过去的路由分配比较简单，使用标签即可。新的版本中，提出了 [`VirtualService`](https://istio.io/docs/reference/config/istio.networking.v1alpha3.html#VirtualService) 的概念。VirtualService 由一组路由规则构成，用于对服务实体（原文为 Host，个人认为在 K8S 中对应为 Pod）进行寻址。一旦有流量符合其中规则的选择条件，就会发送流量给对应的服务（或者服务的一个版本/子集）。



流量的特征除了请求数据之外，还包括流量的来源，这样就能根据一些上下文来进行灵活的定义了。



这里我们定义来自 sleep 对 php-server 的请求，都转向 v1：



~~~yaml

apiVersion: networking.istio.io/v1alpha3

kind: VirtualService

metadata:

  name: sleep-server-route

spec:

  hosts:

  - "php-server"

  http:

  - match:

    - sourceLabels:

        app: sleep

    route:

    - destination:

        name: php-server

        subset: v3

  - route:

    - destination:

        name: php-server

        subset: v2

~~~



>这里的匹配策略是具有从上到下的优先级的，也就是说，最下一条就是缺省路由。



可以看到，`match`中不再包含 `source`，这里使用标签来过滤。写完应用之后，我们在 Sleep Pod 中使用 curl 发起请求，会发现并没有生效。这是因为，**在 v3 中，目标规则不再是小透明了。**，路由定义必须以目标策略为基础。





因此这里需要定义一个 `DestinationRule` 对象，来满足上面的目标需求：



~~~yaml

apiVersion: networking.istio.io/v1alpha3

kind: DestinationRule

metadata:

  name: phpserver

spec:

  name: php-server

  subsets:

  - name: v1

    labels:

      version: v1

  - name: v2

    labels:

      version: v2

  - name: v3

    labels:

      version: v3

~~~



上面的文件，创建了名为 `phpserver` 的目标规则，并在下级使用标签创建了三个子集。再次测试，会发现按照我们的要求执行了。



> 注意：VirtualService 中引用的 Destination.name 似乎对应的是目标规则中的 spec.name，而不是 metadata.name。



## 断路器



这部分的 API 变化较大。可以在上面的 DestinationRule 中加入熔断策略：



~~~yaml

  - name: v2

    labels:

      version: v2

  trafficPolicy:

    connectionPool:

      http:

        http1MaxPendingRequests: 1

        maxRequestsPerConnection: 1

      tcp:

        maxConnections: 100

    outlierDetection:

      http:

        baseEjectionTime: 180.000s

        consecutiveErrors: 1

        interval: 1.000s

        maxEjectionPercent: 100

~~~



接下来就可以使用 Fortio 或其他工具来测试熔断效果了，具体操作可以参考官方文档的[断路器一节](https://istio.io/docs/tasks/traffic-management-v1alpha3/circuit-breaking.html)



## 总结



新版本 API 加入了相当多的非 K8S 特性，另外突出了 Gateway，VirtualService 等主要对象，使得各个定义的条理性大为增强。但是目前这一组 API 仍然是 Alpha 阶段，因此还是存在相当大的变数的，但是个人推测的是，新 API 会得到更大的支持力度，因此可靠性应该更强。总之 Alpha 有风险，使用需谨慎。



## 参考链接



1. `VirtualService`: `https://istio.io/docs/reference/config/istio.networking.v1alpha3.html#VirtualService`

2. `断路器`：`https://istio.io/docs/tasks/traffic-management-v1alpha3/circuit-breaking.html`
