简介

日常工作中我们经常需要对服务进行版本更新升级,为此我们经常使用到的发布方式有滚动升级、分批暂停发布、蓝绿发布以及灰度发布,今天主要跟大家分享下在阿里云容器服务Kubernetes集群中如何通过Ingress Controller来实现应用服务的灰度发布及AB测试。

发布场景

场景一

假设当前线上环境我们已经有一套服务Service A对外提供7层服务,此时我们新开发了一些新的特性,需要灰度发布上线一个新的版本Service A',但是我们暂时又不希望简单地直接替换掉Service A服务,而是希望将请求头中包含foo=bar或者cookie中包含foo=bar的客户端请求转发到Service A'服务中,待运行一段时间稳定,将所有的流量切换到Service A'服务中后,再平滑地下线掉Service A服务:

场景二

假设当前线上环境我们已经有一套服务Service B对外提供7层服务,此时我们修复了一些问题,需要灰度发布上线一个新的版本Service B',但是我们又不希望简单直接地将所有客户端流量切换到新版本Service B'中,而是希望仅仅切换20%的流量到新版本Service B'中,待运行一段时间稳定,将所有的流量切换到Service B'服务中后,再平滑地下线掉Service B服务:

针对以上多种不同的应用发布需求,阿里云容器服务K8S Ingress Controller支持了多种流量切分方式:

  1. 基于Request Header的流量切分,适用于灰度发布以及AB测试场景
  2. 基于Cookie的流量切分,适用于灰度发布以及AB测试场景
  3. 基于Query Param的流量切分,适用于灰度发布以及AB测试场景
  4. 基于服务权重的流量切分,适用于蓝绿发布场景

注解说明

阿里云容器服务K8S Ingress Controller通过下列Annotation来支持应用服务的灰度发布机制:

1. nginx.ingress.kubernetes.io/service-match

该注解用来配置新版本服务的路由匹配规则,格式如下:

nginx.ingress.kubernetes.io/service-match: | <service-name>: <match-rule>
# 参数说明:
# service-name:服务名称,满足match-rule的请求会被路由到该服务中
# match-rule:路由匹配规则
#
# 路由匹配规则:
# 1. 支持的匹配类型
# - header:基于请求头,支持正则匹配和完整匹配
# - cookie:基于cookie,支持正则匹配和完整匹配
# - query:基于请求参数,支持正则匹配和完整匹配
#
# 2. 匹配方式
# - 正则匹配格式:/{regular expression}/,//表明采用正则方式匹配
# - 完整匹配格式:"{exact expression}",""表明采用完整方式匹配

路由匹配规则配置示例:

# 请求头中满足foo正则匹配^bar$的请求被转发到新版本服务new-nginx中
new-nginx: header("foo", /^bar$/)# 请求头中满足foo完整匹配bar的请求被转发到新版本服务new-nginx中
new-nginx: header("foo", "bar")# cookie中满足foo正则匹配^sticky-.+$的请求被转发到新版本服务new-nginx中
new-nginx: cookie("foo", /^sticky-.+$/)# query param中满足foo完整匹配bar的请求被转发到新版本服务new-nginx中
new-nginx: query("foo", "bar")
2. nginx.ingress.kubernetes.io/service-weight

该注解用来配置新旧版本服务的流量权重,格式如下:

nginx.ingress.kubernetes.io/service-weight: | <new-svc-name>:<new-svc-weight>, <old-svc-name>:<old-svc-weight>
参数说明:
new-svc-name:新版本服务名称
new-svc-weight:新版本服务权重
old-svc-name:旧版本服务名称
old-svc-weight:旧版本服务权重

服务权重配置示例:

nginx.ingress.kubernetes.io/service-weight: | new-nginx: 20, old-nginx: 60

注意

  1. 服务权重采用相对值计算方式。如示例中的服务权重设置,new-nginx服务的权重百分比为25%,old-nginx服务的权重百分比为75%。
  2. 一个服务组(同一个ingress yaml中具有相同Host和Path的服务)中未明确设置权重的服务默认权重值为100。

版本更新

