使用 Istio 实现灰度发布

简介 Kubernetes 作为基础平台,提供了强大的容器编排能力。但是在其上部署业务和服务治理上,仍然会面对一些复杂性和局限性。在服务治理上,已经有许多成熟的 ServiceMesh 框架用于扩充其能力,如 Istio、Linkerd、Dapr 等。本文将主要介绍如何使用 Istio 扩充 Kubernetes 灰度发布的能力。

1.Kubernetes 中如何实现灰度发布

当你在 Kubernetes 集群中部署业务时,可以利用 Kubernetes 原生提供的灰度发布的方式去上线业务。这种方式是通过在旧版本和新版本的服务之间,定义一个差异化的 Label,根据不同版本之间的公共 Label 负载流量到后端 Pod,最终实现根据 Pod 的副本数控制流量的百分比。

如下图所示:用户定义了两个 Deployment 对象,其中旧版本名为 frontend-stable,有3个副本。新版本为 frontend-canary,有1个副本。此时定义了一个 Service 对象,使用它们之间公共的 Label 进行选择。这就使得用户访问 frontend 这个 Service 时,能以 3:1 的比例同时访问到两个版本。并且还可以通过调整副本数持续控制流量比例,最终达到完整上线。

k8s-canary.png

Kubernetes 默认的实现方式在简单的部署场景下很有效,但是在一些复杂场景中,仍然会有较大的局限,如:

  1. 业务配置自动伸缩后,会直接影响灰度发布的流量比例

  2. 低百分比的流量控制占用资源高,如 1 % 的流量到达新版本,则至少需要 100 个副本
  3. 精确的流量分发控制,使访问到新版本中的用户一直是同一批,而不是某个用户访问时随机切换

 

2.Istio 灰度发布简述

由于 Kubernetes 提供的灰度发布方式的局限性,在一些复杂场景下,我们就需要使用 Istio 来实现更精细的灰度发布策略。在使用 Istio 进行灰度发布时,我们需要了解两个重要概念:

  1. Virtual services: 虚拟服务定义了请求到服务的路径。可以包含一组路由规则,使匹配到对应规则的请求能到达指定目标。

  2. Destination rules: 目标规则可以管理到达该目标的流量,如对服务后端所对应的实例池进行分组,再结合 Virtual services 定义的路由规则,最终将流量转发到正确的实例上。

如下图所示,以 istio 官网提供的 Bookinfo 示例程序为例,给出了 virtual services 和 destination rules 的主要定义。其中 virtual services 主要分为两块,主机名和路由规则。主机名是客户端向服务发送请求时使用的一个或多个地址。当请求到达 virtual services 时,则会根据其定义的路由规则匹配。图中就定义了邮箱以 gmail.com 结尾的用户流量只会到达 v3 版本的实例上。而其他用户则以 1:9 的比例分别访问到 v1 和 v2 版本的服务。这种方式实现了精确的流量分发控制。

当用户流量来到 reviews.demo.svc.cluster.local 这个 Service 上时,可以看到 destination rules 的规则定义中根据 version 这个 label 定义了不同的实例集,实现了流量比例与副本数的解耦。不管 reviews-v1 有多少实例。始终只有 10% 的流量到达 destination rules 的 v1 子集中。这就解决了业务副本数与流量比例的冲突问题,也使得资源使用更加合理。

istio-canary.png

3.Istio 灰度发布在Rancher上的实践

3.1 Istio准备过程

  • 通过Rancher在现有测试环境自建k8s集群一键部署Istio
使用 Istio 实现灰度发布

在Rancher中,Istio属于集群资源,在集群入口进入工具 – Istio,按照默认配置启动即可。

  • 查看Istio部署状态
使用 Istio 实现灰度发布

进入system项目,查看istio-system namespace中部署状态,等待部署完毕。

此处可以看到istio-ingressgateway deployment已默认提供NodePort。

  • 查看service
使用 Istio 实现灰度发布