阿里云容器服务ACK支持一键部署Istio,并支持Istio的多种扩展功能。本文通过一个官方示例来介绍Istio的流量路由、故障注入、流量转移等功能,介绍如何通过Istio实现智能路由。

前提条件

安装官方示例

快速安装Bookinfo官方示例请参见Bookinfo Application

  1. 执行以下命令为default命名空间打上标签istio-injection=enabled
    说明 阿里云容器服务Kubernetes集群支持一键部署Istio,并支持自动Sidecar注入。
    kubectl label namespace default istio-injection=enabled
  2. 使用Kubectl命令部署Bookinfo示例应用。
    kubectl apply -f samples/bookinfo/platform/kube/bookinfo.yaml

    上面的命令会启动全部的四个服务,其中也包括了reviews服务的三个版本(v1、v2以及v3)。

  3. 执行以下命令,确认所有的服务和Pod都已经启动。
    kubectl get svc,pods
  4. 您需要从外部访问应用程序,例如使用浏览器。您需要创建一个Istio Gateway,为应用程序定义入口网关。
    kubectl apply -f samples/bookinfo/networking/bookinfo-gateway.yaml
    执行以下命令,确认网关创建完成。
    kubectl get gateway
    NAME               AGE
    bookinfo-gateway   32s
  5. 执行以下命令,查询istio-ingressgateway的访问地址。
    kubectl get svc istio-ingressgateway -n istio-system

    您也可以通过容器服务管理控制台查询istio-ingressgateway的访问地址。

    1. 登录容器服务管理控制台
    2. 在控制台左侧导航栏中,单击集群
    3. 集群列表页面中,单击目标集群名称或者目标集群右侧操作列下的应用管理
    4. 在集群管理页左侧导航栏中,单击服务,查看istio-ingressgateway服务的IP地址。
  6. 访问BookInfo首页,地址是http://{EXTERNAL-IP}/productpage
    error

    多次刷新浏览器,将在productpage中看到评论的不同的版本,系统会按照round robin(红星、黑星、没有星星)的方式展现,因为目前为止还没有使用Istio来控制版本的路由。

请求路由

BookInfo示例部署了三个版本的reviews服务,因此需要设置一个缺省路由。否则当多次访问该应用程序时,会发现有时输出会包含带星级的评价内容,有时又没有。出现该现象的原因是当没有为应用显示指定缺省路由时,Istio会将请求随机路由到该服务的所有可用版本上。

在使用Istio控制Bookinfo版本路由之前,您需要在目标规则中定义好可用的版本 。

执行以下命令为Bookinfo服务创建默认的目标规则。

  • 如果不需要启用双向TLS,请执行以下命令。
    kubectl apply -f samples/bookinfo/networking/destination-rule-all.yaml
  • 如果需要启用双向TLS,请执行以下命令。
    kubectl apply -f samples/bookinfo/networking/destination-rule-all-mtls.yaml

    等待几秒钟,目标规则生效。您可以使用以下命令查看目标规则。

    kubectl get destinationrules -o yaml

将所有微服务的缺省版本设置为v1

通过执行如下命令,将所有微服务的缺省版本设置为v1。

kubectl apply -f samples/bookinfo/networking/virtual-service-all-v1.yaml

可以通过执行以下命令来显示所有已创建的路由规则。

kubectl get virtualservices -o yaml

由于路由规则是通过异步方式分发到代理的,过一段时间后规则才会同步到所有Pod上。因此需要等几秒钟后再尝试访问应用。

在浏览器中打开BookInfo应用程序的URL:http://{EXTERNAL-IP}/productpage

可以看到BookInfo应用程序的productpage页面,显示的内容中不包含带星的评价信息,这是因为reviews:v1服务不会访问ratings服务。
error

将来自特定用户的请求路由到reviews:v2

通过执行以下命令,把来自测试用户jason的请求路由到reviews:v2,以启用ratings服务。

kubectl apply -f samples/bookinfo/networking/virtual-service-reviews-test-v2.yaml

可以通过执行以下命令确认是否创建规则。

kubectl get virtualservice reviews -o yaml
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: reviews
  ...
spec:
  hosts:
  - reviews
  http:
  - match:
    - headers:
        end-user:
          exact: jason
    route:
    - destination:
        host: reviews
        subset: v2
  - route:
    - destination:
        host: reviews
        subset: v1

确认规则已创建之后,在浏览器中打开BookInfo应用程序的URL:http://{EXTERNAL-IP}/productpage

jason用户登录productpage页面,您可以在每条评价后面看到星级信息。
说明 账号名称和密码都是jason
error
说明 本例中,首先使用Istio将100%的请求流量都路由到了BookInfo服务的v1版本,然后再设置了一条路由规则,路由规则基于请求的header(例如一个用户cookie)选择性地将特定的流量路由到了reviews服务的v2版本。

故障注入

为了测试BookInfo微服务应用的弹性,您可以计划针对jason用户在reviews:v2ratings服务之间注入7秒的延迟 。由于reviews:v2服务针对调用ratings服务设置了10秒的超时,因此期望端到端的流程能无错持续。

HTTP Delay

使用HTTP Delay创建一个故障注入规则,延迟来自用户jason的流量。

kubectl apply -f samples/bookinfo/networking/virtual-service-ratings-test-delay.yaml

确认规则已创建之后,在浏览器中打开BookInfo应用程序的URL: http://{EXTERNAL-IP}/productpage

jason用户登录productpage页面,您可看到如下画面:
error
说明 整个review服务失败的原因:productpage和review服务之间的超时小于(3秒加上一次重试,总共6秒)review服务和rating服务之间的超时(10秒)。在由不同开发团队负责独立开发不同微服务的典型企业应用中,这类bug就会发生。Istio的故障注入规则有助于识别这些异常,而无需影响到最终用户。

HTTP Abort

使用HTTP Abort创建一个故障注入规则。

kubectl apply -f samples/bookinfo/networking/virtual-service-ratings-test-abort.yaml

确认规则已创建之后,在浏览器中打开BookInfo应用程序的URL: http://{EXTERNAL-IP}/productpage

jason用户登录productpage页面,可以看到如下画面。

error

流量转移

除了基于内容的路由,Istio还支持基于权重的路由规则。

  1. 执行以下命令,将所有微服务的缺省版本设置为v1。
    kubectl replace -f samples/bookinfo/networking/virtual-service-all-v1.yaml
  2. 执行以下命令,把50%的流量从reviews:v1转移到reviews:v3。
    kubectl replace -f samples/bookinfo/networking/virtual-service-reviews-50-v3.yaml

在浏览器中多次刷新productpage页面,大约有50%的几率会看到页面中出现带红星的评价内容。

说明 注意该方式和使用容器编排平台的部署特性来进行版本迁移是完全不同的。容器编排平台使用了实例scaling来对流量进行管理。而通过Istio,两个版本的reviews服务可以独立地进行扩容和缩容,并不会影响这两个版本服务之间的流量分发。
如果觉得reviews:v3微服务已经稳定,你可以通过以下命令, 将virtual service 100%的流量路由到reviews:v3,从而实现一个灰度发布的功能。
kubectl replace -f samples/bookinfo/networking/virtual-service-reviews-v3.yaml

总结

您可以利用阿里云容器服务ACK,快速搭建一套用于连接、管理以及安全化微服务的开放平台Istio,为应用引入和配置多个相关服务。本文通过一个官方示例来演示了Istio的流量路由、故障注入、流量转移等功能。欢迎大家使用ACK,ACK可以快速搭建微服务的开放治理平台Istio,并高效地集成到项目的微服务中。