目前阿里云容器服务K8S Ingress Controller需要0.12.0-5及其以上版本才支持流量切分特性,可以通过下面命令来查看Ingress Controller的当前版本号:

  1. 采用Deployment部署的情况
 kubectl -n kube-system get deploy nginx-ingress-controller -o yaml | grep -v 'apiVersion' | grep 'aliyun-ingress-controller'
  1. 采用DaemonSet部署的情况
 kubectl -n kube-system get ds nginx-ingress-controller -o yaml | grep -v 'apiVersion' | grep 'aliyun-ingress-controller'

若您的集群内Ingress Controller当前版本号小于0.12.0-5,那么您可以通过下面方式来升级Ingress Controller到新版本:

  1. 采用Deployment部署的情况
 kubectl -n kube-system set image deploy/nginx-ingress-controller nginx-ingress-controller=registry.cn-hangzhou.aliyuncs.com/acs/aliyun-ingress-controller:0.12.0-5
  1. 采用DaemonSet部署的情况
 kubectl -n kube-system set image ds/nginx-ingress-controller nginx-ingress-controller=registry.cn-hangzhou.aliyuncs.com/acs/aliyun-ingress-controller:0.12.0-5

至此,您集群内的Ingress Controller已经支持灰度发布功能。

部署服务

在应用灰度发布前,我们必须事先已经存在一套现有的应用对外提供服务。这里我们部署一套nginx服务并通过Ingress Controller对外提供7层域名访问:

apiVersion: extensions/v1beta1
kind: Deployment
metadata:name: old-nginx
spec:replicas: 2selector:matchLabels:run: old-nginxtemplate:metadata:labels:run: old-nginxspec:containers:- image: registry.cn-hangzhou.aliyuncs.com/xianlu/old-nginximagePullPolicy: Alwaysname: old-nginxports:- containerPort: 80protocol: TCPrestartPolicy: Always
---
apiVersion: v1
kind: Service
metadata:name: old-nginx
spec:ports:- port: 80protocol: TCPtargetPort: 80selector:run: old-nginxsessionAffinity: Nonetype: NodePort

部署ingress资源:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:name: gray-release
spec:rules:- host: www.example.comhttp:paths:# 老版本服务- path: /backend:serviceName: old-nginxservicePort: 80

部署并测试访问情况:

 kubectl get ing
NAME           HOSTS             ADDRESS        PORTS     AGE
gray-release   www.example.com   47.107.20.35   80        1mcurl -H "Host: www.example.com"  http://47.107.20.35
oldcurl -H "Host: www.example.com"  http://47.107.20.35
oldcurl -H "Host: www.example.com"  http://47.107.20.35
old

灰度发布新版本服务

此时我们需要发布一个新版本的nginx服务并配置仅允许部分客户端才能访问到这个新版本服务:

apiVersion: extensions/v1beta1
kind: Deployment
metadata:name: new-nginx
spec:replicas: 1selector:matchLabels:run: new-nginxtemplate:metadata:labels:run: new-nginxspec:containers:- image: registry.cn-hangzhou.aliyuncs.com/xianlu/new-nginximagePullPolicy: Alwaysname: new-nginxports:- containerPort: 80protocol: TCPrestartPolicy: Always
---
apiVersion: v1
kind: Service
metadata:name: new-nginx
spec:ports:- port: 80protocol: TCPtargetPort: 80selector:run: new-nginxsessionAffinity: Nonetype: NodePort
场景一:设置满足特定规则的客户端才能访问新版本服务

假若我们希望请求头中满足foo=bar的客户端请求才能路由到新版本服务中,那么我们可以如下修改配置ingress规则:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:name: gray-releaseannotations:# 请求头中满足正则匹配foo=bar的请求才会被路由到新版本服务new-nginx中nginx.ingress.kubernetes.io/service-match: | new-nginx: header("foo", /^bar$/)
spec:rules:- host: www.example.comhttp:paths:# 老版本服务- path: /backend:serviceName: old-nginxservicePort: 80# 新版本服务- path: /backend:serviceName: new-nginxservicePort: 80

测试客户端请求:

 curl -H "Host: www.example.com"  http://47.107.20.35
oldcurl -H "Host: www.example.com"  http://47.107.20.35
oldcurl -H "Host: www.example.com"  http://47.107.20.35
oldcurl -H "Host: www.example.com" -H "foo: bar" http://47.107.20.35
newcurl -H "Host: www.example.com" -H "foo: bar" http://47.107.20.35
newcurl -H "Host: www.example.com" -H "foo: bar" http://47.107.20.35
new
场景二:在满足特定规则的基础上设置一定比例的请求被路由到新版本服务中

