本文主要介绍K8S基于ingress实现的灰度发布,常规操作k8s我们需要编写 yml 文件使用命令行来操作,UI和可视化是一个很方便的东西。本文基于Rancher来实现金丝雀灰度发布的需求,进行一个实例演示。
Rancher是一个容器管理平台。它提供了在测试和生产环境中使用的管理 Docker 和 Kubernetes 的全栈化容器部署与管理平台。你可以通俗的将 Rancher 理解为管理基于K8S管理容器的一个可视化平台。
灰度发布(又名金丝雀发布)是指在黑与白之间,能够平滑过渡的一种发布方式。
k8s 的 nginx-ingress
提供了金丝雀发布规则,包含基于header的灰度发布、基于权重比例的灰度发布和基于cookie的灰度发布。
介绍
Ingress-Nginx 是一个K8S ingress工具,支持配置 Ingress Annotations 来实现不同场景下的灰度发布和测试。 Nginx Annotations 支持以下 4 种 Canary 规则:
-
nginx.ingress.kubernetes.io/canary-by-header:基于 Request Header 的流量切分,适用于灰度发布以及 A/B 测试。当 Request Header 设置为 always时,请求将会被一直发送到 Canary 版本;当 Request Header 设置为 never时,请求不会被发送到 Canary 入口;对于任何其他 Header 值,将忽略 Header,并通过优先级将请求与其他金丝雀规则进行优先级的比较。
-
nginx.ingress.kubernetes.io/canary-by-header-value:要匹配的 Request Header 的值,用于通知 Ingress 将请求路由到 Canary Ingress 中指定的服务。当 Request Header 设置为此值时,它将被路由到 Canary 入口。该规则允许用户自定义 Request Header 的值,必须与上一个 annotation (即:canary-by-header)一起使用。
-
nginx.ingress.kubernetes.io/canary-weight:基于服务权重的流量切分,适用于蓝绿部署,权重范围 0 - 100 按百分比将请求路由到 Canary Ingress 中指定的服务。权重为 0 意味着该金丝雀规则不会向 Canary 入口的服务发送任何请求。权重为 100 意味着所有请求都将被发送到 Canary 入口。
-
nginx.ingress.kubernetes.io/canary-by-cookie:基于 Cookie 的流量切分,适用于灰度发布与 A/B 测试。用于通知 Ingress 将请求路由到 Canary Ingress 中指定的服务的cookie。当 cookie 值设置为 always时,它将被路由到 Canary 入口;当 cookie 值设置为 never时,请求不会被发送到 Canary 入口;对于任何其他值,将忽略 cookie 并将请求与其他金丝雀规则进行优先级的比较。
注意:
- 金丝雀规则按优先顺序为:canary-by-header - > canary-by-cookie - > canary-weight
- 截止目前,同一个 host 的 ingress 规则最多可以应用一个canary ingress
我们可以把以上的四个 annotation 规则可以总体划分为以下两类:
1、基于权重的 Canary 规则(weight)
2、基于用户请求的 Canary 规则(header和cookie)
注意: Ingress-Nginx 在0.21.0 版本 中,引入的Canary 功能,因此要确保ingress版本OK,Rancher-2.3.3以及2.2.10版本中ingress版本为0.25.1
过程
1、创建一个最简单的项目,定义一个接口,准备2个版本返回数据不同。
2、将接口服务打包为镜像并push到镜像仓库中(自行操作)
我准备了2个版本的镜像,接口 /test/api1
返回的结果分别为 Hello Api1 v1
和 Hello Api1 v2
。
下图是我使用公司开发环境的 jenkins 环境对两个版本的进行了构建并发布到了镜像仓库。
3、Rancher UI管理界面,配置工作负载(deployment)
4、Rancher UI管理界面,配置负载均衡(ingress 规则)
注意:前面提过
截止目前为止同一个 host 的 ingress 规则最多可以应用一个canary ingress
,所以下面我们需要配置一个默认的(正常的)ingress 规则,再配置一个带有灰度发布规则的 ingress规则。
带有灰度发布规则的规则,指向 v2 版本(相当于我们上线的新版本)。
截止这里,K8S 的 deployment 和 ingress 已经配置完成。
测试验证
因为例子中的域名是模拟的(假的),所以我们需要在本地配置 hosts
,加入上面定义的伪域名。
192.168.1.124 springboot-test1.shanhy.com
打开 Postman
(或其他随便什么接口工具),请求 http://springboot-test1.shanhy.com/test/api1
可以看到输出 Hello Api1 v1
。
然后再添加一个 header(version=v2),再请求 http://springboot-test1.shanhy.com/test/api1
可以看到输出 Hello Api1 v2
。
下面是 linux 的 curl 测试命令:
# curl http://springboot-test1.shanhy.com/test/api1
Hello Api1 v1
# curl -H "version:v2" http://springboot-test1.shanhy.com/test/api1
Hello Api1 v2
至此验证通过,下面是基于权重和基于cookie的配置截图示例:
如图是基于权重比例的规则配置,你可以通过反复请求接口来验证结果。
如图是基于权重比例的规则配置,你可以在请求接口时候设定 cookie 内容 shanhy=always
(或never
)来验证结果,如下:
基于 curl 的 cookie 测试命令为 curl -b "shanhy=always" http://springboot-test1.shanhy.com/test/api1
注意:使用
canary-by-cookie
、canary-by-header 且不配置 canary-by-header-value
时,均使用两个关键词来控制路由,当值为always
时它将被路由到 canary,当值为never
时,它将永远不会路由到canary。
(END)