假若我们希望请求头中满足foo=bar的客户端请求仅允许50%的流量被路由到新版本服务中,那么我们可以如下修改配置ingress规则:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:name: gray-releaseannotations:# 请求头中满足正则匹配foo=bar的请求才会被路由到新版本服务new-nginx中nginx.ingress.kubernetes.io/service-match: |new-nginx: header("foo", /^bar$/)# 在满足上述匹配规则的基础上仅允许50%的流量会被路由到新版本服务new-nginx中nginx.ingress.kubernetes.io/service-weight: |new-nginx: 50, old-nginx: 50
spec:rules:- host: www.example.comhttp:paths:# 老版本服务- path: /backend:serviceName: old-nginxservicePort: 80# 新版本服务- path: /backend:serviceName: new-nginxservicePort: 80

测试客户端请求:

 curl -H "Host: www.example.com" http://47.107.20.35
oldcurl -H "Host: www.example.com" http://47.107.20.35
oldcurl -H "Host: www.example.com" http://47.107.20.35
oldcurl -H "Host: www.example.com" -H "foo: bar" http://47.107.20.35
newcurl -H "Host: www.example.com" -H "foo: bar" http://47.107.20.35
oldcurl -H "Host: www.example.com" -H "foo: bar" http://47.107.20.35
oldcurl -H "Host: www.example.com" -H "foo: bar" http://47.107.20.35
new
场景三:仅设置一定比例的请求被路由到新版本服务中

假若我们仅仅希望50%的流量被路由到新版本服务中,那么我们可以如下修改配置ingress规则:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:name: gray-releaseannotations:# 允许50%的流量被路由到新版本服务new-nginx中nginx.ingress.kubernetes.io/service-weight: |new-nginx: 50, old-nginx: 50
spec:rules:- host: www.example.comhttp:paths:# 老版本服务- path: /backend:serviceName: old-nginxservicePort: 80# 新版本服务- path: /backend:serviceName: new-nginxservicePort: 80

测试客户端访问:

 curl -H "Host: www.example.com" http://47.107.20.35
newcurl -H "Host: www.example.com" http://47.107.20.35
newcurl -H "Host: www.example.com" http://47.107.20.35
newcurl -H "Host: www.example.com" http://47.107.20.35
oldcurl -H "Host: www.example.com" http://47.107.20.35
oldcurl -H "Host: www.example.com" http://47.107.20.35
newcurl -H "Host: www.example.com" http://47.107.20.35
old

特别说明:当我们既没有设置service-match也没有设置service-weight注解时,Ingress Controller在转发请求时默认会将请求均衡地随机转发到新老版本服务中。

灰度发布完成

系统运行一段时间后,当新版本服务已经稳定并且符合预期后,我们需要将老版本的服务下线掉,仅仅保留新版本服务在线上运行,此时我们需要修改ingress规则删除相关的annotation以及老版本服务,最终规则如下:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:name: gray-release
spec:rules:- host: www.example.comhttp:paths:# 新版本服务- path: /backend:serviceName: new-nginxservicePort: 80

测试客户端访问:

 curl -H "Host: www.example.com" http://47.107.20.35
newcurl -H "Host: www.example.com" http://47.107.20.35
newcurl -H "Host: www.example.com" http://47.107.20.35
new

可以看到,现在的请求是全部被路由到了新版本的服务中,这就完成了灰度发布的整个周期。最后,您可以删除老版本的service和deployment。

通过阿里云容器服务K8S Ingress Controller实现应用服务的灰度发布相关推荐

  1. 阿里云容器服务发布 Knative 托管服务 | 云原生生态周报 Vol. 49

    作者 | 何淋波.丁海洋.陈有坤 业界要闻 阿里云容器服务发布 Knative 托管服务 Knative 是 Kubernetes 生态最流行的 Serverless 编排框架.可 Knative 的 ...

  2. 阿里云容器服务发布 Knative 托管服务

    作者 | 何淋波.丁海洋.陈有坤 业界要闻 阿里云容器服务发布 Knative 托管服务 Knative 是 Kubernetes 生态最流行的 Serverless 编排框架.可 Knative 的 ...

  3. 阿里云容器服务新增支持Kubernetes编排系统,性能重大提升

    摘要: 作为容器编排系统的两大流派, Kubernetes和Swarm的重要性不言而喻.融合了两大高性能集成的阿里云容器服务,不仅可以降低50%的基础架构成本,提高交付速度将产品迭代加快13倍,还可以 ...

  4. 使用阿里云容器服务Kubernetes实现蓝绿发布功能

    背景 在发布应用时,经常需要先上线一个新版本,用较小的流量去测试一下该新版本的可用性.但是Kubernetes的ingress resource 并没有实现流量控制与切分的功能,导致针对同一个域名下的 ...

  5. CICD联动阿里云容器服务Kubernetes实践之Bamboo篇

    本文档以构建一个 Java 软件项目并部署到 阿里云容器服务的Kubernetes集群 为例说明如何使用 Bamboo在阿里云Kubernetes服务上运行Remote Agents并在agents上 ...

  6. 阿里云容器服务DaemonSet实践

    DaemonSet 保证在每个 Node 上都运行一个容器副本,常用来部署一些集群的日志.监控或者其他系统管理应用.下面以日志收集 fluentd 为例,看下如何使用阿里云容器服务控制台创建Daemo ...

  7. 阿里云容器服务新增支持Kubernetes编排系统,性能重大提升 1

    摘要: 作为容器编排系统的两大流派, Kubernetes和Swarm的重要性不言而喻.融合了两大高性能集成的阿里云容器服务,不仅可以降低50%的基础架构成本,提高交付速度将产品迭代加快13倍,还可以 ...

  8. 连续3年入围 Gartner 容器竞争格局,阿里云容器服务新布局首次公开

    连续3年入围 Gartner 容器竞争格局,阿里云容器服务新布局首次公开 https://www.toutiao.com/i6950935574450684423/?tt_from=weixin&am ...

  9. 今年大促季,阿里云容器服务有哪些技术和应用新突破?

    联合作者:志敏,冬岛,戒空,邓隽,佳旭,谢乘胜,元毅,溪洋 在 2022 年的双 11 大促季中,阿里云容器服务(简称 ACK).容器镜像服务(简称 ACR)除了支撑集团核心系统容器化以及为云上产品提 ...

最新文章

  1. 自己写一个轻量的JqueryGrid组件
  2. 科大星云诗社动态20210909
  3. 业务订单号生成算法,每秒50W左右,不同机器保证不重复,包含日期可读性好...
  4. java与html关联_java-如何在HTML文件中搜索某些标签?
  5. 罗永浩担任“大局官”,小米双十一狂发补贴
  6. android factory,“工厂映像”(factory image)是什么?你所不知道的Android问题
  7. idea查看git分支快捷键_开发常用Git/Linux/idea命令快捷键总结(持续更新)
  8. TOPSIS(优劣解距离法)
  9. 无法启动WORKSTATION服务解决方案
  10. win10很多软件显示模糊_win10系统字体模糊的解决方法
  11. UG装配体,打开后总显示卸载的一种可行解决办法
  12. 微信小程序模仿购物车页面
  13. 国外问卷调查怎么做?谁都能做吗?
  14. Alpha测试 / Beta测试 / 黑盒测试 /白盒测试概述
  15. 如何简单有效的管理企业数据安全
  16. APICloud开发app学习(一)
  17. Excel表格中如何获得筛选下拉项的集合?
  18. niosii spi 外部_转载:NIOS II spi详解
  19. 关于毕业必须知道的知识之就业、派遣(1)
  20. java mousemotionadapter_MouseMotionAdapter 类

热门文章

  1. for java_Java For循环
  2. 自由意志是否受机器控制?
  3. 脑电分析系列[MNE-Python-4]| MNE中数据结构Evoked及其对象创建
  4. 自动驾驶系统为何要打上「思想钢印」?北京顺义闹市区里藏着毫末智行的谜底...
  5. 现在,用音频也能指挥GAN生成图像了
  6. 手表可测血压,耳机支持颈椎保护……这届电子设备越来越“养生”了
  7. 无人出租今起免费坐,只恨不是长沙人
  8. 西湖大学新冠研究登上Science封面,解析ACE2全长结构,是他们看清了新冠病毒如何入侵人体...
  9. 大牛出品:TensorFlow 2.0入门指南
  10. java版b2b2c社交电商springcloud分布式微服务 (九)服务链路追踪(Spring Cloud Sleuth)...